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 for (i = 0; i < files; i++) {
3884 char filepath[PATH_MAX];
3885 char *fname;
3886
3887 fname = filelist[i]->d_name;
3888
3889 /* skip anything that starts with a dot */
3890 if (strncmp(fname, ".", 1) == 0) {
3891 free(filelist[i]);
3892 continue;
3893 }
3894
3895 if (bam_verbose)
3896 bam_print(_("/etc/system.d adding %s/%s\n"),
3897 path, fname);
3898
3899 (void) snprintf(filepath, sizeof (filepath), "%s/%s",
3900 path, fname);
3901
3902 if ((assemble_systemfile(filepath, tmpfile)) < 0) {
3903 bam_error(_("failed to append file: %s: %s\n"),
3904 filepath, strerror(errno));
3905 ret = BAM_ERROR;
3906 break;
3907 }
3908 sysfiles++;
3909 }
3910
3911 if (sysfiles > 0) {
3912 if (rename(tmpfile, self_assembly) < 0) {
3913 bam_error(_("failed to rename file: %s: %s\n"), tmpfile,
3914 strerror(errno));
3915 return (BAM_ERROR);
3916 }
3917
3918 /*
3919 * Use previous attribute times to avoid
3920 * boot archive recreation.
3921 */
3922 if (times[1].tv_nsec != 0 &&
3923 utimensat(AT_FDCWD, self_assembly, times, 0) != 0) {
3924 bam_error(_("failed to change times: %s\n"),
3925 strerror(errno));
3926 return (BAM_ERROR);
3927 }
3928 } else {
3929 (void) unlink(tmpfile);
3930 (void) unlink(self_assembly);
3931 }
3932 return (ret);
3933 }
3934
3935 static error_t
3936 create_ramdisk(char *root)
3937 {
3938 char *cmdline, path[PATH_MAX];
3939 size_t len;
3940 struct stat sb;
3941 int ret, status = BAM_SUCCESS;
3942
3943 /* If mkisofs should be used, use it to create the required archives */
3944 if (use_mkisofs()) {
3945 if (has_cachedir() && is_dir_flag_on(NEED_UPDATE)) {
3946 ret = mkisofs_archive(root);
3947 if (ret != 0)
3948 status = BAM_ERROR;
3949 }
3950 return (status);
3951 } else if (bam_format == BAM_FORMAT_HSFS) {
3952 bam_error(_("cannot create hsfs archive\n"));
3953 return (BAM_ERROR);
3954 }
3955
4279 if (bam_smf_check && !bam_root_readonly && !is_zfs(root))
4280 return (BAM_SUCCESS);
4281
4282 /*
4283 * Don't generate archive on ramdisk.
4284 */
4285 if (is_ramdisk(root))
4286 return (BAM_SUCCESS);
4287
4288 /*
4289 * root must be writable. This check applies to alternate
4290 * root (-R option); bam_root_readonly applies to '/' only.
4291 * The behaviour translates into being the one of a 'check'.
4292 */
4293 if (!bam_smf_check && !bam_check && is_readonly(root)) {
4294 set_flag(RDONLY_FSCHK);
4295 bam_check = 1;
4296 }
4297
4298 /*
4299 * Process the /etc/system.d/self-assembly file.
4300 */
4301 if (build_etc_system_dir(bam_root) == BAM_ERROR)
4302 return (BAM_ERROR);
4303
4304 /*
4305 * Now check if an update is really needed.
4306 */
4307 ret = update_required(root);
4308
4309 /*
4310 * The check command (-n) is *not* a dry run.
4311 * It only checks if the archive is in sync.
4312 * A readonly filesystem has to be considered an error only if an update
4313 * is required.
4314 */
4315 if (bam_nowrite()) {
4316 if (is_flag_on(RDONLY_FSCHK)) {
4317 bam_check = bam_saved_check;
4318 if (ret > 0)
4319 bam_error(_("%s filesystem is read-only, "
4320 "skipping archives update\n"), root);
4321 if (bam_update_all)
4322 return ((ret != 0) ? BAM_ERROR : BAM_SUCCESS);
4323 }
4324
|