17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5fbac2b2bSvikram * Common Development and Distribution License (the "License"). 6fbac2b2bSvikram * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate 226debd3f5SAlexander Eremin /* 235f10ef69SYuri Pankov * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 249adfa60dSMatthew Ahrens * Copyright 2012 Milan Jurik. All rights reserved. 259adfa60dSMatthew Ahrens * Copyright (c) 2015 by Delphix. All rights reserved. 262dc23587SToomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com> 272b987d42SAlexander Eremin * Copyright 2017 Nexenta Systems, Inc. 285850749aSAndy Fiddaman * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. 296debd3f5SAlexander Eremin */ 306debd3f5SAlexander Eremin 317c478bd9Sstevel@tonic-gate /* 327c478bd9Sstevel@tonic-gate * bootadm(1M) is a new utility for managing bootability of 337c478bd9Sstevel@tonic-gate * Solaris *Newboot* environments. It has two primary tasks: 3475383e32SAndy Fiddaman * - Allow end users to manage bootability of Newboot Solaris instances 357c478bd9Sstevel@tonic-gate * - Provide services to other subsystems in Solaris (primarily Install) 367c478bd9Sstevel@tonic-gate */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* Headers */ 397c478bd9Sstevel@tonic-gate #include <stdio.h> 407c478bd9Sstevel@tonic-gate #include <errno.h> 417c478bd9Sstevel@tonic-gate #include <stdlib.h> 427c478bd9Sstevel@tonic-gate #include <string.h> 437c478bd9Sstevel@tonic-gate #include <unistd.h> 447c478bd9Sstevel@tonic-gate #include <sys/types.h> 457c478bd9Sstevel@tonic-gate #include <sys/stat.h> 4644da779fSWilliam Kucharski #include <alloca.h> 477c478bd9Sstevel@tonic-gate #include <stdarg.h> 487c478bd9Sstevel@tonic-gate #include <limits.h> 497c478bd9Sstevel@tonic-gate #include <signal.h> 507c478bd9Sstevel@tonic-gate #include <sys/wait.h> 517c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 52f904d32dSJerry Gilliam #include <sys/mntent.h> 537c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 547c478bd9Sstevel@tonic-gate #include <libnvpair.h> 557c478bd9Sstevel@tonic-gate #include <ftw.h> 567c478bd9Sstevel@tonic-gate #include <fcntl.h> 577c478bd9Sstevel@tonic-gate #include <strings.h> 582449e17fSsherrym #include <utime.h> 597c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 607c478bd9Sstevel@tonic-gate #include <sys/dktp/fdisk.h> 6158091fd8Ssetje #include <sys/param.h> 62eb2bd662Svikram #include <dirent.h> 63eb2bd662Svikram #include <ctype.h> 64eb2bd662Svikram #include <libgen.h> 65e7cbe64fSgw #include <sys/sysmacros.h> 6648847494SEnrico Perla - Sun Microsystems #include <sys/elf.h> 67963390b4Svikram #include <libscf.h> 6848847494SEnrico Perla - Sun Microsystems #include <zlib.h> 6948847494SEnrico Perla - Sun Microsystems #include <sys/lockfs.h> 7048847494SEnrico Perla - Sun Microsystems #include <sys/filio.h> 716debd3f5SAlexander Eremin #include <libbe.h> 72fa0c327aSToomas Soome #include <deflt.h> 73e998e519SSheshadri Vasudevan #ifdef i386 74e998e519SSheshadri Vasudevan #include <libfdisk.h> 75e998e519SSheshadri Vasudevan #endif 76986fd29aSsetje 7779c28b70SToomas Soome #if !defined(_OBP) 782449e17fSsherrym #include <sys/ucode.h> 792449e17fSsherrym #endif 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate #include <pwd.h> 827c478bd9Sstevel@tonic-gate #include <grp.h> 837c478bd9Sstevel@tonic-gate #include <device_info.h> 84eb2bd662Svikram #include <sys/vtoc.h> 85eb2bd662Svikram #include <sys/efi_partition.h> 8689c3ee43SGangadhar Mylapuram #include <regex.h> 877c478bd9Sstevel@tonic-gate #include <locale.h> 88c7c0ceafSToomas Soome #include <sys/mkdev.h> 897c478bd9Sstevel@tonic-gate 90ae115bc7Smrj #include "bootadm.h" 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate #ifndef TEXT_DOMAIN 937c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SUNW_OST_OSCMD" 947c478bd9Sstevel@tonic-gate #endif /* TEXT_DOMAIN */ 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* Type definitions */ 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* Primary subcmds */ 997c478bd9Sstevel@tonic-gate typedef enum { 1007c478bd9Sstevel@tonic-gate BAM_MENU = 3, 101c7c0ceafSToomas Soome BAM_ARCHIVE, 102c7c0ceafSToomas Soome BAM_INSTALL 1037c478bd9Sstevel@tonic-gate } subcmd_t; 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate #define LINE_INIT 0 /* lineNum initial value */ 1067c478bd9Sstevel@tonic-gate #define ENTRY_INIT -1 /* entryNum initial value */ 1077c478bd9Sstevel@tonic-gate #define ALL_ENTRIES -2 /* selects all boot entries */ 1087c478bd9Sstevel@tonic-gate 1091a902ef8SHans Rosenfeld #define PARTNO_NOTFOUND -1 /* Solaris partition not found */ 1101a902ef8SHans Rosenfeld #define PARTNO_EFI -2 /* EFI partition table found */ 1111a902ef8SHans Rosenfeld 1127c478bd9Sstevel@tonic-gate #define GRUB_DIR "/boot/grub" 113963390b4Svikram #define GRUB_STAGE2 GRUB_DIR "/stage2" 1147c478bd9Sstevel@tonic-gate #define GRUB_MENU "/boot/grub/menu.lst" 1157c478bd9Sstevel@tonic-gate #define MENU_TMP "/boot/grub/menu.lst.tmp" 116963390b4Svikram #define GRUB_BACKUP_MENU "/etc/lu/GRUB_backup_menu" 1171a96bf60SToomas Soome #define RAMDISK_SPECIAL "/devices/ramdisk" 11840541d5dSvikram #define STUBBOOT "/stubboot" 119eb2bd662Svikram #define MULTIBOOT "/platform/i86pc/multiboot" 120eb2bd662Svikram #define GRUBSIGN_DIR "/boot/grub/bootsign" 121eb2bd662Svikram #define GRUBSIGN_BACKUP "/etc/bootsign" 122eb2bd662Svikram #define GRUBSIGN_UFS_PREFIX "rootfs" 123eb2bd662Svikram #define GRUBSIGN_ZFS_PREFIX "pool_" 124eb2bd662Svikram #define GRUBSIGN_LU_PREFIX "BE_" 125eb2bd662Svikram #define UFS_SIGNATURE_LIST "/var/run/grub_ufs_signatures" 126eb2bd662Svikram #define ZFS_LEGACY_MNTPT "/tmp/bootadm_mnt_zfs_legacy" 127eb2bd662Svikram 12875383e32SAndy Fiddaman /* SMF */ 12975383e32SAndy Fiddaman #define BOOT_ARCHIVE_FMRI "system/boot-archive:default" 13075383e32SAndy Fiddaman #define SCF_PG_CONFIG "config" 13175383e32SAndy Fiddaman #define SCF_PROPERTY_FORMAT "format" 13275383e32SAndy Fiddaman 133fa0c327aSToomas Soome /* BE defaults */ 134fa0c327aSToomas Soome #define BE_DEFAULTS "/etc/default/be" 135fa0c327aSToomas Soome #define BE_DFLT_BE_HAS_GRUB "BE_HAS_GRUB=" 136fa0c327aSToomas Soome 137eb2bd662Svikram #define BOOTADM_RDONLY_TEST "BOOTADM_RDONLY_TEST" 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate /* lock related */ 1407c478bd9Sstevel@tonic-gate #define BAM_LOCK_FILE "/var/run/bootadm.lock" 1417c478bd9Sstevel@tonic-gate #define LOCK_FILE_PERMS (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) 1427c478bd9Sstevel@tonic-gate 143986fd29aSsetje #define CREATE_RAMDISK "boot/solaris/bin/create_ramdisk" 144986fd29aSsetje #define CREATE_DISKMAP "boot/solaris/bin/create_diskmap" 145986fd29aSsetje #define EXTRACT_BOOT_FILELIST "boot/solaris/bin/extract_boot_filelist" 1467c478bd9Sstevel@tonic-gate #define GRUBDISK_MAP "/var/run/solaris_grubdisk.map" 1477c478bd9Sstevel@tonic-gate 148b610f78eSvikram #define GRUB_slice "/etc/lu/GRUB_slice" 149b610f78eSvikram #define GRUB_root "/etc/lu/GRUB_root" 150fbac2b2bSvikram #define GRUB_fdisk "/etc/lu/GRUB_fdisk" 151fbac2b2bSvikram #define GRUB_fdisk_target "/etc/lu/GRUB_fdisk_target" 152963390b4Svikram #define FINDROOT_INSTALLGRUB "/etc/lu/installgrub.findroot" 153963390b4Svikram #define LULIB "/usr/lib/lu/lulib" 154963390b4Svikram #define LULIB_PROPAGATE_FILE "lulib_propagate_file" 155963390b4Svikram #define CKSUM "/usr/bin/cksum" 156963390b4Svikram #define LU_MENU_CKSUM "/etc/lu/menu.cksum" 157963390b4Svikram #define BOOTADM "/sbin/bootadm" 158b610f78eSvikram 159b610f78eSvikram #define INSTALLGRUB "/sbin/installgrub" 160b610f78eSvikram #define STAGE1 "/boot/grub/stage1" 161b610f78eSvikram #define STAGE2 "/boot/grub/stage2" 162b610f78eSvikram 1632b987d42SAlexander Eremin #define ETC_SYSTEM_DIR "etc/system.d" 1642b987d42SAlexander Eremin #define SELF_ASSEMBLY "etc/system.d/.self-assembly" 1652b987d42SAlexander Eremin 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * Default file attributes 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate #define DEFAULT_DEV_MODE 0644 /* default permissions */ 1707c478bd9Sstevel@tonic-gate #define DEFAULT_DEV_UID 0 /* user root */ 1717c478bd9Sstevel@tonic-gate #define DEFAULT_DEV_GID 3 /* group sys */ 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * Menu related 1757c478bd9Sstevel@tonic-gate * menu_cmd_t and menu_cmds must be kept in sync 1767c478bd9Sstevel@tonic-gate */ 177ae115bc7Smrj char *menu_cmds[] = { 1787c478bd9Sstevel@tonic-gate "default", /* DEFAULT_CMD */ 1797c478bd9Sstevel@tonic-gate "timeout", /* TIMEOUT_CMD */ 1807c478bd9Sstevel@tonic-gate "title", /* TITLE_CMD */ 1817c478bd9Sstevel@tonic-gate "root", /* ROOT_CMD */ 1827c478bd9Sstevel@tonic-gate "kernel", /* KERNEL_CMD */ 183ae115bc7Smrj "kernel$", /* KERNEL_DOLLAR_CMD */ 1847c478bd9Sstevel@tonic-gate "module", /* MODULE_CMD */ 185ae115bc7Smrj "module$", /* MODULE_DOLLAR_CMD */ 1867c478bd9Sstevel@tonic-gate " ", /* SEP_CMD */ 1877c478bd9Sstevel@tonic-gate "#", /* COMMENT_CMD */ 188ae115bc7Smrj "chainloader", /* CHAINLOADER_CMD */ 189ae115bc7Smrj "args", /* ARGS_CMD */ 190eb2bd662Svikram "findroot", /* FINDROOT_CMD */ 19144da779fSWilliam Kucharski "bootfs", /* BOOTFS_CMD */ 1927c478bd9Sstevel@tonic-gate NULL 1937c478bd9Sstevel@tonic-gate }; 1947c478bd9Sstevel@tonic-gate 19575383e32SAndy Fiddaman char *bam_formats[] = { 19675383e32SAndy Fiddaman "hsfs", 19775383e32SAndy Fiddaman "ufs", 19875383e32SAndy Fiddaman "cpio", 19975383e32SAndy Fiddaman "ufs-nocompress", 20075383e32SAndy Fiddaman NULL 20175383e32SAndy Fiddaman }; 20275383e32SAndy Fiddaman #define BAM_FORMAT_UNSET -1 20375383e32SAndy Fiddaman #define BAM_FORMAT_HSFS 0 20475383e32SAndy Fiddaman short bam_format = BAM_FORMAT_UNSET; 20575383e32SAndy Fiddaman 2067c478bd9Sstevel@tonic-gate #define OPT_ENTRY_NUM "entry" 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate /* 209eb2bd662Svikram * exec_cmd related 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate typedef struct { 2127c478bd9Sstevel@tonic-gate line_t *head; 2137c478bd9Sstevel@tonic-gate line_t *tail; 2147c478bd9Sstevel@tonic-gate } filelist_t; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate #define BOOT_FILE_LIST "boot/solaris/filelist.ramdisk" 2177c478bd9Sstevel@tonic-gate #define ETC_FILE_LIST "etc/boot/solaris/filelist.ramdisk" 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate #define FILE_STAT "boot/solaris/filestat.ramdisk" 2207c478bd9Sstevel@tonic-gate #define FILE_STAT_TMP "boot/solaris/filestat.ramdisk.tmp" 2217c478bd9Sstevel@tonic-gate #define DIR_PERMS (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) 2227c478bd9Sstevel@tonic-gate #define FILE_STAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) 2237c478bd9Sstevel@tonic-gate 2244a9df875SEnrico Perla - Sun Microsystems #define FILE_STAT_TIMESTAMP "boot/solaris/timestamp.cache" 2254a9df875SEnrico Perla - Sun Microsystems 2267c478bd9Sstevel@tonic-gate /* Globals */ 227ae115bc7Smrj int bam_verbose; 228ae115bc7Smrj int bam_force; 229eb2bd662Svikram int bam_debug; 23075383e32SAndy Fiddaman int bam_skip_lock; 2317c478bd9Sstevel@tonic-gate static char *prog; 2327c478bd9Sstevel@tonic-gate static subcmd_t bam_cmd; 233c262cbbcSToomas Soome char *bam_root; 234c262cbbcSToomas Soome int bam_rootlen; 2357c478bd9Sstevel@tonic-gate static int bam_root_readonly; 236c262cbbcSToomas Soome int bam_alt_root; 23748847494SEnrico Perla - Sun Microsystems static int bam_extend = 0; 23848847494SEnrico Perla - Sun Microsystems static int bam_purge = 0; 2397c478bd9Sstevel@tonic-gate static char *bam_subcmd; 2407c478bd9Sstevel@tonic-gate static char *bam_opt; 2417c478bd9Sstevel@tonic-gate static char **bam_argv; 242c7c0ceafSToomas Soome static char *bam_pool; 2437c478bd9Sstevel@tonic-gate static int bam_argc; 2447c478bd9Sstevel@tonic-gate static int bam_check; 2455eea6091SEnrico Perla - Sun Microsystems static int bam_saved_check; 2467c478bd9Sstevel@tonic-gate static int bam_smf_check; 2477c478bd9Sstevel@tonic-gate static int bam_lock_fd = -1; 248e7cbe64fSgw static int bam_zfs; 249c7c0ceafSToomas Soome static int bam_mbr; 250c262cbbcSToomas Soome char rootbuf[PATH_MAX] = "/"; 2512b987d42SAlexander Eremin static char self_assembly[PATH_MAX]; 252b610f78eSvikram static int bam_update_all; 253d876c67dSjg static int bam_alt_platform; 254d876c67dSjg static char *bam_platform; 255cedc7e57SEnrico Perla - Sun Microsystems static char *bam_home_env = NULL; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* function prototypes */ 258986fd29aSsetje static void parse_args_internal(int, char *[]); 259986fd29aSsetje static void parse_args(int, char *argv[]); 260986fd29aSsetje static error_t bam_menu(char *, char *, int, char *[]); 261c7c0ceafSToomas Soome static error_t bam_install(char *, char *); 262986fd29aSsetje static error_t bam_archive(char *, char *); 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate static void bam_lock(void); 2657c478bd9Sstevel@tonic-gate static void bam_unlock(void); 2667c478bd9Sstevel@tonic-gate 267986fd29aSsetje static int exec_cmd(char *, filelist_t *); 268986fd29aSsetje static error_t read_globals(menu_t *, char *, char *, int); 269eb2bd662Svikram static int menu_on_bootdisk(char *os_root, char *menu_root); 270986fd29aSsetje static menu_t *menu_read(char *); 271986fd29aSsetje static error_t menu_write(char *, menu_t *); 272986fd29aSsetje static void linelist_free(line_t *); 273986fd29aSsetje static void menu_free(menu_t *); 274986fd29aSsetje static void filelist_free(filelist_t *); 275986fd29aSsetje static error_t list2file(char *, char *, char *, line_t *); 276986fd29aSsetje static error_t list_entry(menu_t *, char *, char *); 27744da779fSWilliam Kucharski static error_t list_setting(menu_t *, char *, char *); 278986fd29aSsetje static error_t delete_all_entries(menu_t *, char *, char *); 279eb2bd662Svikram static error_t update_entry(menu_t *mp, char *menu_root, char *opt); 280eb2bd662Svikram static error_t update_temp(menu_t *mp, char *dummy, char *opt); 281986fd29aSsetje 282c7c0ceafSToomas Soome static error_t install_bootloader(void); 283986fd29aSsetje static error_t update_archive(char *, char *); 284986fd29aSsetje static error_t list_archive(char *, char *); 285986fd29aSsetje static error_t update_all(char *, char *); 286986fd29aSsetje static error_t read_list(char *, filelist_t *); 287986fd29aSsetje static error_t set_option(menu_t *, char *, char *); 288986fd29aSsetje static error_t set_kernel(menu_t *, menu_cmd_t, char *, char *, size_t); 289eb2bd662Svikram static error_t get_kernel(menu_t *, menu_cmd_t, char *, size_t); 2902b987d42SAlexander Eremin static error_t build_etc_system_dir(char *); 291986fd29aSsetje static char *expand_path(const char *); 292986fd29aSsetje 293986fd29aSsetje static long s_strtol(char *); 294986fd29aSsetje static int s_fputs(char *, FILE *); 295986fd29aSsetje 2967c478bd9Sstevel@tonic-gate static int is_amd64(void); 29779755401Ssetje static char *get_machine(void); 2987c478bd9Sstevel@tonic-gate static void append_to_flist(filelist_t *, char *); 299eb2bd662Svikram static int ufs_add_to_sign_list(char *sign); 300963390b4Svikram static error_t synchronize_BE_menu(void); 3017c478bd9Sstevel@tonic-gate 30279c28b70SToomas Soome #if !defined(_OBP) 3032449e17fSsherrym static void ucode_install(); 3042449e17fSsherrym #endif 3052449e17fSsherrym 3067c478bd9Sstevel@tonic-gate /* Menu related sub commands */ 3077c478bd9Sstevel@tonic-gate static subcmd_defn_t menu_subcmds[] = { 308eb2bd662Svikram "set_option", OPT_ABSENT, set_option, 0, /* PUB */ 3091a97e40eSvikram "list_entry", OPT_OPTIONAL, list_entry, 1, /* PUB */ 3101a97e40eSvikram "delete_all_entries", OPT_ABSENT, delete_all_entries, 0, /* PVT */ 3111a97e40eSvikram "update_entry", OPT_REQ, update_entry, 0, /* menu */ 3121a97e40eSvikram "update_temp", OPT_OPTIONAL, update_temp, 0, /* reboot */ 313