summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2018-08-29 14:58:43 +0000
committerRobert Mustacchi <rm@joyent.com>2018-09-21 15:12:28 +0000
commit75383e32bbd38e24115eefe5dee272d42a5c723e (patch)
treeb86871b136837439650d0b884cc51877cb245312 /usr/src/cmd
parentc057d312c6f715bb3aeadb653466e7046f26c4af (diff)
downloadillumos-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/Makefile3
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.c589
-rw-r--r--usr/src/cmd/boot/scripts/boot-archive-update.ksh9
-rw-r--r--usr/src/cmd/boot/scripts/create_ramdisk.ksh487
-rw-r--r--usr/src/cmd/halt/halt.c15
-rw-r--r--usr/src/cmd/svc/milestone/boot-archive.xml8
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>