7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 * Copyright (c) 2015 by Delphix. All rights reserved.
26 * Copyright 2016 Toomas Soome <tsoome@me.com>
27 * Copyright 2016 Nexenta Systems, Inc.
28 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
29 */
30
31 /*
32 * bootadm(1M) is a new utility for managing bootability of
33 * Solaris *Newboot* environments. It has two primary tasks:
34 * - Allow end users to manage bootability of Newboot Solaris instances
35 * - Provide services to other subsystems in Solaris (primarily Install)
36 */
37
38 /* Headers */
39 #include <stdio.h>
40 #include <errno.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <alloca.h>
47 #include <stdarg.h>
143 #define CREATE_RAMDISK "boot/solaris/bin/create_ramdisk"
144 #define CREATE_DISKMAP "boot/solaris/bin/create_diskmap"
145 #define EXTRACT_BOOT_FILELIST "boot/solaris/bin/extract_boot_filelist"
146 #define GRUBDISK_MAP "/var/run/solaris_grubdisk.map"
147
148 #define GRUB_slice "/etc/lu/GRUB_slice"
149 #define GRUB_root "/etc/lu/GRUB_root"
150 #define GRUB_fdisk "/etc/lu/GRUB_fdisk"
151 #define GRUB_fdisk_target "/etc/lu/GRUB_fdisk_target"
152 #define FINDROOT_INSTALLGRUB "/etc/lu/installgrub.findroot"
153 #define LULIB "/usr/lib/lu/lulib"
154 #define LULIB_PROPAGATE_FILE "lulib_propagate_file"
155 #define CKSUM "/usr/bin/cksum"
156 #define LU_MENU_CKSUM "/etc/lu/menu.cksum"
157 #define BOOTADM "/sbin/bootadm"
158
159 #define INSTALLGRUB "/sbin/installgrub"
160 #define STAGE1 "/boot/grub/stage1"
161 #define STAGE2 "/boot/grub/stage2"
162
163 /*
164 * Default file attributes
165 */
166 #define DEFAULT_DEV_MODE 0644 /* default permissions */
167 #define DEFAULT_DEV_UID 0 /* user root */
168 #define DEFAULT_DEV_GID 3 /* group sys */
169
170 /*
171 * Menu related
172 * menu_cmd_t and menu_cmds must be kept in sync
173 */
174 char *menu_cmds[] = {
175 "default", /* DEFAULT_CMD */
176 "timeout", /* TIMEOUT_CMD */
177 "title", /* TITLE_CMD */
178 "root", /* ROOT_CMD */
179 "kernel", /* KERNEL_CMD */
180 "kernel$", /* KERNEL_DOLLAR_CMD */
181 "module", /* MODULE_CMD */
182 "module$", /* MODULE_DOLLAR_CMD */
228 static char *prog;
229 static subcmd_t bam_cmd;
230 char *bam_root;
231 int bam_rootlen;
232 static int bam_root_readonly;
233 int bam_alt_root;
234 static int bam_extend = 0;
235 static int bam_purge = 0;
236 static char *bam_subcmd;
237 static char *bam_opt;
238 static char **bam_argv;
239 static char *bam_pool;
240 static int bam_argc;
241 static int bam_check;
242 static int bam_saved_check;
243 static int bam_smf_check;
244 static int bam_lock_fd = -1;
245 static int bam_zfs;
246 static int bam_mbr;
247 char rootbuf[PATH_MAX] = "/";
248 static int bam_update_all;
249 static int bam_alt_platform;
250 static char *bam_platform;
251 static char *bam_home_env = NULL;
252
253 /* function prototypes */
254 static void parse_args_internal(int, char *[]);
255 static void parse_args(int, char *argv[]);
256 static error_t bam_menu(char *, char *, int, char *[]);
257 static error_t bam_install(char *, char *);
258 static error_t bam_archive(char *, char *);
259
260 static void bam_lock(void);
261 static void bam_unlock(void);
262
263 static int exec_cmd(char *, filelist_t *);
264 static error_t read_globals(menu_t *, char *, char *, int);
265 static int menu_on_bootdisk(char *os_root, char *menu_root);
266 static menu_t *menu_read(char *);
267 static error_t menu_write(char *, menu_t *);
268 static void linelist_free(line_t *);
269 static void menu_free(menu_t *);
270 static void filelist_free(filelist_t *);
271 static error_t list2file(char *, char *, char *, line_t *);
272 static error_t list_entry(menu_t *, char *, char *);
273 static error_t list_setting(menu_t *, char *, char *);
274 static error_t delete_all_entries(menu_t *, char *, char *);
275 static error_t update_entry(menu_t *mp, char *menu_root, char *opt);
276 static error_t update_temp(menu_t *mp, char *dummy, char *opt);
277
278 static error_t install_bootloader(void);
279 static error_t update_archive(char *, char *);
280 static error_t list_archive(char *, char *);
281 static error_t update_all(char *, char *);
282 static error_t read_list(char *, filelist_t *);
283 static error_t set_option(menu_t *, char *, char *);
284 static error_t set_kernel(menu_t *, menu_cmd_t, char *, char *, size_t);
285 static error_t get_kernel(menu_t *, menu_cmd_t, char *, size_t);
286 static char *expand_path(const char *);
287
288 static long s_strtol(char *);
289 static int s_fputs(char *, FILE *);
290
291 static int is_amd64(void);
292 static char *get_machine(void);
293 static void append_to_flist(filelist_t *, char *);
294 static int ufs_add_to_sign_list(char *sign);
295 static error_t synchronize_BE_menu(void);
296
297 #if !defined(_OBP)
298 static void ucode_install();
299 #endif
300
301 /* Menu related sub commands */
302 static subcmd_defn_t menu_subcmds[] = {
303 "set_option", OPT_ABSENT, set_option, 0, /* PUB */
304 "list_entry", OPT_OPTIONAL, list_entry, 1, /* PUB */
305 "delete_all_entries", OPT_ABSENT, delete_all_entries, 0, /* PVT */
2442 NEED_UPDATE_SAFE_FILE,
2443 0644);
2444 return (0);
2445 }
2446 }
2447 safefilep = safefilep->next;
2448 }
2449 }
2450
2451 if (is_flag_on(IS_SPARC_TARGET)) {
2452 set_dir_flag(NEED_UPDATE);
2453 } else {
2454 ret = update_dircache(file, flags);
2455 if (ret == BAM_ERROR) {
2456 bam_error(_("directory cache update failed "
2457 "for %s\n"), file);
2458 return (-1);
2459 }
2460 }
2461
2462 if (bam_verbose) {
2463 if (bam_smf_check)
2464 bam_print(" %s\n", file);
2465 else
2466 bam_print(_(" changed %s\n"), file);
2467 }
2468 }
2469
2470 return (0);
2471 }
2472
2473 /*
2474 * Remove a directory path recursively
2475 */
2476 static int
2477 rmdir_r(char *path)
2478 {
2479 struct dirent *d = NULL;
2480 DIR *dir = NULL;
2481 char tpath[PATH_MAX];
3774
3775
3776 ret = create_x86_archive(boot_archive, temp,
3777 get_cachedir());
3778 }
3779
3780 if (digest_archive(boot_archive) == BAM_ERROR && bam_verbose)
3781 bam_print("boot archive hashing failed\n");
3782
3783 if (ret == BAM_SUCCESS && bam_verbose)
3784 bam_print("Successfully created %s\n", boot_archive);
3785
3786 return (ret);
3787
3788 out_path_err:
3789 bam_error(_("unable to create path on mountpoint %s, path too long\n"),
3790 root);
3791 return (BAM_ERROR);
3792 }
3793
3794 static error_t
3795 create_ramdisk(char *root)
3796 {
3797 char *cmdline, path[PATH_MAX];
3798 size_t len;
3799 struct stat sb;
3800 int ret, status = BAM_SUCCESS;
3801
3802 /* If mkisofs should be used, use it to create the required archives */
3803 if (use_mkisofs()) {
3804 if (has_cachedir() && is_dir_flag_on(NEED_UPDATE)) {
3805 ret = mkisofs_archive(root);
3806 if (ret != 0)
3807 status = BAM_ERROR;
3808 }
3809 return (status);
3810 } else if (bam_format == BAM_FORMAT_HSFS) {
3811 bam_error(_("cannot create hsfs archive\n"));
3812 return (BAM_ERROR);
3813 }
3814
4138 if (bam_smf_check && !bam_root_readonly && !is_zfs(root))
4139 return (BAM_SUCCESS);
4140
4141 /*
4142 * Don't generate archive on ramdisk.
4143 */
4144 if (is_ramdisk(root))
4145 return (BAM_SUCCESS);
4146
4147 /*
4148 * root must be writable. This check applies to alternate
4149 * root (-R option); bam_root_readonly applies to '/' only.
4150 * The behaviour translates into being the one of a 'check'.
4151 */
4152 if (!bam_smf_check && !bam_check && is_readonly(root)) {
4153 set_flag(RDONLY_FSCHK);
4154 bam_check = 1;
4155 }
4156
4157 /*
4158 * Now check if an update is really needed.
4159 */
4160 ret = update_required(root);
4161
4162 /*
4163 * The check command (-n) is *not* a dry run.
4164 * It only checks if the archive is in sync.
4165 * A readonly filesystem has to be considered an error only if an update
4166 * is required.
4167 */
4168 if (bam_nowrite()) {
4169 if (is_flag_on(RDONLY_FSCHK)) {
4170 bam_check = bam_saved_check;
4171 if (ret > 0)
4172 bam_error(_("%s filesystem is read-only, "
4173 "skipping archives update\n"), root);
4174 if (bam_update_all)
4175 return ((ret != 0) ? BAM_ERROR : BAM_SUCCESS);
4176 }
4177
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 * Copyright (c) 2015 by Delphix. All rights reserved.
26 * Copyright 2016 Toomas Soome <tsoome@me.com>
27 * Copyright 2017 Nexenta Systems, Inc.
28 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
29 */
30
31 /*
32 * bootadm(1M) is a new utility for managing bootability of
33 * Solaris *Newboot* environments. It has two primary tasks:
34 * - Allow end users to manage bootability of Newboot Solaris instances
35 * - Provide services to other subsystems in Solaris (primarily Install)
36 */
37
38 /* Headers */
39 #include <stdio.h>
40 #include <errno.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <alloca.h>
47 #include <stdarg.h>
143 #define CREATE_RAMDISK "boot/solaris/bin/create_ramdisk"
144 #define CREATE_DISKMAP "boot/solaris/bin/create_diskmap"
145 #define EXTRACT_BOOT_FILELIST "boot/solaris/bin/extract_boot_filelist"
146 #define GRUBDISK_MAP "/var/run/solaris_grubdisk.map"
147
148 #define GRUB_slice "/etc/lu/GRUB_slice"
149 #define GRUB_root "/etc/lu/GRUB_root"
150 #define GRUB_fdisk "/etc/lu/GRUB_fdisk"
151 #define GRUB_fdisk_target "/etc/lu/GRUB_fdisk_target"
152 #define FINDROOT_INSTALLGRUB "/etc/lu/installgrub.findroot"
153 #define LULIB "/usr/lib/lu/lulib"
154 #define LULIB_PROPAGATE_FILE "lulib_propagate_file"
155 #define CKSUM "/usr/bin/cksum"
156 #define LU_MENU_CKSUM "/etc/lu/menu.cksum"
157 #define BOOTADM "/sbin/bootadm"
158
159 #define INSTALLGRUB "/sbin/installgrub"
160 #define STAGE1 "/boot/grub/stage1"
161 #define STAGE2 "/boot/grub/stage2"
162
163 #define ETC_SYSTEM_DIR "etc/system.d"
164 #define SELF_ASSEMBLY "etc/system.d/.self-assembly"
165
166 /*
167 * Default file attributes
168 */
169 #define DEFAULT_DEV_MODE 0644 /* default permissions */
170 #define DEFAULT_DEV_UID 0 /* user root */
171 #define DEFAULT_DEV_GID 3 /* group sys */
172
173 /*
174 * Menu related
175 * menu_cmd_t and menu_cmds must be kept in sync
176 */
177 char *menu_cmds[] = {
178 "default", /* DEFAULT_CMD */
179 "timeout", /* TIMEOUT_CMD */
180 "title", /* TITLE_CMD */
181 "root", /* ROOT_CMD */
182 "kernel", /* KERNEL_CMD */
183 "kernel$", /* KERNEL_DOLLAR_CMD */
184 "module", /* MODULE_CMD */
185 "module$", /* MODULE_DOLLAR_CMD */
231 static char *prog;
232 static subcmd_t bam_cmd;
233 char *bam_root;
234 int bam_rootlen;
235 static int bam_root_readonly;
236 int bam_alt_root;
237 static int bam_extend = 0;
238 static int bam_purge = 0;
239 static char *bam_subcmd;
240 static char *bam_opt;
241 static char **bam_argv;
242 static char *bam_pool;
243 static int bam_argc;
244 static int bam_check;
245 static int bam_saved_check;
246 static int bam_smf_check;
247 static int bam_lock_fd = -1;
248 static int bam_zfs;
249 static int bam_mbr;
250 char rootbuf[PATH_MAX] = "/";
251 static char self_assembly[PATH_MAX];
252 static int bam_update_all;
253 static int bam_alt_platform;
254 static char *bam_platform;
255 static char *bam_home_env = NULL;
256
257 /* function prototypes */
258 static void parse_args_internal(int, char *[]);
259 static void parse_args(int, char *argv[]);
260 static error_t bam_menu(char *, char *, int, char *[]);
261 static error_t bam_install(char *, char *);
262 static error_t bam_archive(char *, char *);
263
264 static void bam_lock(void);
265 static void bam_unlock(void);
266
267 static int exec_cmd(char *, filelist_t *);
268 static error_t read_globals(menu_t *, char *, char *, int);
269 static int menu_on_bootdisk(char *os_root, char *menu_root);
270 static menu_t *menu_read(char *);
271 static error_t menu_write(char *, menu_t *);
272 static void linelist_free(line_t *);
273 static void menu_free(menu_t *);
274 static void filelist_free(filelist_t *);
275 static error_t list2file(char *, char *, char *, line_t *);
276 static error_t list_entry(menu_t *, char *, char *);
277 static error_t list_setting(menu_t *, char *, char *);
278 static error_t delete_all_entries(menu_t *, char *, char *);
279 static error_t update_entry(menu_t *mp, char *menu_root, char *opt);
280 static error_t update_temp(menu_t *mp, char *dummy, char *opt);
281
282 static error_t install_bootloader(void);
283 static error_t update_archive(char *, char *);
284 static error_t list_archive(char *, char *);
285 static error_t update_all(char *, char *);
286 static error_t read_list(char *, filelist_t *);
287 static error_t set_option(menu_t *, char *, char *);
288 static error_t set_kernel(menu_t *, menu_cmd_t, char *, char *, size_t);
289 static error_t get_kernel(menu_t *, menu_cmd_t, char *, size_t);
290 static error_t build_etc_system_dir(char *);
291 static char *expand_path(const char *);
292
293 static long s_strtol(char *);
294 static int s_fputs(char *, FILE *);
295
296 static int is_amd64(void);
297 static char *get_machine(void);
298 static void append_to_flist(filelist_t *, char *);
299 static int ufs_add_to_sign_list(char *sign);
300 static error_t synchronize_BE_menu(void);
301
302 #if !defined(_OBP)
303 static void ucode_install();
304 #endif
305
306 /* Menu related sub commands */
307 static subcmd_defn_t menu_subcmds[] = {
308 "set_option", OPT_ABSENT, set_option, 0, /* PUB */
309 "list_entry", OPT_OPTIONAL, list_entry, 1, /* PUB */
310 "delete_all_entries", OPT_ABSENT, delete_all_entries, 0, /* PVT */
2447 NEED_UPDATE_SAFE_FILE,
2448 0644);
2449 return (0);
2450 }
2451 }
2452 safefilep = safefilep->next;
2453 }
2454 }
2455
2456 if (is_flag_on(IS_SPARC_TARGET)) {
2457 set_dir_flag(NEED_UPDATE);
2458 } else {
2459 ret = update_dircache(file, flags);
2460 if (ret == BAM_ERROR) {
2461 bam_error(_("directory cache update failed "
2462 "for %s\n"), file);
2463 return (-1);
2464 }
2465 }
2466
2467 /*
2468 * Update self-assembly file if there are changes in
2469 * /etc/system.d directory
2470 */
2471 if (strstr(file, ETC_SYSTEM_DIR)) {
2472 ret = update_dircache(self_assembly, flags);
2473 if (ret == BAM_ERROR) {
2474 bam_error(_("directory cache update failed "
2475 "for %s\n"), file);
2476 return (-1);
2477 }
2478 }
2479
2480 if (bam_verbose) {
2481 if (bam_smf_check)
2482 bam_print(" %s\n", file);
2483 else
2484 bam_print(_(" changed %s\n"), file);
2485 }
2486 }
2487
2488 return (0);
2489 }
2490
2491 /*
2492 * Remove a directory path recursively
2493 */
2494 static int
2495 rmdir_r(char *path)
2496 {
2497 struct dirent *d = NULL;
2498 DIR *dir = NULL;
2499 char tpath[PATH_MAX];
3792
3793
3794 ret = create_x86_archive(boot_archive, temp,
3795 get_cachedir());
3796 }
3797
3798 if (digest_archive(boot_archive) == BAM_ERROR && bam_verbose)
3799 bam_print("boot archive hashing failed\n");
3800
3801 if (ret == BAM_SUCCESS && bam_verbose)
3802 bam_print("Successfully created %s\n", boot_archive);
3803
3804 return (ret);
3805
3806 out_path_err:
3807 bam_error(_("unable to create path on mountpoint %s, path too long\n"),
3808 root);
3809 return (BAM_ERROR);
3810 }
3811
3812 static int
3813 assemble_systemfile(char *infilename, char *outfilename)
3814 {
3815 char buf[BUFSIZ];
3816 FILE *infile, *outfile;
3817 size_t n;
3818
3819 if ((infile = fopen(infilename, "r")) == NULL) {
3820 bam_error(_("failed to open file: %s: %s\n"), infilename,
3821 strerror(errno));
3822 return (BAM_ERROR);
3823 }
3824
3825 if ((outfile = fopen(outfilename, "a")) == NULL) {
3826 bam_error(_("failed to open file: %s: %s\n"), outfilename,
3827 strerror(errno));
3828 (void) fclose(infile);
3829 return (BAM_ERROR);
3830 }
3831
3832 while ((n = fread(buf, 1, sizeof (buf), infile)) > 0) {
3833 if (fwrite(buf, 1, n, outfile) != n) {
3834 bam_error(_("failed to write file: %s: %s\n"),
3835 outfilename, strerror(errno));
3836 (void) fclose(infile);
3837 (void) fclose(outfile);
3838 return (BAM_ERROR);
3839 }
3840 }
3841
3842 (void) fclose(infile);
3843 (void) fclose(outfile);
3844
3845 return (BAM_SUCCESS);
3846 }
3847
3848 /*
3849 * Concatenate all files (except those starting with a dot)
3850 * from /etc/system.d directory into a single /etc/system.d/.self-assembly
3851 * file. The kernel reads it before /etc/system file.
3852 */
3853 static error_t
3854 build_etc_system_dir(char *root)
3855 {
3856 struct dirent **filelist;
3857 char path[PATH_MAX], tmpfile[PATH_MAX];
3858 int i, files, sysfiles = 0;
3859 int ret = BAM_SUCCESS;
3860 struct stat st;
3861 timespec_t times[2];
3862
3863 (void) snprintf(path, sizeof (path), "%s/%s", root, ETC_SYSTEM_DIR);
3864 (void) snprintf(self_assembly, sizeof (self_assembly),
3865 "%s%s", root, SELF_ASSEMBLY);
3866 (void) snprintf(tmpfile, sizeof (tmpfile), "%s.%ld",
3867 self_assembly, (long)getpid());
3868
3869 if (stat(self_assembly, &st) >= 0 && (st.st_mode & S_IFMT) == S_IFREG) {
3870 times[0] = times[1] = st.st_mtim;
3871 } else {
3872 times[1].tv_nsec = 0;
3873 }
3874
3875 if ((files = scandir(path, &filelist, NULL, alphasort)) < 0) {
3876 /* Don't fail the update if <ROOT>/etc/system.d doesn't exist */
3877 if (errno == ENOENT)
3878 return (BAM_SUCCESS);
3879 bam_error(_("can't read %s: %s\n"), path, strerror(errno));
3880 return (BAM_ERROR);
3881 }
3882
3883 (void) unlink(tmpfile);
3884
3885 for (i = 0; i < files; i++) {
3886 char filepath[PATH_MAX];
3887 char *fname;
3888
3889 fname = filelist[i]->d_name;
3890
3891 /* skip anything that starts with a dot */
3892 if (strncmp(fname, ".", 1) == 0) {
3893 free(filelist[i]);
3894 continue;
3895 }
3896
3897 if (bam_verbose)
3898 bam_print(_("/etc/system.d adding %s/%s\n"),
3899 path, fname);
3900
3901 (void) snprintf(filepath, sizeof (filepath), "%s/%s",
3902 path, fname);
3903
3904 if ((assemble_systemfile(filepath, tmpfile)) < 0) {
3905 bam_error(_("failed to append file: %s: %s\n"),
3906 filepath, strerror(errno));
3907 ret = BAM_ERROR;
3908 break;
3909 }
3910 sysfiles++;
3911 }
3912
3913 if (sysfiles > 0) {
3914 if (rename(tmpfile, self_assembly) < 0) {
3915 bam_error(_("failed to rename file: %s: %s\n"), tmpfile,
3916 strerror(errno));
3917 return (BAM_ERROR);
3918 }
3919
3920 /*
3921 * Use previous attribute times to avoid
3922 * boot archive recreation.
3923 */
3924 if (times[1].tv_nsec != 0 &&
3925 utimensat(AT_FDCWD, self_assembly, times, 0) != 0) {
3926 bam_error(_("failed to change times: %s\n"),
3927 strerror(errno));
3928 return (BAM_ERROR);
3929 }
3930 } else {
3931 (void) unlink(tmpfile);
3932 (void) unlink(self_assembly);
3933 }
3934 return (ret);
3935 }
3936
3937 static error_t
3938 create_ramdisk(char *root)
3939 {
3940 char *cmdline, path[PATH_MAX];
3941 size_t len;
3942 struct stat sb;
3943 int ret, status = BAM_SUCCESS;
3944
3945 /* If mkisofs should be used, use it to create the required archives */
3946 if (use_mkisofs()) {
3947 if (has_cachedir() && is_dir_flag_on(NEED_UPDATE)) {
3948 ret = mkisofs_archive(root);
3949 if (ret != 0)
3950 status = BAM_ERROR;
3951 }
3952 return (status);
3953 } else if (bam_format == BAM_FORMAT_HSFS) {
3954 bam_error(_("cannot create hsfs archive\n"));
3955 return (BAM_ERROR);
3956 }
3957
4281 if (bam_smf_check && !bam_root_readonly && !is_zfs(root))
4282 return (BAM_SUCCESS);
4283
4284 /*
4285 * Don't generate archive on ramdisk.
4286 */
4287 if (is_ramdisk(root))
4288 return (BAM_SUCCESS);
4289
4290 /*
4291 * root must be writable. This check applies to alternate
4292 * root (-R option); bam_root_readonly applies to '/' only.
4293 * The behaviour translates into being the one of a 'check'.
4294 */
4295 if (!bam_smf_check && !bam_check && is_readonly(root)) {
4296 set_flag(RDONLY_FSCHK);
4297 bam_check = 1;
4298 }
4299
4300 /*
4301 * Process the /etc/system.d/.self-assembly file.
4302 */
4303 if (build_etc_system_dir(bam_root) == BAM_ERROR)
4304 return (BAM_ERROR);
4305
4306 /*
4307 * Now check if an update is really needed.
4308 */
4309 ret = update_required(root);
4310
4311 /*
4312 * The check command (-n) is *not* a dry run.
4313 * It only checks if the archive is in sync.
4314 * A readonly filesystem has to be considered an error only if an update
4315 * is required.
4316 */
4317 if (bam_nowrite()) {
4318 if (is_flag_on(RDONLY_FSCHK)) {
4319 bam_check = bam_saved_check;
4320 if (ret > 0)
4321 bam_error(_("%s filesystem is read-only, "
4322 "skipping archives update\n"), root);
4323 if (bam_update_all)
4324 return ((ret != 0) ? BAM_ERROR : BAM_SUCCESS);
4325 }
4326
|