diff --git a/usr.sbin/sysinst/README.md_defs b/usr.sbin/sysinst/README.md_defs index 5f379727c11a..08d363e0e538 100644 --- a/usr.sbin/sysinst/README.md_defs +++ b/usr.sbin/sysinst/README.md_defs @@ -1,4 +1,4 @@ -/* $NetBSD: README.md_defs,v 1.3 2019/12/10 06:25:50 isaki Exp $ */ +/* $NetBSD: README.md_defs,v 1.4 2020/01/20 21:26:35 martin Exp $ */ The following is trying to document the most important machine dependent defines used in the sysinst code. @@ -71,6 +71,24 @@ used like: returns true if this setup needs boot blocks. Used for example on x86 when UEFI installs do not need any bootblocks, but BIOS ones do. +MD_MAY_SWAP_TO may be undefined + +used like: + + bool MD_MAY_SWAP_TO(const char *disk_name) + +returns true if the disk is usable as a swap device. Typical implementation +in utils.c:may_swap_if_not_sdmmc. + +MD_SET_EXTRACT_FINALIZE may be undefined + +used like: + + int MD_SET_EXTRACT_FINALIZE(int update) + +extracts any additional parts of the distribution. Returns an error code +if something fails. + HAVE_PLAIN_DISKLABEL_BOOT may be undefined, only used on architectures that have MBR as primary with disklabel as @@ -90,3 +108,9 @@ If defined, do not verify the presence of on-disk disklabels before offering the disklabel partitioning scheme. This allows ports to use kernel translation for the disklabel ioctls (e.g. x68k uses Human68k partitions this way). + + +HAVE_GPT_BOOT defined if the architecture can boot from GPT + +NO_DISKLABEL_BOOT defined if the architecture can NOT boot + from a disklabel partitioned disk diff --git a/usr.sbin/sysinst/arch/evbarm/md.c b/usr.sbin/sysinst/arch/evbarm/md.c index 5866f6c7c4f8..332821f5b0f7 100644 --- a/usr.sbin/sysinst/arch/evbarm/md.c +++ b/usr.sbin/sysinst/arch/evbarm/md.c @@ -1,4 +1,4 @@ -/* $NetBSD: md.c,v 1.12 2020/01/09 17:06:46 martin Exp $ */ +/* $NetBSD: md.c,v 1.13 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -81,8 +81,13 @@ md_init(void) void md_init_set_status(int flags) { - if (boardtype == BOARD_TYPE_RPI) - set_kernel_set(SET_KERNEL_RPI); + + /* + * we will extract kernel variants and DTB files piecwise + * manually later, just fetch the kernel set, do not + * unpack it. + */ + set_noextract_set(SET_KERNEL_1); } bool @@ -111,10 +116,7 @@ md_get_info(struct install_partition_desc *install) pm->dlsize = ps->size_limit; } - if (boardtype == BOARD_TYPE_RPI) - return set_bios_geom_with_mbr_guess(pm->parts); - - return true; + return edit_outer_parts(pm->parts); } /* @@ -134,16 +136,13 @@ md_check_partitions(struct install_partition_desc *install) { size_t i; - if (boardtype == BOARD_TYPE_NORMAL) - return true; - if (boardtype == BOARD_TYPE_RPI) { - for (i = 0; i < install->num; i++) - if (install->infos[i].fs_type == FS_MSDOS) - return true; + for (i = 0; i < install->num; i++) + if (install->infos[i].fs_type == FS_MSDOS) + return true; + + msg_display(MSG_nomsdospart); + process_menu(MENU_ok, NULL); - msg_display(MSG_nomsdospart); - process_menu(MENU_ok, NULL); - } return false; } @@ -195,13 +194,43 @@ md_post_newfs(struct install_partition_desc *install) } int -md_post_extract(struct install_partition_desc *install) +evbarm_extract_finalize(int update) { + distinfo *dist; char kernelbin[100]; + int (*saved_fetch_fn)(const char *); +#ifdef _LP64 +#define EFIBOOT "/usr/mdec/bootaa64.efi" +#else +#define EFIBOOT "/usr/mdec/bootarm.efi" +#endif - if (boardtype == BOARD_TYPE_NORMAL) + dist = get_set_distinfo(SET_KERNEL_1); + if (dist == NULL) return 0; + + saved_fetch_fn = fetch_fn; + extract_file_to(dist, false, "/", "./netbsd", false); + fetch_fn = NULL; + make_target_dir("/boot/EFI/boot"); + if (target_file_exists_p(EFIBOOT)) + cp_within_target(EFIBOOT, "/boot/EFI/boot", 0); + + if (boardtype == BOARD_TYPE_ACPI) { + fetch_fn = saved_fetch_fn; + return 0; + } + if (boardtype == BOARD_TYPE_NORMAL) { + make_target_dir("/boot/dtb"); + extract_file_to(dist, false, "/boot/dtb", "*.dt*", false); + extract_file_to(dist, false, "/boot", "./netbsd.ub", false); + fetch_fn = saved_fetch_fn; + return 0; + } if (boardtype == BOARD_TYPE_RPI) { + extract_file_to(dist, false, "/boot", "./netbsd.img", false); + extract_file_to(dist, false, "/boot", "./bcm*.dtb", false); + fetch_fn = saved_fetch_fn; snprintf(kernelbin, 100, "%s/netbsd.img", targetroot_mnt); if (file_exists_p(kernelbin)) { run_program(RUN_DISPLAY, @@ -212,6 +241,14 @@ md_post_extract(struct install_partition_desc *install) return 1; } } + fetch_fn = saved_fetch_fn; + return 0; +} + +int +md_post_extract(struct install_partition_desc *install) +{ + return 0; } @@ -252,86 +289,36 @@ md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet) struct mbr_partition *part; int i, hasboot=0; - if (boardtype == BOARD_TYPE_NORMAL) - return 2; - /* raspi code */ - if (boardtype == BOARD_TYPE_RPI) { - for (ext = mbri; ext; ext = ext->extended) { - part = ext->mbr.mbr_parts; - for (i=0, hasboot=0; i < MBR_PART_COUNT; part++, i++) { - if (part->mbrp_type != MBR_PTYPE_FAT16L && - part->mbrp_type != MBR_PTYPE_FAT32L) - continue; - hasboot = 1; - break; - } - } - if (!hasboot) { - if (quiet) - return 2; - msg_display(MSG_nomsdospart); - return ask_reedit(parts); + for (ext = mbri; ext; ext = ext->extended) { + part = ext->mbr.mbr_parts; + for (i=0, hasboot=0; i < MBR_PART_COUNT; part++, i++) { + if (part->mbrp_type != MBR_PTYPE_FAT16L && + part->mbrp_type != MBR_PTYPE_FAT32L) + continue; + hasboot = 1; + break; } } + if (!hasboot) { + if (quiet) + return 2; + msg_display(MSG_nomsdospart); + return ask_reedit(parts); + } + return 2; } bool md_parts_use_wholedisk(struct disk_partitions *parts) { - part_id nbsd, boot; - struct disk_part_info info; - daddr_t offset; + struct disk_part_info boot_part = { + .size = boardtype == BOARD_TYPE_NORMAL ? + PART_BOOT_LARGE/512 : PART_BOOT/512, + .fs_type = PART_BOOT_TYPE, .fs_sub_type = MBR_PTYPE_FAT16L, + }; - /* - * XXX - set (U)EFI install depending on boardtype - */ - - if (boardtype == BOARD_TYPE_NORMAL) { - /* this keeps it from creating /boot as msdos */ - pm->bootsize = 0; - return parts_use_wholedisk(parts, 0, NULL); - } - - /* raspi code */ - if (boardtype == BOARD_TYPE_RPI) { - - for (boot = 0; boot < parts->num_part; boot++) { - if (!parts->pscheme->get_part_info(parts, boot, &info)) - continue; - if (info.nat_type == NULL) - continue; - if (info.nat_type->generic_ptype == PT_FAT) - break; - } - - if (boot >= parts->num_part) { - /* It's hopelessly corrupt, punt for now */ - msg_display(MSG_nomsdospart); - process_menu(MENU_ok, NULL); - return false; - } - pm->bootstart = info.start; - pm->bootsize = info.size; - offset = info.start + info.size + 1; - memset(&info, 0, sizeof info); - info.start = offset; - info.size = parts->pscheme->max_free_space_at(parts, offset); - info.nat_type = parts->pscheme->get_generic_part_type(PT_root); - info.fs_type = FS_BSDFFS; - info.fs_sub_type = 2; - - nbsd = parts->pscheme->add_partition(parts, &info, NULL); - if (nbsd == NO_PART) - return false; - - parts->pscheme->get_part_info(parts, nbsd, &info); - pm->ptstart = info.start; - pm->ptsize = info.size; - return true; - } - - return parts_use_wholedisk(parts, 0, NULL); + return parts_use_wholedisk(parts, 1, &boot_part); } /* returns false if no write-back of parts is required */ @@ -353,3 +340,23 @@ md_gpt_post_write(struct disk_partitions *parts, part_id root_id, return true; } #endif + +void +evbarm_part_defaults(struct pm_devs *my_pm, struct part_usage_info *infos, + size_t num_usage_infos) +{ + size_t i; + + if (boardtype != BOARD_TYPE_NORMAL) + return; + + for (i = 0; i < num_usage_infos; i++) { + if (infos[i].fs_type == PART_BOOT_TYPE && + infos[i].mount != NULL && + strcmp(infos[i].mount, PART_BOOT_MOUNT) == 0) { + infos[i].size = PART_BOOT_LARGE; + return; + } + } +} + diff --git a/usr.sbin/sysinst/arch/evbarm/md.h b/usr.sbin/sysinst/arch/evbarm/md.h index 475b9738b2ed..dd64a976c791 100644 --- a/usr.sbin/sysinst/arch/evbarm/md.h +++ b/usr.sbin/sysinst/arch/evbarm/md.h @@ -1,4 +1,4 @@ -/* $NetBSD: md.h,v 1.4 2020/01/09 17:06:46 martin Exp $ */ +/* $NetBSD: md.h,v 1.5 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -39,19 +39,30 @@ /* Constants and defines */ #define PART_BOOT (16*MEG) +#define PART_BOOT_LARGE (32*MEG) #define PART_BOOT_TYPE FS_MSDOS +#define PART_BOOT_SUBT MBR_PTYPE_FAT16L #define PART_BOOT_MOUNT "/boot" /* Megs required for a full X installation. */ #define XNEEDMB 60 +#define DEFSWAPSIZE (-1) + +/* use UFS2 by default for ffs */ +#define DEFAULT_UFS2 + #define HAVE_UFS2_BOOT +/* allow using tmpfs for /tmp instead of mfs */ +#define HAVE_TMPFS + /* * Default filesets to fetch and install during installation * or upgrade. The standard sets are: * base etc comp games man misc rescue tests text xbase xcomp xetc xfont xserver */ +#if 0 /* XXX */ #define SET_KERNEL_1_NAME "kern-ADI_BRH" #define SET_KERNEL_2_NAME "kern-INTEGRATOR" #define SET_KERNEL_3_NAME "kern-IQ80310" @@ -61,7 +72,13 @@ #define SET_KERNEL_7_NAME "kern-TS7200" #define SET_KERNEL_8_NAME "kern-RPI" #define SET_KERNEL_9_NAME "kern-KUROBOX_PRO" -#define SET_KERNEL_RPI SET_KERNEL_8 +#endif + +#ifdef _LP64 +#define SET_KERNEL_1_NAME "kern-GENERIC64" +#else +#define SET_KERNEL_1_NAME "kern-GENERIC" +#endif #define MD_SETS_SELECTED SET_SYSTEM @@ -87,3 +104,17 @@ int boardtype; */ #define MD_GPT_INITIAL_SIZE (8*1024) + +#define HAVE_GPT_BOOT /* yes, u-boot can boot us from GPT */ +#define NO_DISKLABEL_BOOT /* ... but not directly from disklabel */ + +#define MD_MAY_SWAP_TO(DISK) may_swap_if_not_sdmmc(DISK) + +int evbarm_extract_finalize(int); +#define MD_SET_EXTRACT_FINALIZE(UP) evbarm_extract_finalize(UP) + +void evbarm_part_defaults(struct pm_devs*, struct part_usage_info*, + size_t num_usage_infos); + +#define MD_PART_DEFAULTS(A,B,C) evbarm_part_defaults(A,B,C) + diff --git a/usr.sbin/sysinst/bsddisklabel.c b/usr.sbin/sysinst/bsddisklabel.c index 67c5958d110e..a9b0df53f0c6 100644 --- a/usr.sbin/sysinst/bsddisklabel.c +++ b/usr.sbin/sysinst/bsddisklabel.c @@ -1,4 +1,4 @@ -/* $NetBSD: bsddisklabel.c,v 1.35 2020/01/16 16:47:19 martin Exp $ */ +/* $NetBSD: bsddisklabel.c,v 1.36 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -949,10 +949,28 @@ fill_defaults(struct partition_usage_set *wanted, struct disk_partitions *parts, for (i = 0; i < wanted->num; i++) { wanted->infos[i].parts = parts; wanted->infos[i].cur_part_id = NO_PART; + if (wanted->infos[i].type == PT_undef && + wanted->infos[i].fs_type != FS_UNUSED) { + const struct part_type_desc *pt = + parts->pscheme->get_fs_part_type(PT_undef, + wanted->infos[i].fs_type, + wanted->infos[i].fs_version); + if (pt != NULL) + wanted->infos[i].type = pt->generic_ptype; + } + if (wanted->parts->parent != NULL && + wanted->infos[i].fs_type == FS_MSDOS) + wanted->infos[i].flags |= + PUIFLG_ADD_INNER|PUIFLAG_ADD_OUTER; #if DEFSWAPSIZE == -1 - if (wanted->infos[i].type == PT_swap) - wanted->infos[i].size = get_ramsize() * (MEG / 512); + if (wanted->infos[i].type == PT_swap) { +#ifdef MD_MAY_SWAP_TO + if (MD_MAY_SWAP_TO(wanted->parts->disk)) +#endif + wanted->infos[i].size = + get_ramsize() * (MEG / 512); + } #endif if (wanted->infos[i].type == PT_swap && swap > wanted->num) swap = i; @@ -988,7 +1006,8 @@ fill_defaults(struct partition_usage_set *wanted, struct disk_partitions *parts, * empty disk. Merge the partitions in target range that are already * there (match with wanted) or are there additionaly. * The only thing outside of target range that we care for - * is a potential swap partition - we assume one is enough. + * are FAT partitions and a potential swap partition - we assume one + * is enough. */ size_t num = wanted->num; if (parts->parent) { @@ -998,7 +1017,8 @@ fill_defaults(struct partition_usage_set *wanted, struct disk_partitions *parts, if (!parts->parent->pscheme->get_part_info( parts->parent, pno, &info)) continue; - if (info.nat_type->generic_ptype != PT_swap) + if (info.nat_type->generic_ptype != PT_swap && + info.fs_type != FS_MSDOS) continue; merge_part_with_wanted(parts->parent, pno, &info, wanted, num, true); @@ -1297,16 +1317,16 @@ apply_settings_to_partitions(struct pm_devs *p, struct disk_partitions *parts, if ((wanted->infos[i].flags & PUIFLAG_EXTEND) && exp_ndx == ~0U) exp_ndx = i; - if (wanted->infos[i].flags & - (PUIFLG_JUST_MOUNTPOINT|PUIFLG_IS_OUTER)) + if (wanted->infos[i].flags & PUIFLG_JUST_MOUNTPOINT) continue; nsp = wanted->infos[i].size; if (wanted->infos[i].cur_part_id != NO_PART) { ps = wanted->infos[i].flags & PUIFLG_IS_OUTER ? parts->parent : parts; - if (ps->pscheme->get_part_info(ps, - wanted->infos[i].cur_part_id, &infos[i])) + ps->pscheme->get_part_info(ps, + wanted->infos[i].cur_part_id, &infos[i]); + if (!(wanted->infos[i].flags & PUIFLG_IS_OUTER)) nsp -= infos[i].size; } if (nsp > 0) @@ -1343,9 +1363,11 @@ apply_settings_to_partitions(struct pm_devs *p, struct disk_partitions *parts, infos[i].start); if (free_size < wanted->infos[i].size) continue; - infos[i].size = wanted->infos[i].size; - ps->pscheme->set_part_info(ps, want->cur_part_id, - &infos[i], NULL); + if (infos[i].size != wanted->infos[i].size) { + infos[i].size = wanted->infos[i].size; + ps->pscheme->set_part_info(ps, want->cur_part_id, + &infos[i], NULL); + } } from = -1; @@ -1488,7 +1510,7 @@ apply_settings_to_partitions(struct pm_devs *p, struct disk_partitions *parts, for (i = 0; i < wanted->num; i++) { struct part_usage_info *want = &wanted->infos[i]; - if (want->cur_part_id != NO_PART) + if (want->cur_part_id == NO_PART) continue; if (want->flags & PUIFLG_JUST_MOUNTPOINT) continue; @@ -1522,6 +1544,13 @@ apply_settings_to_partitions(struct pm_devs *p, struct disk_partitions *parts, wanted->parts->pscheme->get_part_info( wanted->parts, new_part_id, &infos[i]); + want->parts = wanted->parts; + if (want->fs_type != FS_UNUSED && + want->type != PT_swap) { + want->instflags |= PUIINST_NEWFS; + if (want->mount[0] != 0) + want->instflags |= PUIINST_MOUNT; + } } /* diff --git a/usr.sbin/sysinst/defs.h b/usr.sbin/sysinst/defs.h index 4dee51698552..8cc384c68537 100644 --- a/usr.sbin/sysinst/defs.h +++ b/usr.sbin/sysinst/defs.h @@ -1,4 +1,4 @@ -/* $NetBSD: defs.h,v 1.51 2020/01/16 16:47:19 martin Exp $ */ +/* $NetBSD: defs.h,v 1.52 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -789,6 +789,7 @@ int get_via_localdir(void); void show_cur_distsets(void); void make_ramdisk_dir(const char *); void set_kernel_set(unsigned int); +void set_noextract_set(unsigned int); unsigned int get_kernel_set(void); unsigned int set_X11_selected(void); int get_and_unpack_sets(int, msg, msg, msg); @@ -811,7 +812,10 @@ const char *set_dir_for_set(const char *); const char *ext_dir_for_set(const char *); void replace(const char *, const char *, ...) __printflike(2, 3); void get_tz_default(void); +distinfo* get_set_distinfo(int); int extract_file(distinfo *, int); +int extract_file_to(distinfo *dist, int update, const char *dest_dir, + const char *extr_pattern, bool do_stats); void do_coloring (unsigned int, unsigned int); int set_menu_select(menudesc *, void *); const char *safectime(time_t *); @@ -823,6 +827,7 @@ void free_usage_set(struct partition_usage_set*); bool install_desc_from_parts(struct install_partition_desc *, struct disk_partitions*); void free_install_desc(struct install_partition_desc*); +bool may_swap_if_not_sdmmc(const char*); /* from target.c */ #if defined(DEBUG) || defined(DEBUG_ROOT) diff --git a/usr.sbin/sysinst/disklabel.c b/usr.sbin/sysinst/disklabel.c index 2bbe86c30111..35ed9a992429 100644 --- a/usr.sbin/sysinst/disklabel.c +++ b/usr.sbin/sysinst/disklabel.c @@ -1,4 +1,4 @@ -/* $NetBSD: disklabel.c,v 1.30 2020/01/15 19:36:30 martin Exp $ */ +/* $NetBSD: disklabel.c,v 1.31 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 2018 The NetBSD Foundation, Inc. @@ -123,6 +123,13 @@ disklabel_cylinder_size(const struct disk_partitions *arg) return parts->l.d_secpercyl; } +static bool +disklabel_non_bootable(const char *disk) +{ + + return false; +} + static struct disk_partitions * disklabel_parts_new(const char *dev, daddr_t start, daddr_t len, daddr_t total_size, bool is_boot_drive, struct disk_partitions *parent) @@ -1221,6 +1228,9 @@ disklabel_parts = { .write_to_disk = disklabel_write_to_disk, .read_from_disk = disklabel_parts_read, .create_new_for_disk = disklabel_parts_new, +#ifdef NO_DISKLABEL_BOOT + .have_boot_support = disklabel_non_bootable, +#endif .change_disk_geom = disklabel_change_geom, .get_cylinder_size = disklabel_cylinder_size, .find_by_name = disklabel_find_by_name, diff --git a/usr.sbin/sysinst/mbr.c b/usr.sbin/sysinst/mbr.c index 8016d8c37325..217ffc82d121 100644 --- a/usr.sbin/sysinst/mbr.c +++ b/usr.sbin/sysinst/mbr.c @@ -1,4 +1,4 @@ -/* $NetBSD: mbr.c,v 1.28 2020/01/18 18:39:55 martin Exp $ */ +/* $NetBSD: mbr.c,v 1.29 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -1017,6 +1017,10 @@ mbr_map_part_type(unsigned int t) switch (t) { case MBR_PTYPE_FAT32: case MBR_PTYPE_FAT32L: + case MBR_PTYPE_FAT16S: + case MBR_PTYPE_FAT16B: + case MBR_PTYPE_FAT16L: + case MBR_PTYPE_FAT12: case MBR_PTYPE_FT_FAT32: case MBR_PTYPE_FT_FAT32_EXT: return PT_FAT; diff --git a/usr.sbin/sysinst/part_edit.c b/usr.sbin/sysinst/part_edit.c index 1044243a495f..6bdd9d51292e 100644 --- a/usr.sbin/sysinst/part_edit.c +++ b/usr.sbin/sysinst/part_edit.c @@ -1,4 +1,4 @@ -/* $NetBSD: part_edit.c,v 1.14 2020/01/09 13:22:30 martin Exp $ */ +/* $NetBSD: part_edit.c,v 1.15 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright (c) 2019 The NetBSD Foundation, Inc. @@ -973,6 +973,10 @@ parts_use_wholedisk(struct disk_partitions *parts, 1, info.size, align, -1, -1) != 1) return false; info.start = space.start; + if (info.nat_type == NULL) + info.nat_type = parts->pscheme-> + get_fs_part_type(PT_undef, info.fs_type, + info.fs_sub_type); if (parts->pscheme->add_partition(parts, &info, NULL) == NO_PART) return false; diff --git a/usr.sbin/sysinst/util.c b/usr.sbin/sysinst/util.c index 1a4510f72c1a..7bbeb725b729 100644 --- a/usr.sbin/sysinst/util.c +++ b/usr.sbin/sysinst/util.c @@ -1,4 +1,4 @@ -/* $NetBSD: util.c,v 1.40 2019/11/16 21:25:14 martin Exp $ */ +/* $NetBSD: util.c,v 1.41 2020/01/20 21:26:35 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -59,6 +59,9 @@ #include "defsizes.h" #include "msg_defs.h" #include "menu_defs.h" +#ifdef MD_MAY_SWAP_TO +#include +#endif #define MAX_CD_DEVS 256 /* how many cd drives do we expect to attach */ #define ISO_BLKSIZE ISO_DEFAULT_BLOCK_SIZE @@ -71,6 +74,7 @@ static uint8_t set_status[SET_GROUP_END]; #define SET_SELECTED 0x02 #define SET_SKIPPED 0x04 #define SET_INSTALLED 0x08 +#define SET_NO_EXTRACT 0x10 struct tarstats { int nselected; @@ -721,6 +725,13 @@ set_kernel_set(unsigned int kernel_set) set_status[kernel_set] |= SET_SELECTED; } +void +set_noextract_set(unsigned int set) +{ + + set_status[set] |= SET_NO_EXTRACT; +} + static int set_toggle(menudesc *menu, void *arg) { @@ -906,6 +917,23 @@ customise_sets(void) int extract_file(distinfo *dist, int update) +{ + const char *dest_dir = NULL; + + if (update && (dist->set == SET_ETC || dist->set == SET_X11_ETC)) { + dest_dir = "/.sysinst"; + make_target_dir(dest_dir); + } else if (dist->set == SET_PKGSRC) + dest_dir = "/usr"; + else + dest_dir = "/"; + + return extract_file_to(dist, update, dest_dir, NULL, true); +} + +int +extract_file_to(distinfo *dist, int update, const char *dest_dir, + const char *extr_pattern, bool do_stats) { char path[STRSIZE]; char *owd; @@ -942,7 +970,8 @@ extract_file(distinfo *dist, int update) if (!file_exists_p(path)) { #endif /* SUPPORT_8_3_SOURCE_FILESYSTEM */ - tarstats.nnotfound++; + if (do_stats) + tarstats.nnotfound++; char *err = str_arg_subst(msg_string(MSG_notarfile), 1, &dist->name); @@ -955,15 +984,10 @@ extract_file(distinfo *dist, int update) } #endif /* SUPPORT_8_3_SOURCE_FILESYSTEM */ - tarstats.nfound++; + if (do_stats) + tarstats.nfound++; /* cd to the target root. */ - if (update && (dist->set == SET_ETC || dist->set == SET_X11_ETC)) { - make_target_dir("/.sysinst"); - target_chdir_or_die("/.sysinst"); - } else if (dist->set == SET_PKGSRC) - target_chdir_or_die("/usr"); - else - target_chdir_or_die("/"); + target_chdir_or_die(dest_dir); /* * /usr/X11R7/lib/X11/xkb/symbols/pc was a directory in 5.0 @@ -974,16 +998,24 @@ extract_file(distinfo *dist, int update) run_program(0, "rm -rf usr/X11R7/lib/X11/xkb/symbols/pc"); /* now extract set files into "./". */ - rval = run_program(RUN_DISPLAY | RUN_PROGRESS, - "progress -zf %s tar --chroot " - TAR_EXTRACT_FLAGS " -", path); + if (extr_pattern != NULL) { + rval = run_program(RUN_DISPLAY | RUN_PROGRESS, + "progress -zf %s tar --chroot " + TAR_EXTRACT_FLAGS " - '%s'", + path, extr_pattern); + } else { + rval = run_program(RUN_DISPLAY | RUN_PROGRESS, + "progress -zf %s tar --chroot " + TAR_EXTRACT_FLAGS " -", path); + } chdir(owd); free(owd); /* Check rval for errors and give warning. */ if (rval != 0) { - tarstats.nerror++; + if (do_stats) + tarstats.nerror++; msg_fmt_display(MSG_tarerror, "%s", path); hit_enter_to_continue(NULL, NULL); return SET_RETRY; @@ -995,7 +1027,8 @@ extract_file(distinfo *dist, int update) } set_status[dist->set] |= SET_INSTALLED; - tarstats.nsuccess++; + if (do_stats) + tarstats.nsuccess++; return SET_OK; } @@ -1020,6 +1053,27 @@ skip_set(distinfo *dist, int skip_type) } } +distinfo* +get_set_distinfo(int opt) +{ + distinfo *dist; + int set; + + for (dist = dist_list; (set = dist->set) != SET_LAST; dist++) { + if (set != opt) + continue; + if (dist->name == NULL) + continue; + if ((set_status[set] & (SET_VALID | SET_SELECTED)) + != (SET_VALID | SET_SELECTED)) + continue; + return dist; + } + + return NULL; +} + + /* * Get and unpack the distribution. * Show success_msg if installation completes. @@ -1047,6 +1101,8 @@ get_and_unpack_sets(int update, msg setupdone_msg, msg success_msg, msg failure_ for (dist = dist_list; (set = dist->set) != SET_LAST; dist++) { if (dist->name == NULL) continue; + if (set_status[set] & SET_NO_EXTRACT) + continue; if ((set_status[set] & (SET_VALID | SET_SELECTED)) == (SET_VALID | SET_SELECTED)) tarstats.nselected++; @@ -1090,12 +1146,19 @@ get_and_unpack_sets(int update, msg setupdone_msg, msg success_msg, msg failure_ } } + if (set_status[set] & SET_NO_EXTRACT) + continue; + /* Try to extract this set */ status = extract_file(dist, update); if (status == SET_RETRY) dist--; } +#ifdef MD_SET_EXTRACT_FINALIZE + MD_SET_EXTRACT_FINALIZE(update); +#endif + if (tarstats.nerror == 0 && tarstats.nsuccess == tarstats.nselected) { msg_display(MSG_endtarok); /* Give user a chance to see the success message */ @@ -2126,3 +2189,59 @@ free_install_desc(struct install_partition_desc *install) free(install->infos); } +#ifdef MD_MAY_SWAP_TO +bool +may_swap_if_not_sdmmc(const char *disk) +{ + int fd, res; + prop_dictionary_t command_dict, args_dict, results_dict, data_dict; + prop_string_t string; + prop_number_t number; + const char *parent = ""; + + fd = open(DRVCTLDEV, O_RDONLY, 0); + if (fd == -1) + return true; + + command_dict = prop_dictionary_create(); + args_dict = prop_dictionary_create(); + + string = prop_string_create_cstring_nocopy("get-properties"); + prop_dictionary_set(command_dict, "drvctl-command", string); + prop_object_release(string); + + string = prop_string_create_cstring(disk); + prop_dictionary_set(args_dict, "device-name", string); + prop_object_release(string); + + prop_dictionary_set(command_dict, "drvctl-arguments", + args_dict); + prop_object_release(args_dict); + + res = prop_dictionary_sendrecv_ioctl(command_dict, fd, + DRVCTLCOMMAND, &results_dict); + prop_object_release(command_dict); + close(fd); + if (res) + return true; + + number = prop_dictionary_get(results_dict, "drvctl-error"); + if (prop_number_integer_value(number) == 0) { + data_dict = prop_dictionary_get(results_dict, + "drvctl-result-data"); + if (data_dict != NULL) { + string = prop_dictionary_get(data_dict, + "device-parent"); + if (string != NULL) + parent = prop_string_cstring_nocopy(string); + } + } + + prop_object_release(results_dict); + + if (parent == NULL) + return true; + + return strncmp(parent, "sdmmc", 5) != 0; +} +#endif