summaryrefslogtreecommitdiff
path: root/usr/src/cmd/boot/bootadm/bootadm.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/boot/bootadm/bootadm.c')
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.c589
1 files changed, 314 insertions, 275 deletions
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) {