diff options
| author | Andy Fiddaman <omnios@citrus-it.co.uk> | 2018-08-29 14:58:43 +0000 |
|---|---|---|
| committer | Robert Mustacchi <rm@joyent.com> | 2018-09-21 15:12:28 +0000 |
| commit | 75383e32bbd38e24115eefe5dee272d42a5c723e (patch) | |
| tree | b86871b136837439650d0b884cc51877cb245312 /usr/src/cmd | |
| parent | c057d312c6f715bb3aeadb653466e7046f26c4af (diff) | |
| download | illumos-joyent-75383e32bbd38e24115eefe5dee272d42a5c723e.tar.gz | |
9627 No longer need 32-bit boot_archive
9628 UFS boot archives are too large
9721 cmd/boot: support cpio boot archive
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src/cmd')
| -rw-r--r-- | usr/src/cmd/boot/bootadm/Makefile | 3 | ||||
| -rw-r--r-- | usr/src/cmd/boot/bootadm/bootadm.c | 589 | ||||
| -rw-r--r-- | usr/src/cmd/boot/scripts/boot-archive-update.ksh | 9 | ||||
| -rw-r--r-- | usr/src/cmd/boot/scripts/create_ramdisk.ksh | 487 | ||||
| -rw-r--r-- | usr/src/cmd/halt/halt.c | 15 | ||||
| -rw-r--r-- | usr/src/cmd/svc/milestone/boot-archive.xml | 8 |
6 files changed, 564 insertions, 547 deletions
diff --git a/usr/src/cmd/boot/bootadm/Makefile b/usr/src/cmd/boot/bootadm/Makefile index b25c45ce04..da5dbf5332 100644 --- a/usr/src/cmd/boot/bootadm/Makefile +++ b/usr/src/cmd/boot/bootadm/Makefile @@ -24,6 +24,7 @@ # # Copyright 2016 Toomas Soome <tsoome@me.com> # Copyright 2016 Nexenta Systems, Inc. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # PROG= bootadm @@ -43,7 +44,7 @@ POFILE= bootadm_cmd.po LDLIBS_i386= -lfdisk LDLIBS += -lficl-sys -lmd -lcryptoutil -lnvpair -lgen -ladm -lefi -LDLIBS += -lz -lbe -lzfs -lofmt $(LDLIBS_$(MACH)) +LDLIBS += -lscf -lz -lbe -lzfs -lofmt $(LDLIBS_$(MACH)) # Writing into string literals is incorrect. We need to match gcc's # behavior, which causes us to take SIGSEGV on such a write. diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c index 0444c5cda7..bedca2a6b5 100644 --- a/usr/src/cmd/boot/bootadm/bootadm.c +++ b/usr/src/cmd/boot/bootadm/bootadm.c @@ -31,7 +31,7 @@ /* * bootadm(1M) is a new utility for managing bootability of * Solaris *Newboot* environments. It has two primary tasks: - * - Allow end users to manage bootability of Newboot Solaris instances + * - Allow end users to manage bootability of Newboot Solaris instances * - Provide services to other subsystems in Solaris (primarily Install) */ @@ -125,6 +125,11 @@ typedef enum { #define UFS_SIGNATURE_LIST "/var/run/grub_ufs_signatures" #define ZFS_LEGACY_MNTPT "/tmp/bootadm_mnt_zfs_legacy" +/* SMF */ +#define BOOT_ARCHIVE_FMRI "system/boot-archive:default" +#define SCF_PG_CONFIG "config" +#define SCF_PROPERTY_FORMAT "format" + /* BE defaults */ #define BE_DEFAULTS "/etc/default/be" #define BE_DFLT_BE_HAS_GRUB "BE_HAS_GRUB=" @@ -184,6 +189,17 @@ char *menu_cmds[] = { NULL }; +char *bam_formats[] = { + "hsfs", + "ufs", + "cpio", + "ufs-nocompress", + NULL +}; +#define BAM_FORMAT_UNSET -1 +#define BAM_FORMAT_HSFS 0 +short bam_format = BAM_FORMAT_UNSET; + #define OPT_ENTRY_NUM "entry" /* @@ -208,6 +224,7 @@ typedef struct { int bam_verbose; int bam_force; int bam_debug; +int bam_skip_lock; static char *prog; static subcmd_t bam_cmd; char *bam_root; @@ -309,29 +326,27 @@ static subcmd_defn_t inst_subcmds[] = { NULL, 0, NULL, 0 /* must be last */ }; -enum dircache_copy_opt { - FILE32 = 0, - FILE64, - CACHEDIR_NUM -}; +#define build_path(buf, len, root, prefix, suffix) \ + snprintf((buf), (len), "%s%s%s%s%s", (root), (prefix), get_machine(), \ + is_flag_on(IS_SPARC_TARGET) ? "" : "/amd64", (suffix)) /* * Directory specific flags: * NEED_UPDATE : the specified archive needs to be updated - * NO_MULTI : don't extend the specified archive, but recreate it + * NO_EXTEND : don't extend the specified archive, but recreate it */ #define NEED_UPDATE 0x00000001 -#define NO_MULTI 0x00000002 +#define NO_EXTEND 0x00000002 -#define set_dir_flag(id, f) (walk_arg.dirinfo[id].flags |= f) -#define unset_dir_flag(id, f) (walk_arg.dirinfo[id].flags &= ~f) -#define is_dir_flag_on(id, f) (walk_arg.dirinfo[id].flags & f ? 1 : 0) +#define set_dir_flag(f) (walk_arg.dirinfo.flags |= (f)) +#define unset_dir_flag(f) (walk_arg.dirinfo.flags &= ~(f)) +#define is_dir_flag_on(f) (walk_arg.dirinfo.flags & (f) ? 1 : 0) -#define get_cachedir(id) (walk_arg.dirinfo[id].cdir_path) -#define get_updatedir(id) (walk_arg.dirinfo[id].update_path) -#define get_count(id) (walk_arg.dirinfo[id].count) -#define has_cachedir(id) (walk_arg.dirinfo[id].has_dir) -#define set_dir_present(id) (walk_arg.dirinfo[id].has_dir = 1) +#define get_cachedir() (walk_arg.dirinfo.cdir_path) +#define get_updatedir() (walk_arg.dirinfo.update_path) +#define get_count() (walk_arg.dirinfo.count) +#define has_cachedir() (walk_arg.dirinfo.has_dir) +#define set_dir_present() (walk_arg.dirinfo.has_dir = 1) /* * dirinfo_t (specific cache directory information): @@ -375,11 +390,11 @@ typedef struct _dirinfo { * sparcfile: list of file paths for mkisofs -path-list (SPARC only) */ static struct { - int update_flags; - nvlist_t *new_nvlp; - nvlist_t *old_nvlp; - FILE *sparcfile; - dirinfo_t dirinfo[CACHEDIR_NUM]; + int update_flags; + nvlist_t *new_nvlp; + nvlist_t *old_nvlp; + FILE *sparcfile; + dirinfo_t dirinfo; } walk_arg; struct safefile { @@ -418,7 +433,7 @@ struct iso_pdesc { /* * COUNT_MAX: maximum number of changed files to justify a multisession update * BA_SIZE_MAX: maximum size of the boot_archive to justify a multisession - * update + * update */ #define COUNT_MAX 50 #define BA_SIZE_MAX (50 * 1024 * 1024) @@ -434,7 +449,8 @@ usage(void) /* archive usage */ (void) fprintf(stderr, - "\t%s update-archive [-vn] [-R altroot [-p platform]]\n", prog); + "\t%s update-archive [-vnf] [-R altroot [-p platform]] " + "[-F format]\n", prog); (void) fprintf(stderr, "\t%s list-archive [-R altroot [-p platform]]\n", prog); #if defined(_OBP) @@ -619,7 +635,7 @@ parse_args(int argc, char *argv[]) * The internal syntax and the corresponding functionality are: * -a update -- update-archive * -a list -- list-archive - * -a update-all -- (reboot to sync all mnted OS archive) + * -a update_all -- (reboot to sync all mnted OS archive) * -i install_bootloader -- install-bootloader * -m update_entry -- update-menu * -m list_entry -- list-menu @@ -630,20 +646,21 @@ parse_args(int argc, char *argv[]) * -m list_setting [entry] [value] -- list_setting * * A set of private flags is there too: - * -F -- purge the cache directories and rebuild them + * -Q -- purge the cache directories and rebuild them * -e -- use the (faster) archive update approach (used by * reboot) + * -L -- skip locking */ static void parse_args_internal(int argc, char *argv[]) { - int c, error; + int c, i, error; extern char *optarg; extern int optind, opterr; #if defined(_OBP) - const char *optstring = "a:d:fi:m:no:veFCR:p:P:XZ"; + const char *optstring = "a:d:fF:i:m:no:veQCLR:p:P:XZ"; #else - const char *optstring = "a:d:fi:m:no:veFCMR:p:P:XZ"; + const char *optstring = "a:d:fF:i:m:no:veQCMLR:p:P:XZ"; #endif /* Suppress error message from getopt */ @@ -673,8 +690,30 @@ parse_args_internal(int argc, char *argv[]) bam_force = 1; break; case 'F': + if (bam_format != BAM_FORMAT_UNSET) { + error = 1; + bam_error( + _("multiple formats specified: -%c\n"), c); + } + for (i = 0; bam_formats[i] != NULL; i++) { + if (strcmp(bam_formats[i], optarg) == 0) { + bam_format = i; + break; + } + } + if (bam_format == BAM_FORMAT_UNSET) { + error = 1; + bam_error( + _("unknown format specified: -%c %s\n"), + c, optarg); + } + break; + case 'Q': bam_purge = 1; break; + case 'L': + bam_skip_lock = 1; + break; case 'i': if (bam_cmd) { error = 1; @@ -1648,6 +1687,9 @@ bam_lock(void) struct flock lock; pid_t pid; + if (bam_skip_lock) + return; + bam_lock_fd = open(BAM_LOCK_FILE, O_CREAT|O_RDWR, LOCK_FILE_PERMS); if (bam_lock_fd < 0) { /* @@ -1707,6 +1749,9 @@ bam_unlock(void) { struct flock unlock; + if (bam_skip_lock) + return; + /* * NOP if we don't hold the lock */ @@ -1910,7 +1955,7 @@ list2file(char *root, char *tmp, char *final, line_t *start) static int setup_path(char *path) { - char *p; + char *p; int ret; struct stat sb; @@ -2047,19 +2092,19 @@ cache_close(cachefile cf) } static int -dircache_updatefile(const char *path, int what) +dircache_updatefile(const char *path) { - int ret, exitcode; - char buf[4096 * 4]; - FILE *infile; - cachefile outfile, outupdt; + int ret, exitcode; + char buf[4096 * 4]; + FILE *infile; + cachefile outfile, outupdt; if (bam_nowrite()) { - set_dir_flag(what, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); return (BAM_SUCCESS); } - if (!has_cachedir(what)) + if (!has_cachedir()) return (BAM_SUCCESS); if ((infile = fopen(path, "rb")) == NULL) { @@ -2068,15 +2113,15 @@ dircache_updatefile(const char *path, int what) return (BAM_ERROR); } - ret = setup_file(get_cachedir(what), path, &outfile); + ret = setup_file(get_cachedir(), path, &outfile); if (ret == BAM_ERROR) { exitcode = BAM_ERROR; goto out; } - if (!is_dir_flag_on(what, NO_MULTI)) { - ret = setup_file(get_updatedir(what), path, &outupdt); + if (!is_dir_flag_on(NO_EXTEND)) { + ret = setup_file(get_updatedir(), path, &outupdt); if (ret == BAM_ERROR) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } while ((ret = fread(buf, 1, sizeof (buf), infile)) > 0) { @@ -2084,21 +2129,21 @@ dircache_updatefile(const char *path, int what) exitcode = BAM_ERROR; goto out; } - if (!is_dir_flag_on(what, NO_MULTI)) + if (!is_dir_flag_on(NO_EXTEND)) if (cache_write(outupdt, buf, ret) == BAM_ERROR) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } - set_dir_flag(what, NEED_UPDATE); - get_count(what)++; - if (get_count(what) > COUNT_MAX) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NEED_UPDATE); + get_count()++; + if (get_count() > COUNT_MAX) + set_dir_flag(NO_EXTEND); exitcode = BAM_SUCCESS; out: (void) fclose(infile); if (cache_close(outfile) == BAM_ERROR) exitcode = BAM_ERROR; - if (!is_dir_flag_on(what, NO_MULTI) && + if (!is_dir_flag_on(NO_EXTEND) && cache_close(outupdt) == BAM_ERROR) exitcode = BAM_ERROR; if (exitcode == BAM_ERROR) @@ -2107,7 +2152,7 @@ out: } static int -dircache_updatedir(const char *path, int what, int updt) +dircache_updatedir(const char *path, int updt) { int ret; char dpath[PATH_MAX]; @@ -2117,7 +2162,7 @@ dircache_updatedir(const char *path, int what, int updt) strip = (char *)path + strlen(rootbuf); ret = snprintf(dpath, sizeof (dpath), "%s/%s", updt ? - get_updatedir(what) : get_cachedir(what), strip); + get_updatedir() : get_cachedir(), strip); if (ret >= sizeof (dpath)) { bam_error(_("unable to create path on mountpoint %s, " @@ -2130,9 +2175,9 @@ dircache_updatedir(const char *path, int what, int updt) return (BAM_SUCCESS); if (updt) { - if (!is_dir_flag_on(what, NO_MULTI)) + if (!is_dir_flag_on(NO_EXTEND)) if (!bam_nowrite() && mkdirp(dpath, DIR_PERMS) == -1) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } else { if (!bam_nowrite() && mkdirp(dpath, DIR_PERMS) == -1) { set_flag(UPDATE_ERROR); @@ -2140,7 +2185,7 @@ dircache_updatedir(const char *path, int what, int updt) } } - set_dir_flag(what, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); return (BAM_SUCCESS); } @@ -2190,51 +2235,33 @@ update_dircache(const char *path, int flags) } (void) close(fd); - /* - * If the file is not an executable and is not inside an amd64 - * directory, we copy it in both the cache directories, - * otherwise, we only copy it inside the 64-bit one. - */ if (memcmp(elf.e_ident, ELFMAG, 4) != 0) { - if (strstr(path, "/amd64")) { - rc = dircache_updatefile(path, FILE64); - } else { - rc = dircache_updatefile(path, FILE32); - if (rc == BAM_SUCCESS) - rc = dircache_updatefile(path, FILE64); - } + /* Not an ELF file, include in archive */ + rc = dircache_updatefile(path); } else { - /* - * Based on the ELF class we copy the file in the 32-bit - * or the 64-bit cache directory. - */ - if (elf.e_ident[EI_CLASS] == ELFCLASS32) { - rc = dircache_updatefile(path, FILE32); - } else if (elf.e_ident[EI_CLASS] == ELFCLASS64) { - rc = dircache_updatefile(path, FILE64); - } else { - bam_print(_("WARNING: file %s is neither a " - "32-bit nor a 64-bit ELF\n"), path); - /* paranoid */ - rc = dircache_updatefile(path, FILE32); - if (rc == BAM_SUCCESS) - rc = dircache_updatefile(path, FILE64); + /* Include 64-bit ELF files only */ + switch (elf.e_ident[EI_CLASS]) { + case ELFCLASS32: + bam_print(_("WARNING: ELF file %s is 32-bit " + "and will be excluded\n"), path); + break; + case ELFCLASS64: + rc = dircache_updatefile(path); + break; + default: + bam_print(_("WARNING: ELF file %s is neither " + "32-bit nor 64-bit\n"), path); + break; } } break; } case FTW_D: - if (strstr(path, "/amd64") == NULL) { - rc = dircache_updatedir(path, FILE32, DO_UPDATE_DIR); - if (rc == BAM_SUCCESS) - rc = dircache_updatedir(path, FILE32, - DO_CACHE_DIR); - } else { - if (has_cachedir(FILE64)) { - rc = dircache_updatedir(path, FILE64, - DO_UPDATE_DIR); + if (strstr(path, "/amd64") != NULL) { + if (has_cachedir()) { + rc = dircache_updatedir(path, DO_UPDATE_DIR); if (rc == BAM_SUCCESS) - rc = dircache_updatedir(path, FILE64, + rc = dircache_updatedir(path, DO_CACHE_DIR); } } @@ -2255,13 +2282,13 @@ cmpstat( int flags, struct FTW *ftw) { - uint_t sz; - uint64_t *value; - uint64_t filestat[2]; - int error, ret, status; + uint_t sz; + uint64_t *value; + uint64_t filestat[2]; + int error, ret, status; struct safefile *safefilep; - FILE *fp; + FILE *fp; struct stat sb; regex_t re; @@ -2347,7 +2374,7 @@ cmpstat( bam_print(_(" new %s\n"), file); if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); return (0); } @@ -2371,7 +2398,7 @@ cmpstat( return (0); if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } else { ret = update_dircache(file, flags); if (ret == BAM_ERROR) { @@ -2391,7 +2418,7 @@ cmpstat( * iso image. We just need to know if we are going to rebuild it or not */ if (is_flag_on(IS_SPARC_TARGET) && - is_dir_flag_on(FILE64, NEED_UPDATE) && !bam_nowrite()) + is_dir_flag_on(NEED_UPDATE) && !bam_nowrite()) return (0); /* * File exists in old archive. Check if file has changed @@ -2422,7 +2449,7 @@ cmpstat( } if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } else { ret = update_dircache(file, flags); if (ret == BAM_ERROR) { @@ -2449,10 +2476,10 @@ cmpstat( static int rmdir_r(char *path) { - struct dirent *d = NULL; - DIR *dir = NULL; - char tpath[PATH_MAX]; - struct stat sb; + struct dirent *d = NULL; + DIR *dir = NULL; + char tpath[PATH_MAX]; + struct stat sb; if ((dir = opendir(path)) == NULL) return (-1); @@ -2480,105 +2507,93 @@ rmdir_r(char *path) * If the user requested a 'purge', always recreate the directory from scratch. */ static int -set_cache_dir(char *root, int what) +set_cache_dir(char *root) { struct stat sb; int ret = 0; - ret = snprintf(get_cachedir(what), sizeof (get_cachedir(what)), - "%s%s%s%s%s", root, ARCHIVE_PREFIX, get_machine(), what == FILE64 ? - "/amd64" : "", CACHEDIR_SUFFIX); + ret = build_path(get_cachedir(), sizeof (get_cachedir()), + root, ARCHIVE_PREFIX, CACHEDIR_SUFFIX); - if (ret >= sizeof (get_cachedir(what))) { + if (ret >= sizeof (get_cachedir())) { bam_error(_("unable to create path on mountpoint %s, " "path too long\n"), rootbuf); return (BAM_ERROR); } if (bam_purge || is_flag_on(INVALIDATE_CACHE)) - (void) rmdir_r(get_cachedir(what)); + (void) rmdir_r(get_cachedir()); - if (stat(get_cachedir(what), &sb) != 0 || !(S_ISDIR(sb.st_mode))) { + if (stat(get_cachedir(), &sb) != 0 || !(S_ISDIR(sb.st_mode))) { /* best effort unlink attempt, mkdir will catch errors */ - (void) unlink(get_cachedir(what)); + (void) unlink(get_cachedir()); if (bam_verbose) bam_print(_("archive cache directory not found: %s\n"), - get_cachedir(what)); - ret = mkdir(get_cachedir(what), DIR_PERMS); + get_cachedir()); + ret = mkdir(get_cachedir(), DIR_PERMS); if (ret < 0) { bam_error(_("mkdir of %s failed: %s\n"), - get_cachedir(what), strerror(errno)); - get_cachedir(what)[0] = '\0'; + get_cachedir(), strerror(errno)); + get_cachedir()[0] = '\0'; return (ret); } set_flag(NEED_CACHE_DIR); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } return (BAM_SUCCESS); } static int -set_update_dir(char *root, int what) +set_update_dir(char *root) { struct stat sb; int ret; - if (is_dir_flag_on(what, NO_MULTI)) + if (is_dir_flag_on(NO_EXTEND)) return (BAM_SUCCESS); if (!bam_extend) { - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); return (BAM_SUCCESS); } - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(get_updatedir(what), - sizeof (get_updatedir(what)), "%s%s%s/amd64%s", root, - ARCHIVE_PREFIX, get_machine(), UPDATEDIR_SUFFIX); - else - ret = snprintf(get_updatedir(what), - sizeof (get_updatedir(what)), "%s%s%s%s", root, - ARCHIVE_PREFIX, get_machine(), UPDATEDIR_SUFFIX); + ret = build_path(get_updatedir(), sizeof (get_updatedir()), + root, ARCHIVE_PREFIX, UPDATEDIR_SUFFIX); - if (ret >= sizeof (get_updatedir(what))) { + if (ret >= sizeof (get_updatedir())) { bam_error(_("unable to create path on mountpoint %s, " "path too long\n"), rootbuf); return (BAM_ERROR); } - if (stat(get_updatedir(what), &sb) == 0) { + if (stat(get_updatedir(), &sb) == 0) { if (S_ISDIR(sb.st_mode)) - ret = rmdir_r(get_updatedir(what)); + ret = rmdir_r(get_updatedir()); else - ret = unlink(get_updatedir(what)); + ret = unlink(get_updatedir()); if (ret != 0) - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } - if (mkdir(get_updatedir(what), DIR_PERMS) < 0) - set_dir_flag(what, NO_MULTI); + if (mkdir(get_updatedir(), DIR_PERMS) < 0) + set_dir_flag(NO_EXTEND); return (BAM_SUCCESS); } static int -is_valid_archive(char *root, int what) +is_valid_archive(char *root) { - char archive_path[PATH_MAX]; + char archive_path[PATH_MAX]; char timestamp_path[PATH_MAX]; - struct stat sb, timestamp; - int ret; + struct stat sb, timestamp; + int ret; - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(archive_path, sizeof (archive_path), - "%s%s%s/amd64%s", root, ARCHIVE_PREFIX, get_machine(), - ARCHIVE_SUFFIX); - else - ret = snprintf(archive_path, sizeof (archive_path), "%s%s%s%s", - root, ARCHIVE_PREFIX, get_machine(), ARCHIVE_SUFFIX); + ret = build_path(archive_path, sizeof (archive_path), + root, ARCHIVE_PREFIX, ARCHIVE_SUFFIX); if (ret >= sizeof (archive_path)) { bam_error(_("unable to create path on mountpoint %s, " @@ -2589,8 +2604,7 @@ is_valid_archive(char *root, int what) if (stat(archive_path, &sb) != 0) { if (bam_verbose && !bam_check) bam_print(_("archive not found: %s\n"), archive_path); - set_dir_flag(what, NEED_UPDATE); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NEED_UPDATE | NO_EXTEND); return (BAM_SUCCESS); } @@ -2630,8 +2644,7 @@ is_valid_archive(char *root, int what) } set_flag(INVALIDATE_CACHE); - set_dir_flag(what, NEED_UPDATE); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NEED_UPDATE | NO_EXTEND); return (BAM_SUCCESS); } @@ -2642,7 +2655,7 @@ is_valid_archive(char *root, int what) if (bam_verbose && !bam_check) bam_print(_("archive %s is bigger than %d bytes and " "will be rebuilt\n"), archive_path, BA_SIZE_MAX); - set_dir_flag(what, NO_MULTI); + set_dir_flag(NO_EXTEND); } return (BAM_SUCCESS); @@ -2659,80 +2672,62 @@ static int check_flags_and_files(char *root) { - struct stat sb; - int ret; + struct stat sb; + int ret; /* * If archive is missing, create archive */ - if (is_flag_on(IS_SPARC_TARGET)) { - ret = is_valid_archive(root, FILE64); - if (ret == BAM_ERROR) - return (BAM_ERROR); - } else { - int what = FILE32; - do { - ret = is_valid_archive(root, what); - if (ret == BAM_ERROR) - return (BAM_ERROR); - what++; - } while (bam_direct == BAM_DIRECT_DBOOT && what < CACHEDIR_NUM); - } + ret = is_valid_archive(root); + if (ret == BAM_ERROR) + return (BAM_ERROR); if (bam_nowrite()) return (BAM_SUCCESS); - /* * check if cache directories exist on x86. * check (and always open) the cache file on SPARC. */ if (is_sparc()) { - ret = snprintf(get_cachedir(FILE64), - sizeof (get_cachedir(FILE64)), "%s%s%s/%s", root, + ret = snprintf(get_cachedir(), + sizeof (get_cachedir()), "%s%s%s/%s", root, ARCHIVE_PREFIX, get_machine(), CACHEDIR_SUFFIX); - if (ret >= sizeof (get_cachedir(FILE64))) { + if (ret >= sizeof (get_cachedir())) { bam_error(_("unable to create path on mountpoint %s, " "path too long\n"), rootbuf); return (BAM_ERROR); } - if (stat(get_cachedir(FILE64), &sb) != 0) { + if (stat(get_cachedir(), &sb) != 0) { set_flag(NEED_CACHE_DIR); - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } - walk_arg.sparcfile = fopen(get_cachedir(FILE64), "w"); + walk_arg.sparcfile = fopen(get_cachedir(), "w"); if (walk_arg.sparcfile == NULL) { bam_error(_("failed to open file: %s: %s\n"), - get_cachedir(FILE64), strerror(errno)); + get_cachedir(), strerror(errno)); return (BAM_ERROR); } - set_dir_present(FILE64); + set_dir_present(); } else { - int what = FILE32; - - do { - if (set_cache_dir(root, what) != 0) - return (BAM_ERROR); + if (set_cache_dir(root) != 0) + return (BAM_ERROR); - set_dir_present(what); + set_dir_present(); - if (set_update_dir(root, what) != 0) - return (BAM_ERROR); - what++; - } while (bam_direct == BAM_DIRECT_DBOOT && what < CACHEDIR_NUM); + if (set_update_dir(root) != 0) + return (BAM_ERROR); } /* * if force, create archive unconditionally */ if (bam_force) { - if (!is_sparc()) - set_dir_flag(FILE32, NEED_UPDATE); - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); if (bam_verbose) bam_print(_("forced update of archive requested\n")); return (BAM_SUCCESS); @@ -2744,10 +2739,10 @@ check_flags_and_files(char *root) static error_t read_one_list(char *root, filelist_t *flistp, char *filelist) { - char path[PATH_MAX]; - FILE *fp; - char buf[BAM_MAXLINE]; - const char *fcn = "read_one_list()"; + char path[PATH_MAX]; + FILE *fp; + char buf[BAM_MAXLINE]; + const char *fcn = "read_one_list()"; (void) snprintf(path, sizeof (path), "%s%s", root, filelist); @@ -2774,11 +2769,11 @@ read_one_list(char *root, filelist_t *flistp, char *filelist) static error_t read_list(char *root, filelist_t *flistp) { - char path[PATH_MAX]; - char cmd[PATH_MAX]; - struct stat sb; - int n, rval; - const char *fcn = "read_list()"; + char path[PATH_MAX]; + char cmd[PATH_MAX]; + struct stat sb; + int n, rval; + const char *fcn = "read_list()"; flistp->head = flistp->tail = NULL; @@ -2855,10 +2850,10 @@ read_list(char *root, filelist_t *flistp) static void getoldstat(char *root) { - char path[PATH_MAX]; - int fd, error; - struct stat sb; - char *ostat; + char path[PATH_MAX]; + int fd, error; + struct stat sb; + char *ostat; (void) snprintf(path, sizeof (path), "%s%s", root, FILE_STAT); fd = open(path, O_RDONLY); @@ -2904,26 +2899,24 @@ getoldstat(char *root) out_err: if (fd != -1) (void) close(fd); - if (!is_flag_on(IS_SPARC_TARGET)) - set_dir_flag(FILE32, NEED_UPDATE); - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } /* Best effort stale entry removal */ static void -delete_stale(char *file, int what) +delete_stale(char *file) { char path[PATH_MAX]; struct stat sb; - (void) snprintf(path, sizeof (path), "%s/%s", get_cachedir(what), file); + (void) snprintf(path, sizeof (path), "%s/%s", get_cachedir(), file); if (!bam_check && stat(path, &sb) == 0) { if (sb.st_mode & S_IFDIR) (void) rmdir_r(path); else (void) unlink(path); - set_dir_flag(what, (NEED_UPDATE | NO_MULTI)); + set_dir_flag(NEED_UPDATE | NO_EXTEND); } } @@ -2938,7 +2931,7 @@ check4stale(char *root) { nvpair_t *nvp; nvlist_t *nvlp; - char *file; + char *file; char path[PATH_MAX]; /* @@ -2966,17 +2959,14 @@ check4stale(char *root) (void) snprintf(path, sizeof (path), "%s/%s", root, file); if (access(path, F_OK) < 0) { - int what; - if (bam_verbose) bam_print(_(" stale %s\n"), path); if (is_flag_on(IS_SPARC_TARGET)) { - set_dir_flag(FILE64, NEED_UPDATE); + set_dir_flag(NEED_UPDATE); } else { - for (what = FILE32; what < CACHEDIR_NUM; what++) - if (has_cachedir(what)) - delete_stale(file, what); + if (has_cachedir()) + delete_stale(file); } } } @@ -3058,11 +3048,11 @@ update_timestamp(char *root) static void savenew(char *root) { - char path[PATH_MAX]; - char path2[PATH_MAX]; - size_t sz; - char *nstat; - int fd, wrote, error; + char path[PATH_MAX]; + char path2[PATH_MAX]; + size_t sz; + char *nstat; + int fd, wrote, error; nstat = NULL; sz = 0; @@ -3131,11 +3121,11 @@ clear_walk_args(void) static int update_required(char *root) { - struct stat sb; - char path[PATH_MAX]; - filelist_t flist; - filelist_t *flistp = &flist; - int ret; + struct stat sb; + char path[PATH_MAX]; + filelist_t flist; + filelist_t *flistp = &flist; + int ret; flistp->head = flistp->tail = NULL; @@ -3189,7 +3179,7 @@ update_required(char *root) create_newstat(); /* * This walk does 2 things: - * - gets new stat data for every file + * - gets new stat data for every file * - (optional) compare old and new stat data */ ret = walk_list(root, &flist); @@ -3213,8 +3203,7 @@ update_required(char *root) /* If nothing was updated, discard newstat. */ - if (!is_dir_flag_on(FILE32, NEED_UPDATE) && - !is_dir_flag_on(FILE64, NEED_UPDATE)) { + if (!is_dir_flag_on(NEED_UPDATE)) { clear_walk_args(); return (0); } @@ -3346,14 +3335,61 @@ is_be(char *root) } /* - * Returns 1 if mkiso is in the expected PATH, 0 otherwise + * Returns B_TRUE if mkiso is in the expected PATH and should be used, + * B_FALSE otherwise */ -static int -is_mkisofs() +static boolean_t +use_mkisofs() { - if (access(MKISOFS_PATH, X_OK) == 0) - return (1); - return (0); + scf_simple_prop_t *prop; + char *format = NULL; + boolean_t ret; + + /* Check whether the mkisofs binary is in the expected location */ + if (access(MKISOFS_PATH, X_OK) != 0) { + if (bam_verbose) + bam_print("mkisofs not found\n"); + return (B_FALSE); + } + + if (bam_format == BAM_FORMAT_HSFS) { + if (bam_verbose) + bam_print("-F specified HSFS"); + return (B_TRUE); + } + + /* If working on an alt-root, do not use HSFS unless asked via -F */ + if (bam_alt_root) + return (B_FALSE); + + /* + * Then check that the system/boot-archive config/format property + * is "hsfs" or empty. + */ + if ((prop = scf_simple_prop_get(NULL, BOOT_ARCHIVE_FMRI, SCF_PG_CONFIG, + SCF_PROPERTY_FORMAT)) == NULL) { + /* Could not find property, use mkisofs */ + if (bam_verbose) { + bam_print( + "%s does not have %s/%s property, using mkisofs\n", + BOOT_ARCHIVE_FMRI, SCF_PG_CONFIG, + SCF_PROPERTY_FORMAT); + } + return (B_TRUE); + } + if (scf_simple_prop_numvalues(prop) < 0 || + (format = scf_simple_prop_next_astring(prop)) == NULL) + ret = B_TRUE; + else + ret = strcmp(format, "hsfs") == 0 ? B_TRUE : B_FALSE; + if (bam_verbose) { + if (ret) + bam_print("Creating hsfs boot archive\n"); + else + bam_print("Creating %s boot archive\n", format); + } + scf_simple_prop_free(prop); + return (ret); } #define MKISO_PARAMS " -quiet -graft-points -dlrDJN -relaxed-filenames " @@ -3668,37 +3704,31 @@ create_x86_archive(char *archive, char *tempname, char *update_dir) } static int -mkisofs_archive(char *root, int what) +mkisofs_archive(char *root) { int ret; + char suffix[20]; char temp[PATH_MAX]; - char bootblk[PATH_MAX]; + char bootblk[PATH_MAX]; char boot_archive[PATH_MAX]; - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(temp, sizeof (temp), - "%s%s%s/amd64/archive-new-%d", root, ARCHIVE_PREFIX, - get_machine(), getpid()); - else - ret = snprintf(temp, sizeof (temp), "%s%s%s/archive-new-%d", - root, ARCHIVE_PREFIX, get_machine(), getpid()); + ret = snprintf(suffix, sizeof (suffix), "/archive-new-%d", getpid()); + if (ret >= sizeof (suffix)) + goto out_path_err; + + ret = build_path(temp, sizeof (temp), root, ARCHIVE_PREFIX, suffix); if (ret >= sizeof (temp)) goto out_path_err; - if (what == FILE64 && !is_flag_on(IS_SPARC_TARGET)) - ret = snprintf(boot_archive, sizeof (boot_archive), - "%s%s%s/amd64%s", root, ARCHIVE_PREFIX, get_machine(), - ARCHIVE_SUFFIX); - else - ret = snprintf(boot_archive, sizeof (boot_archive), - "%s%s%s%s", root, ARCHIVE_PREFIX, get_machine(), - ARCHIVE_SUFFIX); + ret = build_path(boot_archive, sizeof (boot_archive), root, + ARCHIVE_PREFIX, ARCHIVE_SUFFIX); if (ret >= sizeof (boot_archive)) goto out_path_err; - bam_print("updating %s\n", boot_archive); + bam_print("updating %s (HSFS)\n", + boot_archive[1] == '/' ? boot_archive + 1 : boot_archive); if (is_flag_on(IS_SPARC_TARGET)) { ret = snprintf(bootblk, sizeof (bootblk), @@ -3707,21 +3737,21 @@ mkisofs_archive(char *root, int what) goto out_path_err; ret = create_sparc_archive(boot_archive, temp, bootblk, - get_cachedir(what)); + get_cachedir()); } else { - if (!is_dir_flag_on(what, NO_MULTI)) { + if (!is_dir_flag_on(NO_EXTEND)) { if (bam_verbose) bam_print("Attempting to extend x86 archive: " "%s\n", boot_archive); ret = extend_iso_archive(boot_archive, temp, - get_updatedir(what)); + get_updatedir()); if (ret == BAM_SUCCESS) { if (bam_verbose) bam_print("Successfully extended %s\n", boot_archive); - (void) rmdir_r(get_updatedir(what)); + (void) rmdir_r(get_updatedir()); return (BAM_SUCCESS); } } @@ -3739,12 +3769,12 @@ mkisofs_archive(char *root, int what) bam_print("Unable to extend %s... rebuilding archive\n", boot_archive); - if (get_updatedir(what)[0] != '\0') - (void) rmdir_r(get_updatedir(what)); + if (get_updatedir()[0] != '\0') + (void) rmdir_r(get_updatedir()); ret = create_x86_archive(boot_archive, temp, - get_cachedir(what)); + get_cachedir()); } if (digest_archive(boot_archive) == BAM_ERROR && bam_verbose) @@ -3767,27 +3797,25 @@ create_ramdisk(char *root) char *cmdline, path[PATH_MAX]; size_t len; struct stat sb; - int ret, what, status = BAM_SUCCESS; - - /* If there is mkisofs, use it to create the required archives */ - if (is_mkisofs()) { - for (what = FILE32; what < CACHEDIR_NUM; what++) { - if (has_cachedir(what) && is_dir_flag_on(what, - NEED_UPDATE)) { - ret = mkisofs_archive(root, what); - if (ret != 0) - status = BAM_ERROR; - } + int ret, status = BAM_SUCCESS; + + /* If mkisofs should be used, use it to create the required archives */ + if (use_mkisofs()) { + if (has_cachedir() && is_dir_flag_on(NEED_UPDATE)) { + ret = mkisofs_archive(root); + if (ret != 0) + status = BAM_ERROR; } return (status); + } else if (bam_format == BAM_FORMAT_HSFS) { + bam_error(_("cannot create hsfs archive\n")); + return (BAM_ERROR); } /* - * Else setup command args for create_ramdisk.ksh for the UFS archives + * Else setup command args for create_ramdisk.ksh for the archive * Note: we will not create hash here, CREATE_RAMDISK should create it. */ - if (bam_verbose) - bam_print("mkisofs not found, creating UFS archive\n"); (void) snprintf(path, sizeof (path), "%s/%s", root, CREATE_RAMDISK); if (stat(path, &sb) != 0) { @@ -3801,7 +3829,9 @@ create_ramdisk(char *root) len = strlen(path) + strlen(root) + 10; /* room for space + -R */ if (bam_alt_platform) - len += strlen(bam_platform) + strlen("-p "); + len += strlen(bam_platform) + strlen(" -p "); + if (bam_format != BAM_FORMAT_UNSET) + len += strlen(bam_formats[bam_format]) + strlen(" -f "); cmdline = s_calloc(1, len); if (bam_alt_platform) { @@ -3817,6 +3847,15 @@ create_ramdisk(char *root) } else (void) snprintf(cmdline, len, "%s", path); + if (bam_format != BAM_FORMAT_UNSET) { + if (strlcat(cmdline, " -f ", len) >= len || + strlcat(cmdline, bam_formats[bam_format], len) >= len) { + bam_error(_("boot-archive command line too long\n")); + free(cmdline); + return (BAM_ERROR); + } + } + if (exec_cmd(cmdline, NULL) != 0) { bam_error(_("boot-archive creation FAILED, command: '%s'\n"), cmdline); @@ -5812,7 +5851,7 @@ get_mountpoint(char *special, char *fstype) /* * Mounts a "legacy" top dataset (if needed) * Returns: The mountpoint of the legacy top dataset or NULL on error - * mnted returns one of the above values defined for zfs_mnted_t + * mnted returns one of the above values defined for zfs_mnted_t */ static char * mount_legacy_dataset(char *pool, zfs_mnted_t *mnted) @@ -5906,7 +5945,7 @@ mount_legacy_dataset(char *pool, zfs_mnted_t *mnted) /* * Mounts the top dataset (if needed) * Returns: The mountpoint of the top dataset or NULL on error - * mnted returns one of the above values defined for zfs_mnted_t + * mnted returns one of the above values defined for zfs_mnted_t */ char * mount_top_dataset(char *pool, zfs_mnted_t *mnted) @@ -6349,7 +6388,7 @@ search_hash(mhash_t *mhp, char *special, char **mntpt) { int idx; mcache_t *mcp; - const char *fcn = "search_hash()"; + const char *fcn = "search_hash()"; assert(mntpt); @@ -7754,7 +7793,7 @@ get_special(char *mountp) struct mnttab mpref = {0}; int error; int ret; - const char *fcn = "get_special()"; + const char *fcn = "get_special()"; INJECT_ERROR1("GET_SPECIAL_MNTPT", mountp = NULL); if (mountp == NULL) { diff --git a/usr/src/cmd/boot/scripts/boot-archive-update.ksh b/usr/src/cmd/boot/scripts/boot-archive-update.ksh index 693c715c73..deae20e814 100644 --- a/usr/src/cmd/boot/scripts/boot-archive-update.ksh +++ b/usr/src/cmd/boot/scripts/boot-archive-update.ksh @@ -22,6 +22,7 @@ # # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # . /lib/svc/share/smf_include.sh @@ -31,14 +32,18 @@ UPDATEFILE=/etc/svc/volatile/boot_archive_safefile_update smf_is_globalzone || exit $SMF_EXIT_OK -# on x86 get rid of transient reboot entry in the GRUB menu -# if [ `uname -p` = "i386" ]; then + # on x86 get rid of transient reboot entry in the GRUB menu if [ -f /stubboot/boot/grub/menu.lst ]; then /sbin/bootadm -m update_temp -R /stubboot else /sbin/bootadm -m update_temp fi + # Remove old 32-bit archives if present. + plat=/platform/`uname -i` + [ -f $plat/boot_archive ] && rm -f $plat/boot_archive + [ -f $plat/boot_archive.hash ] && rm -f $plat/boot_archive.hash + [ -d $plat/archive_cache ] && rm -rf $plat/archive_cache fi if [ -f $UPDATEFILE ] || [ -f /reconfigure ]; then diff --git a/usr/src/cmd/boot/scripts/create_ramdisk.ksh b/usr/src/cmd/boot/scripts/create_ramdisk.ksh index 6ccd546bfd..1f6f4a4dfd 100644 --- a/usr/src/cmd/boot/scripts/create_ramdisk.ksh +++ b/usr/src/cmd/boot/scripts/create_ramdisk.ksh @@ -27,23 +27,25 @@ # # Copyright (c) 2014 by Delphix. All rights reserved. +# Copyright 2018 OmniOS Community Edition (OmniOSce) Association. # ALT_ROOT= EXTRACT_ARGS= +FORMAT= +format_set=0 compress=yes -SPLIT=unknown -ERROR=0 -dirsize32=0 -dirsize64=0 +dirsize=0 usage() { - echo "This utility is a component of the bootadm(1M) implementation" - echo "and it is not recommended for stand-alone use." - echo "Please use bootadm(1M) instead." - echo "" - echo "Usage: ${0##*/}: [-R \<root\>] [-p \<platform\>] [--nocompress]" - echo "where \<platform\> is one of i86pc, sun4u or sun4v" + cat <<- EOM +This utility is a component of the bootadm(1M) implementation and it is not +recommended for stand-alone use. Please use bootadm(1M) instead. + +Usage: ${0##*/}: [-R <root>] [-p <platform>] [ -f <format> ] [--nocompress] +where <platform> is one of i86pc, sun4u or sun4v + and <format> is one of ufs, ufs-nocompress or cpio + EOM exit } @@ -52,15 +54,25 @@ PLATFORM=`uname -m` export PATH=/usr/sbin:/usr/bin:/sbin export GZIP_CMD=/usr/bin/gzip +export CPIO_CMD=/usr/bin/cpio EXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist" # # Parse options # -while [ "$1" != "" ] -do +while [ -n "$1" ]; do case $1 in + -f) shift + FORMAT="$1" + format_set=1 + ;; + -n|--nocompress) compress=no + ;; + -p) shift + PLATFORM="$1" + EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}" + ;; -R) shift ALT_ROOT="$1" if [ "$ALT_ROOT" != "/" ]; then @@ -69,12 +81,6 @@ do EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}" fi ;; - -n|--nocompress) compress=no - ;; - -p) shift - PLATFORM="$1" - EXTRACT_ARGS="${EXTRACT_ARGS} -p ${PLATFORM}" - ;; *) usage ;; esac @@ -88,73 +94,56 @@ if [ $# -eq 1 ]; then echo "Creating boot_archive for $ALT_ROOT" fi -case $PLATFORM in -i386) PLATFORM=i86pc - ISA=i386 - ARCH64=amd64 - ;; -i86pc) ISA=i386 - ARCH64=amd64 - ;; -sun4u) ISA=sparc - ARCH64=sparcv9 - ;; -sun4v) ISA=sparc - ARCH64=sparcv9 - ;; -*) usage - ;; -esac - -BOOT_ARCHIVE=platform/$PLATFORM/boot_archive -BOOT_ARCHIVE_64=platform/$PLATFORM/$ARCH64/boot_archive +if [ -z "$FORMAT" ]; then + if [ -n "$ALT_ROOT" ]; then + SVCCFG_DTD=/$ALT_ROOT/usr/share/lib/xml/dtd/service_bundle.dtd.1 + SVCCFG_REPOSITORY=/$ALT_ROOT/etc/svc/repository.db + export SVCCFG_DTD SVCCFG_REPOSITORY + fi + FORMAT=`svccfg -s system/boot-archive listprop config/format \ + | awk '{print $3}'` +fi -if [ $PLATFORM = i86pc ] ; then - SPLIT=yes -else # must be sparc - SPLIT=no # there's only 64-bit (sparcv9), so don't split - compress=no +if [ $format_set -eq 0 -a "$FORMAT" = hsfs ]; then + if /sbin/bootadm update-archive -R ${ALT_ROOT:-/} -f -L -F hsfs; then + exit 0 + else + echo "Failed to create HSFS archive, falling back." + fi fi -[ -x $GZIP_CMD ] || compress=no +[[ "$FORMAT" =~ ^(cpio|ufs|ufs-nocompress)$ ]] || FORMAT=ufs + +case $PLATFORM in +i386|i86pc) PLATFORM=i86pc + ISA=i386 + ARCH64=amd64 + BOOT_ARCHIVE_SUFFIX=$ARCH64/boot_archive + ;; +sun4u|sun4v) ISA=sparc + ARCH64=sparcv9 + BOOT_ARCHIVE_SUFFIX=boot_archive + compress=no + ;; +*) usage + ;; +esac + +BOOT_ARCHIVE=platform/$PLATFORM/$BOOT_ARCHIVE_SUFFIX -function cleanup +function fatal_error { - umount -f "$rdmnt32" 2>/dev/null - umount -f "$rdmnt64" 2>/dev/null - lofiadm -d "$rdfile32" 2>/dev/null - lofiadm -d "$rdfile64" 2>/dev/null - [ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null - [ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null + print -u2 $* + exit 1 } -function getsize -{ - # Estimate image size and add 10% overhead for ufs stuff. - # Note, we can't use du here in case we're on a filesystem, e.g. zfs, - # in which the disk usage is less than the sum of the file sizes. - # The nawk code - # - # {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} - # - # below rounds up the size of a file/directory, in bytes, to the - # next multiple of 1024. This mimics the behavior of ufs especially - # with directories. This results in a total size that's slightly - # bigger than if du was called on a ufs directory. - size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null | - nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} - END {print int(t * 1.10 / 1024)}') - (( size32 += dirsize32 )) - size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null | - nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} - END {print int(t * 1.10 / 1024)}') - (( size64 += dirsize64 )) - (( total_size = size32 + size64 )) +[ -x $GZIP_CMD ] || compress=no - if [ $compress = yes ] ; then - total_size=`echo $total_size | nawk '{print int($1 / 2)}'` - fi -} +case $FORMAT in +cpio) [ -x $CPIO_CMD ] || FORMAT=ufs ;; +ufs-nocompress) FORMAT=ufs; compress=no ;; +ufs) ;; +esac # # Copies all desired files to a target directory. One argument should be @@ -167,7 +156,7 @@ function getsize # function copy_files { - list="$1" + typeset listfile="$1" # # If compress is set, the files are gzip'd and put in the correct @@ -177,8 +166,7 @@ function copy_files # If compress is not set, the file names are printed, which causes # the cpio at the end to do the copy. # - while read path - do + while read path; do if [ $compress = yes ]; then dir="${path%/*}" [ -d "$rdmnt/$dir" ] || mkdir -p "$rdmnt/$dir" @@ -186,7 +174,7 @@ function copy_files else print "$path" fi - done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null + done <"$listfile" | cpio -pdum "$rdmnt" 2>/dev/null if [ $ISA = sparc ] ; then # copy links @@ -201,39 +189,112 @@ function copy_files } -# -# The first argument can be: -# -# "both" - create an archive with both 32-bit and 64-bit binaries -# "32-bit" - create an archive with only 32-bit binaries -# "64-bit" - create an archive with only 64-bit binaries -# -function create_ufs +function ufs_cleanup { - which=$1 - archive=$2 - lofidev=$3 - - # should we exclude amd64 binaries? - if [ "$which" = "32-bit" ]; then - rdfile="$rdfile32" - rdmnt="$rdmnt32" - list="$list32" - elif [ "$which" = "64-bit" ]; then - rdfile="$rdfile64" - rdmnt="$rdmnt64" - list="$list64" - else - rdfile="$rdfile32" - rdmnt="$rdmnt32" - list="$list32" + umount -f "$rdmnt" 2>/dev/null + lofiadm -d "$rdfile" 2>/dev/null + [ -n "$rddir" ] && rm -fr "$rddir" 2> /dev/null + [ -n "$new_rddir" ] && rm -fr "$new_rddir" 2>/dev/null +} + +function ufs_getsize +{ + # Estimate image size and add 10% overhead for ufs stuff. + # Note, we can't use du here in case we're on a filesystem, e.g. zfs, + # in which the disk usage is less than the sum of the file sizes. + # The nawk code + # + # {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} + # + # below rounds up the size of a file/directory, in bytes, to the + # next multiple of 1024. This mimics the behavior of ufs especially + # with directories. This results in a total size that's slightly + # bigger than if du was called on a ufs directory. + size=$(cat "$list" | xargs -I {} ls -lLd "{}" 2> /dev/null | + nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5} + END {print int(t * 1.10 / 1024)}') + (( size += dirsize )) + (( total_size = size )) + # If compression is enabled, then each file within the archive will + # be individually compressed. The compression ratio is around 60% + # across the archive so make the image smaller. + [ $compress = yes ] && (( total_size = total_size / 2 )) +} + +function create_ufs_archive +{ + typeset archive="$ALT_ROOT/$BOOT_ARCHIVE" + + [ "$compress" = yes ] && \ + echo "updating $archive (UFS)" || \ + echo "updating $archive (UFS-nocompress)" + + # + # We use /tmp/ for scratch space now. This will be changed later to + # $ALT_ROOT/var/tmp if there is insufficient space in /tmp/. + # + rddir="/tmp/create_ramdisk.$$.tmp" + new_rddir= + rm -rf "$rddir" + mkdir "$rddir" || fatal_error "Could not create directory $rddir" + + # Clean up upon exit. + trap 'ufs_cleanup' EXIT + + list="$rddir/filelist" + + cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT" + find $filelist -print 2>/dev/null | while read path; do + if [ -d "$path" ]; then + size=`ls -lLd "$path" | nawk ' + {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'` + (( dirsize += size / 1024 )) + else + print "$path" + fi + done >"$list" + + # calculate image size + ufs_getsize + + # check to see if there is sufficient space in tmpfs + # + tmp_free=`df -b /tmp | tail -1 | awk '{ print $2 }'` + (( tmp_free = tmp_free / 3 )) + + if [ $total_size -gt $tmp_free ] ; then + echo "Insufficient space in /tmp, using $ALT_ROOT/var/tmp" + # assumes we have enough scratch space on $ALT_ROOT + new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp" + rm -rf "$new_rddir" + mkdir "$new_rddir" || fatal_error \ + "Could not create temporary directory $new_rddir" + + # Save the file lists + mv "$list" "$new_rddir"/ + list="/$new_rddir/filelist" + + # Remove the old $rddir and set the new value of rddir + rm -rf "$rddir" + rddir="$new_rddir" + new_rddir= fi - NOINUSE_CHECK=1 newfs $lofidev < /dev/null 2> /dev/null + rdfile="$rddir/rd.file" + rdmnt="$rddir/rd.mount" + errlog="$rddir/rd.errlog" + lofidev="" + + mkfile ${total_size}k "$rdfile" || \ + fatal_error "Could not create backing file" + lofidev=`lofiadm -a "$rdfile"` || \ + fatal_error "Could not create lofi device" + + NOINUSE_CHECK=1 newfs -m 0 $lofidev < /dev/null 2> /dev/null mkdir "$rdmnt" mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1 mount -F ufs -o nologging $lofidev "$rdmnt" - files= + rm -rf "$rdmnt/lost+found" # do the actual copy copy_files "$list" @@ -241,12 +302,14 @@ function create_ufs rmdir "$rdmnt" if [ $ISA = sparc ] ; then - rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"` - bb="$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk" + rlofidev="${lofidev/lofi/rlofi}" + bb="/$ALT_ROOT/platform/$PLATFORM/lib/fs/ufs/bootblk" # installboot is not available on all platforms dd if=$bb of=$rlofidev bs=1b oseek=1 count=15 conv=sync 2>&1 fi + lofiadm -d "$rdfile" + # # Check if gzip exists in /usr/bin, so we only try to run gzip # on systems that have gzip. Then run gzip out of the patch to @@ -256,27 +319,15 @@ function create_ufs # compressed, and the final compression will accomplish very # little. To save time, we skip the gzip in this case. # - if [ $ISA = i386 ] && [ $compress = no ] && \ - [ -x $GZIP_CMD ] ; then - gzip -c "$rdfile" > "${archive}-new" + if [ $ISA = i386 ] && [ $compress = no ] && [ -x $GZIP_CMD ] ; then + $GZIP_CMD -c "$rdfile" > "${archive}-new" else cat "$rdfile" > "${archive}-new" fi - + if [ $? -ne 0 ] ; then rm -f "${archive}-new" fi -} - -function create_archive -{ - which=$1 - archive=$2 - lofidev=$3 - - echo "updating $archive" - - create_ufs "$which" "$archive" "$lofidev" # sanity check the archive before moving it into place # @@ -298,27 +349,59 @@ function create_archive if [ $? = 1 ] && [ -x $GZIP_CMD ] || [ "$ARCHIVE_SIZE" -lt 10000 ] then - # - # Two of these functions may be run in parallel. We - # need to allow the other to clean up, so we can't - # exit immediately. Instead, we set a flag. - # - echo "update of $archive failed" - ERROR=1 + fatal_error "update of $archive failed" else lockfs -f "/$ALT_ROOT" 2>/dev/null - mv "${archive}-new" "$archive" rm -f "$archive.hash" - digest -a sha1 "$archive" > "$archive.hash" + mv "${archive}-new" "$archive" + digest -a sha1 "$rdfile" > "$archive.hash" lockfs -f "/$ALT_ROOT" 2>/dev/null fi + [ -n "$rddir" ] && rm -rf "$rddir" +} +function cpio_cleanup +{ + [ -f "/$ALT_ROOT/$tarchive" ] && rm -f "/$ALT_ROOT/$tarchive" + [ -f "/$ALT_ROOT/$tarchive.cpio" ] && rm -f "/$ALT_ROOT/$tarchive.cpio" + [ -f "/$ALT_ROOT/$tarchive.hash" ] && rm -f "/$ALT_ROOT/$tarchive.hash" } -function fatal_error +function create_cpio_archive { - print -u2 $* - exit 1 + typeset archive="$ALT_ROOT/$BOOT_ARCHIVE" + + echo "updating $archive (CPIO)" + + tarchive="$archive.$$.new" + + # Clean up upon exit. + trap 'cpio_cleanup' EXIT + + cd "/$ALT_ROOT" || fatal_error "Cannot chdir to $ALT_ROOT" + + touch "$tarchive" \ + || fatal_error "Cannot create temporary archive $tarchive" + + find $filelist 2>/dev/null | cpio -qo -H odc > "$tarchive.cpio" \ + || fatal_error "Problem creating archive" + + [ -x /usr/bin/digest ] \ + && /usr/bin/digest -a sha1 "$tarchive.cpio" \ + > "$tarchive.hash" + + if [ -x "$GZIP_CMD" ]; then + $GZIP_CMD -c "$tarchive.cpio" > "$tarchive" + rm -f "$tarchive.cpio" + else + mv "$tarchive.cpio" "$tarchive" + fi + + # Move new archive into place + [ -f "$archive.hash" ] && rm -f "$archive.hash" + mv "$tarchive" "$archive" + [ $? -eq 0 -a -f "$tarchive.hash" ] \ + && mv "$tarchive.hash" "$archive.hash" } # @@ -335,119 +418,15 @@ filelist=$($EXTRACT_FILELIST $EXTRACT_ARGS \ /etc/boot/solaris/filelist.ramdisk \ 2>/dev/null | sort -u) -# -# We use /tmp/ for scratch space now. This may be changed later if there -# is insufficient space in /tmp/. -# -rddir="/tmp/create_ramdisk.$$.tmp" -new_rddir= -rm -rf "$rddir" -mkdir "$rddir" || fatal_error "Could not create temporary directory $rddir" - -# Clean up upon exit. -trap 'cleanup' EXIT - -list32="$rddir/filelist.32" -list64="$rddir/filelist.64" - -touch $list32 $list64 - -# -# This loop creates the 32-bit and 64-bit lists of files. The 32-bit list -# is written to stdout, which is redirected at the end of the loop. The -# 64-bit list is appended with each write. -# -cd "/$ALT_ROOT" -find $filelist -print 2>/dev/null | while read path -do - if [ $SPLIT = no ]; then - print "$path" - elif [ -d "$path" ]; then - size=`ls -lLd "$path" | nawk ' - {print ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}'` - if [ `basename "$path"` != "amd64" ]; then - (( dirsize32 += size )) - fi - (( dirsize64 += size )) - else - case `LC_MESSAGES=C /usr/bin/file -m /dev/null "$path" 2>/dev/null` in - *ELF\ 64-bit*) - print "$path" >> "$list64" - ;; - *ELF\ 32-bit*) - print "$path" - ;; - *) - # put in both lists - print "$path" - print "$path" >> "$list64" - esac - fi -done >"$list32" - -# calculate image size -getsize - -# check to see if there is sufficient space in tmpfs -# -tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'` -(( tmp_free = tmp_free / 3 )) -if [ $SPLIT = yes ]; then - (( tmp_free = tmp_free / 2 )) -fi - -if [ $total_size -gt $tmp_free ] ; then - # assumes we have enough scratch space on $ALT_ROOT - new_rddir="/$ALT_ROOT/var/tmp/create_ramdisk.$$.tmp" - rm -rf "$new_rddir" - mkdir "$new_rddir" || fatal_error \ - "Could not create temporary directory $new_rddir" - - # Save the file lists - mv "$list32" "$new_rddir"/ - mv "$list64" "$new_rddir"/ - list32="/$new_rddir/filelist.32" - list64="/$new_rddir/filelist.64" - - # Remove the old $rddir and set the new value of rddir - rm -rf "$rddir" - rddir="$new_rddir" - new_rddir= -fi +# Now that we have the list of files, we can create the archive. -rdfile32="$rddir/rd.file.32" -rdfile64="$rddir/rd.file.64" -rdmnt32="$rddir/rd.mount.32" -rdmnt64="$rddir/rd.mount.64" -errlog32="$rddir/rd.errlog.32" -errlog64="$rddir/rd.errlog.64" -lofidev32="" -lofidev64="" - -if [ $SPLIT = yes ]; then - # - # We can't run lofiadm commands in parallel, so we have to do - # them here. - # - mkfile ${size32}k "$rdfile32" - lofidev32=`lofiadm -a "$rdfile32"` - mkfile ${size64}k "$rdfile64" - lofidev64=`lofiadm -a "$rdfile64"` - create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 & - create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64 - wait - lofiadm -d "$rdfile32" - lofiadm -d "$rdfile64" -else - mkfile ${total_size}k "$rdfile32" - lofidev32=`lofiadm -a "$rdfile32"` - create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 - lofiadm -d "$rdfile32" -fi -if [ $ERROR = 1 ]; then - cleanup - exit 1 -fi +case "$FORMAT" in + cpio) create_cpio_archive ;; + ufs) create_ufs_archive ;; + *) print -u2 "Unknown boot archive format, $FORMAT" + exit 1 + ;; +esac # # For the diskless case, hardlink archive to /boot to make it @@ -456,11 +435,7 @@ fi # grep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev/null if [ $? = 0 ]; then - rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive" - ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive" - if [ $SPLIT = yes ]; then - ln "$ALT_ROOT/$BOOT_ARCHIVE_64" \ - "$ALT_ROOT/boot/amd64/boot_archive" - fi + rm -f "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX" + mkdir -p "$ALT_ROOT/boot/`dirname $BOOT_ARCHIVE_SUFFIX`" + ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/$BOOT_ARCHIVE_SUFFIX" fi -[ -n "$rddir" ] && rm -rf "$rddir" diff --git a/usr/src/cmd/halt/halt.c b/usr/src/cmd/halt/halt.c index 166e5a163b..a98360d6c2 100644 --- a/usr/src/cmd/halt/halt.c +++ b/usr/src/cmd/halt/halt.c @@ -19,13 +19,14 @@ * CDDL HEADER END */ /* - * Copyright 2016 Toomas Soome <tsoome@me.com> * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2015 by Delphix. All rights reserved. + * Copyright 2016 Toomas Soome <tsoome@me.com> + * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -1582,18 +1583,10 @@ main(int argc, char *argv[]) * handle a SIGTERM and clean up properly. */ if (cmd != A_DUMP) { - int start, end, delta; - - (void) kill(-1, SIGTERM); - start = time(NULL); - if (zoneid == GLOBAL_ZONEID && !nosync) do_archives_update(fast_reboot); - - end = time(NULL); - delta = end - start; - if (delta < 5) - (void) sleep(5 - delta); + (void) kill(-1, SIGTERM); + (void) sleep(5); } (void) signal(SIGINT, SIG_IGN); diff --git a/usr/src/cmd/svc/milestone/boot-archive.xml b/usr/src/cmd/svc/milestone/boot-archive.xml index ca8f947321..a342834cab 100644 --- a/usr/src/cmd/svc/milestone/boot-archive.xml +++ b/usr/src/cmd/svc/milestone/boot-archive.xml @@ -24,12 +24,12 @@ CDDL HEADER END - ident "%Z%%M% %I% %E% SMI" - NOTE: This service manifest is not editable; its contents will be overwritten by package or patch operations, including operating system upgrade. Make customizations in a different file. + + Copyright 2018 OmniOS Community Edition (OmniOSce) Association. --> <service_bundle type='manifest' name='SUNWcsr:boot-archive'> @@ -71,6 +71,10 @@ <propval name='duration' type='astring' value='transient' /> </property_group> + <property_group name='config' type='application'> + <propval name='format' type='astring' value='cpio' /> + </property_group> + <stability value='Unstable' /> <template> |
