1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2016 Toomas Soome <tsoome@me.com>.
  26  */
  27 
  28 #ifndef _BOOTADM_H
  29 #define _BOOTADM_H
  30 
  31 #ifdef  __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 #include <assert.h>
  36 #include <libintl.h>
  37 
  38 #ifndef TEXT_DOMAIN
  39 #define TEXT_DOMAIN     "SUNW_OST_OSCMD"
  40 #endif  /* TEXT_DOMAIN */
  41 
  42 #ifndef lint
  43 #define _(x) gettext(x)
  44 #else
  45 #define _(x) (x)
  46 #endif
  47 
  48 /* Type definitions */
  49 
  50 /* GRUB menu per-line classification */
  51 typedef enum {
  52         BAM_INVALID = 0,
  53         BAM_EMPTY,
  54         BAM_COMMENT,
  55         BAM_GLOBAL,
  56         BAM_ENTRY,
  57         BAM_TITLE
  58 } menu_flag_t;
  59 
  60 /* struct for menu.lst contents */
  61 typedef struct line {
  62         int  lineNum;   /* Line number in menu.lst */
  63         int  entryNum;  /* menu boot entry #. ENTRY_INIT if not applicable */
  64         char *cmd;
  65         char *sep;
  66         char *arg;
  67         char *line;
  68         menu_flag_t flags;
  69         struct line *next;
  70         struct line *prev;
  71 } line_t;
  72 
  73 typedef struct entry {
  74         struct entry *next;
  75         struct entry *prev;
  76         line_t *start;
  77         line_t *end;
  78         int     entryNum;
  79         uint_t  flags;
  80 } entry_t;
  81 
  82 /* For flags value in entry_t */
  83 #define BAM_ENTRY_BOOTADM       0x01    /* entry created by bootadm */
  84 #define BAM_ENTRY_LU            0x02    /* entry created by Live Upgrade */
  85 #define BAM_ENTRY_CHAINLOADER   0x04    /* chainloader entry; do not disturb */
  86 #define BAM_ENTRY_ROOT          0x08    /* entry has a root line */
  87 #define BAM_ENTRY_FAILSAFE      0x10    /* failsafe entry  */
  88 #define BAM_ENTRY_DBOOT         0x20    /* Is dboot (normal or failsafe) */
  89 #define BAM_ENTRY_32BIT         0x40    /* Is a 32-bit entry */
  90 #define BAM_ENTRY_HV            0x80    /* Is a hypervisor entry */
  91 #define BAM_ENTRY_FINDROOT      0x100   /* entry has a findroot line */
  92 #define BAM_ENTRY_MULTIBOOT     0x200   /* is multiboot (normal or failsafe) */
  93 #define BAM_ENTRY_64BIT         0x400   /* Is a 64-bit entry */
  94 
  95 #define BAM_ENTRY_UPGFSKERNEL   0x800   /* Upgrade failsafe kernel entry */
  96 #define BAM_ENTRY_UPGFSMODULE   0x1000  /* Upgrade failsafe module entry */
  97 
  98 #define BAM_ENTRY_LIBBE         0x2000  /* entry created by libbe */
  99 
 100 typedef struct {
 101         line_t  *start;
 102         line_t  *end;
 103         line_t  *curdefault;    /* line containing default */
 104         line_t  *olddefault;    /* old default line (commented) */
 105         line_t  *old_rc_default;        /* old default line for bootenv.rc */
 106         entry_t *entries;       /* os entries */
 107 } menu_t;
 108 
 109 typedef enum {
 110         BAM_ERROR = -1, /* Must be negative. add_boot_entry() depends on it */
 111         BAM_SUCCESS = 0,
 112         BAM_WRITE = 2,
 113         BAM_MSG,        /* Used by upgrade_menu() */
 114         BAM_NOCHANGE    /* Used by cvt_to_hyper()/cvt_to_metal() */
 115 } error_t;
 116 
 117 /*
 118  * Menu related
 119  * menu_cmd_t and menu_cmds must be kept in sync
 120  *
 121  * The *_DOLLAR_CMD values must be 1 greater than the
 122  * respective [KERNEL|MODULE]_CMD values.
 123  */
 124 typedef enum {
 125         DEFAULT_CMD = 0,
 126         TIMEOUT_CMD,
 127         TITLE_CMD,
 128         ROOT_CMD,
 129         KERNEL_CMD,
 130         KERNEL_DOLLAR_CMD,      /* Must be KERNEL_CMD + 1 */
 131         MODULE_CMD,
 132         MODULE_DOLLAR_CMD,      /* Must be MODULE_CMD + 1 */
 133         SEP_CMD,
 134         COMMENT_CMD,
 135         CHAINLOADER_CMD,
 136         ARGS_CMD,
 137         FINDROOT_CMD,
 138         BOOTFS_CMD
 139 } menu_cmd_t;
 140 
 141 extern char *menu_cmds[];
 142 
 143 /* For multi- or direct-boot */
 144 typedef enum {
 145         BAM_DIRECT_NOT_SET,
 146         BAM_DIRECT_MULTIBOOT,
 147         BAM_DIRECT_DBOOT
 148 } direct_or_multi_t;
 149 
 150 /* Is there a hypervisor present? */
 151 typedef enum {
 152         BAM_HV_UNKNOWN,
 153         BAM_HV_NO,
 154         BAM_HV_PRESENT
 155 } hv_t;
 156 
 157 /* Is there findroot capability present ? */
 158 typedef enum {
 159         BAM_FINDROOT_UNKNOWN,
 160         BAM_FINDROOT_ABSENT,
 161         BAM_FINDROOT_PRESENT
 162 } findroot_t;
 163 
 164 typedef enum {
 165         OPT_ABSENT = 0,         /* No option */
 166         OPT_REQ,                /* option required */
 167         OPT_OPTIONAL            /* option may or may not be present */
 168 } option_t;
 169 
 170 typedef struct {
 171         char    *subcmd;
 172         option_t option;
 173         error_t (*handler)();
 174         int     unpriv;                 /* is this an unprivileged command */
 175 } subcmd_defn_t;
 176 
 177 typedef enum zfs_mnted {
 178         ZFS_MNT_ERROR = -1,
 179         LEGACY_MOUNTED = 1,
 180         LEGACY_ALREADY,
 181         ZFS_MOUNTED,
 182         ZFS_ALREADY
 183 } zfs_mnted_t;
 184 
 185 extern int bam_verbose;
 186 extern int bam_force;
 187 extern direct_or_multi_t bam_direct;
 188 extern hv_t bam_is_hv;
 189 extern findroot_t bam_is_findroot;
 190 extern int bam_debug;
 191 
 192 extern void bam_add_line(menu_t *mp, entry_t *entry, line_t *prev, line_t *lp);
 193 extern void update_numbering(menu_t *mp);
 194 extern error_t set_global(menu_t *, char *, int);
 195 extern error_t upgrade_menu(menu_t *, char *, char *);
 196 extern error_t cvt_to_hyper(menu_t *, char *, char *);
 197 extern error_t cvt_to_metal(menu_t *, char *, char *);
 198 extern error_t check_subcmd_and_options(char *, char *, subcmd_defn_t *,
 199     error_t (**fp)());
 200 extern char *mount_top_dataset(char *pool, zfs_mnted_t *mnted);
 201 extern void elide_trailing_slash(const char *, char *, size_t);
 202 extern int umount_top_dataset(char *, zfs_mnted_t, char *);
 203 extern void *s_calloc(size_t, size_t);
 204 extern void *s_realloc(void *, size_t);
 205 extern char *s_fgets(char *buf, int n, FILE *fp);
 206 extern void bam_error(char *format, ...);
 207 extern void bam_exit(int);
 208 extern void bam_print(char *, ...);
 209 extern void bam_print_stderr(char *format, ...);
 210 extern void bam_derror(char *format, ...);
 211 extern error_t bam_loader_menu(char *, char *, int, char *[]);
 212 extern error_t get_boot_cap(const char *osroot);
 213 extern char *get_special(char *);
 214 extern char *os_to_grubdisk(char *, int);
 215 extern void update_line(line_t *);
 216 extern int add_boot_entry(menu_t *, char *, char *, char *, char *, char *,
 217     char *);
 218 extern error_t delete_boot_entry(menu_t *, int, int);
 219 extern int is_grub(const char *);
 220 extern char *get_grubsign(char *osroot, char *osdev);
 221 extern char *get_grubroot(char *osroot, char *osdev, char *menu_root);
 222 extern int root_optional(char *osroot, char *menu_root);
 223 extern void unlink_line(menu_t *mp, line_t *lp);
 224 extern void line_free(line_t *lp);
 225 extern char *s_strdup(char *);
 226 extern int is_sparc(void);
 227 extern int is_pcfs(char *);
 228 extern int is_zfs(char *);
 229 extern int bootadm_digest(const char *, char **);
 230 
 231 #define BAM_MAXLINE     8192
 232 
 233 /* menu.lst comments created by bootadm */
 234 #define BAM_BOOTADM_HDR "---------- ADDED BY BOOTADM - DO NOT EDIT ----------"
 235 #define BAM_BOOTADM_FTR "---------------------END BOOTADM--------------------"
 236 
 237 /*
 238  * menu.lst comments create by Live Upgrade.  Note that these are the end of
 239  * the comment strings - there will be other text before them.
 240  */
 241 #define BAM_LU_HDR      " - ADDED BY LIVE UPGRADE - DO NOT EDIT  -----"
 242 #define BAM_LU_FTR      " -------------- END LIVE UPGRADE ------------"
 243 
 244 #define BAM_OLDDEF      "BOOTADM SAVED DEFAULT: "
 245 #define BAM_OLD_RC_DEF  "BOOTADM RC SAVED DEFAULT: "
 246 
 247 /*
 248  * menu.lst comment created by libbe
 249  */
 250 #define BAM_LIBBE_FTR   "============ End of LIBBE entry ============="
 251 
 252 /* Title used for failsafe entries */
 253 #define FAILSAFE_TITLE  "Solaris failsafe"
 254 
 255 /* Title used for hv entries */
 256 #define NEW_HV_ENTRY    "Solaris xVM"
 257 
 258 /* ZFS boot option */
 259 #define ZFS_BOOT        "-B $ZFS-BOOTFS"
 260 
 261 /* multiboot */
 262 #define MULTI_BOOT      "/platform/i86pc/multiboot"
 263 #define MULTI_BOOT_FAILSAFE     "/boot/multiboot"
 264 #define MULTI_BOOT_FAILSAFE_UNIX        "kernel/unix"
 265 #define MULTI_BOOT_FAILSAFE_LINE        "/boot/multiboot kernel/unix -s"
 266 
 267 /* directboot kernels */
 268 #define DIRECT_BOOT_32  "/platform/i86pc/kernel/unix"
 269 #define DIRECT_BOOT_64  "/platform/i86pc/kernel/amd64/unix"
 270 #define DIRECT_BOOT_KERNEL      "/platform/i86pc/kernel/$ISADIR/unix"
 271 #define DIRECT_BOOT_FAILSAFE_32 "/boot/platform/i86pc/kernel/unix"
 272 #define DIRECT_BOOT_FAILSAFE_64 "/boot/platform/i86pc/kernel/amd64/unix"
 273 #define DIRECT_BOOT_FAILSAFE_KERNEL \
 274         "/boot/platform/i86pc/kernel/$ISADIR/unix"
 275 #define DIRECT_BOOT_FAILSAFE_LINE       DIRECT_BOOT_FAILSAFE_KERNEL " -s"
 276 #define DIRECT_BOOT_KERNEL_ZFS  DIRECT_BOOT_KERNEL " " ZFS_BOOT
 277 #define DIRECT_BOOT_PREFIX      "/platform/i86pc/"
 278 #define KERNEL_PREFIX   "/platform/i86pc/"
 279 #define AMD_UNIX_SPACE  "/amd64/unix "
 280 #define UNIX_SPACE      "/unix "
 281 
 282 /* xVM kernels */
 283 #define XEN_KERNEL_SUBSTR "xen.gz"
 284 
 285 /* Boot archives */
 286 #define ARCHIVE_PREFIX          "/platform/"
 287 #define ARCHIVE_SUFFIX          "/boot_archive"
 288 #define CACHEDIR_SUFFIX         "/archive_cache"
 289 #define UPDATEDIR_SUFFIX        "/updates"
 290 #define DIRECT_BOOT_ARCHIVE     "/platform/i86pc/$ISADIR/boot_archive"
 291 #define DIRECT_BOOT_ARCHIVE_32  "/platform/i86pc/boot_archive"
 292 #define DIRECT_BOOT_ARCHIVE_64  "/platform/i86pc/amd64/boot_archive"
 293 #define MULTIBOOT_ARCHIVE       DIRECT_BOOT_ARCHIVE_32
 294 #define FAILSAFE_ARCHIVE        "/boot/$ISADIR/x86.miniroot-safe"
 295 #define FAILSAFE_ARCHIVE_32     "/boot/x86.miniroot-safe"
 296 #define FAILSAFE_ARCHIVE_64     "/boot/amd64/x86.miniroot-safe"
 297 #define CACHEDIR_32             "/platform/i86pc/archive_cache"
 298 #define CACHEDIR_64             "/platform/i86pc/amd64/archive_cache"
 299 #define UPDATEDIR_32            "/platform/i86pc/updates"
 300 #define UPDATEDIR_64            "/platform/i86pc/amd64/updates"
 301 
 302 /* Hypervisors */
 303 #define XEN_64                  "/boot/amd64/xen.gz"
 304 #define XEN_MENU                "/boot/$ISADIR/xen.gz"
 305 #define HYPERVISOR_KERNEL       "/platform/i86xpv/kernel/$ISADIR/unix"
 306 #define XEN_KERNEL_MODULE_LINE  HYPERVISOR_KERNEL " " HYPERVISOR_KERNEL
 307 #define XEN_KERNEL_MODULE_LINE_ZFS      \
 308         HYPERVISOR_KERNEL " " HYPERVISOR_KERNEL " " ZFS_BOOT
 309 
 310 /* Helpers */
 311 #define MKISOFS_PATH            "/usr/bin/mkisofs"
 312 #define DD_PATH_USR             "/usr/bin/dd"
 313 #define LOCKFS_PATH             "/usr/sbin/lockfs"
 314 
 315 /* A first guess at the number of entries in a menu */
 316 #define BAM_ENTRY_NUM           10
 317 
 318 /* toggle for whether delete_boot_entry prints an error message or not */
 319 #define DBE_PRINTERR            0
 320 #define DBE_QUIET               1
 321 
 322 /*
 323  * Debugging defines
 324  */
 325 #define INJECT_ERROR1(x, y)     \
 326 { \
 327         if (bam_debug) { \
 328                 char *inj = getenv("_BOOTADM_INJECT"); \
 329                 if (inj && strcmp(inj, (x)) == 0) {  \
 330                         y;      \
 331                 } \
 332         } \
 333 }
 334 
 335 #define INJECT_ERROR2(x, y, z)  \
 336 { \
 337         if (bam_debug) { \
 338                 char *inj = getenv("_BOOTADM_INJECT"); \
 339                 if (inj && strcmp(inj, (x)) == 0) {  \
 340                         y;      \
 341                         z;      \
 342                 } \
 343         } \
 344 }
 345 
 346 #define BAM_DPRINTF(x)  {if (bam_debug)  bam_derror x; }
 347 
 348 #ifdef __cplusplus
 349 }
 350 #endif
 351 
 352 #endif  /* _BOOTADM_H */