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_FINDROOT      0x100   /* entry has a findroot line */
  91 #define BAM_ENTRY_MULTIBOOT     0x200   /* is multiboot (normal or failsafe) */
  92 #define BAM_ENTRY_64BIT         0x400   /* Is a 64-bit entry */
  93 
  94 #define BAM_ENTRY_UPGFSKERNEL   0x800   /* Upgrade failsafe kernel entry */
  95 #define BAM_ENTRY_UPGFSMODULE   0x1000  /* Upgrade failsafe module entry */
  96 
  97 #define BAM_ENTRY_LIBBE         0x2000  /* entry created by libbe */
  98 
  99 typedef struct {
 100         line_t  *start;
 101         line_t  *end;
 102         line_t  *curdefault;    /* line containing default */
 103         line_t  *olddefault;    /* old default line (commented) */
 104         line_t  *old_rc_default;        /* old default line for bootenv.rc */
 105         entry_t *entries;       /* os entries */
 106 } menu_t;
 107 
 108 typedef enum {
 109         BAM_ERROR = -1, /* Must be negative. add_boot_entry() depends on it */
 110         BAM_SUCCESS = 0,
 111         BAM_WRITE = 2,
 112         BAM_MSG         /* Used by upgrade_menu() */
 113 } error_t;
 114 
 115 /*
 116  * Menu related
 117  * menu_cmd_t and menu_cmds must be kept in sync
 118  *
 119  * The *_DOLLAR_CMD values must be 1 greater than the
 120  * respective [KERNEL|MODULE]_CMD values.
 121  */
 122 typedef enum {
 123         DEFAULT_CMD = 0,
 124         TIMEOUT_CMD,
 125         TITLE_CMD,
 126         ROOT_CMD,
 127         KERNEL_CMD,
 128         KERNEL_DOLLAR_CMD,      /* Must be KERNEL_CMD + 1 */
 129         MODULE_CMD,
 130         MODULE_DOLLAR_CMD,      /* Must be MODULE_CMD + 1 */
 131         SEP_CMD,
 132         COMMENT_CMD,
 133         CHAINLOADER_CMD,
 134         ARGS_CMD,
 135         FINDROOT_CMD,
 136         BOOTFS_CMD
 137 } menu_cmd_t;
 138 
 139 extern char *menu_cmds[];
 140 
 141 /* For multi- or direct-boot */
 142 typedef enum {
 143         BAM_DIRECT_NOT_SET,
 144         BAM_DIRECT_MULTIBOOT,
 145         BAM_DIRECT_DBOOT
 146 } direct_or_multi_t;
 147 
 148 /* Is there findroot capability present ? */
 149 typedef enum {
 150         BAM_FINDROOT_UNKNOWN,
 151         BAM_FINDROOT_ABSENT,
 152         BAM_FINDROOT_PRESENT
 153 } findroot_t;
 154 
 155 typedef enum {
 156         OPT_ABSENT = 0,         /* No option */
 157         OPT_REQ,                /* option required */
 158         OPT_OPTIONAL            /* option may or may not be present */
 159 } option_t;
 160 
 161 typedef struct {
 162         char    *subcmd;
 163         option_t option;
 164         error_t (*handler)();
 165         int     unpriv;                 /* is this an unprivileged command */
 166 } subcmd_defn_t;
 167 
 168 typedef enum zfs_mnted {
 169         ZFS_MNT_ERROR = -1,
 170         LEGACY_MOUNTED = 1,
 171         LEGACY_ALREADY,
 172         ZFS_MOUNTED,
 173         ZFS_ALREADY
 174 } zfs_mnted_t;
 175 
 176 extern int bam_verbose;
 177 extern int bam_force;
 178 extern direct_or_multi_t bam_direct;
 179 extern findroot_t bam_is_findroot;
 180 extern int bam_debug;
 181 
 182 extern void bam_add_line(menu_t *mp, entry_t *entry, line_t *prev, line_t *lp);
 183 extern void update_numbering(menu_t *mp);
 184 extern error_t set_global(menu_t *, char *, int);
 185 extern error_t upgrade_menu(menu_t *, char *, char *);
 186 extern error_t check_subcmd_and_options(char *, char *, subcmd_defn_t *,
 187     error_t (**fp)());
 188 extern char *mount_top_dataset(char *pool, zfs_mnted_t *mnted);
 189 extern void elide_trailing_slash(const char *, char *, size_t);
 190 extern int umount_top_dataset(char *, zfs_mnted_t, char *);
 191 extern void *s_calloc(size_t, size_t);
 192 extern void *s_realloc(void *, size_t);
 193 extern char *s_fgets(char *buf, int n, FILE *fp);
 194 extern void bam_error(char *format, ...);
 195 extern void bam_exit(int);
 196 extern void bam_print(char *, ...);
 197 extern void bam_print_stderr(char *format, ...);
 198 extern void bam_derror(char *format, ...);
 199 extern error_t bam_loader_menu(char *, char *, int, char *[]);
 200 extern error_t get_boot_cap(const char *osroot);
 201 extern char *get_special(char *);
 202 extern char *os_to_grubdisk(char *, int);
 203 extern void update_line(line_t *);
 204 extern int add_boot_entry(menu_t *, char *, char *, char *, char *, char *,
 205     char *);
 206 extern error_t delete_boot_entry(menu_t *, int, int);
 207 extern int is_grub(const char *);
 208 extern char *get_grubsign(char *osroot, char *osdev);
 209 extern char *get_grubroot(char *osroot, char *osdev, char *menu_root);
 210 extern int root_optional(char *osroot, char *menu_root);
 211 extern void unlink_line(menu_t *mp, line_t *lp);
 212 extern void line_free(line_t *lp);
 213 extern char *s_strdup(char *);
 214 extern int is_sparc(void);
 215 extern int is_pcfs(char *);
 216 extern int is_zfs(char *);
 217 extern int bootadm_digest(const char *, char **);
 218 
 219 #define BAM_MAXLINE     8192
 220 
 221 /* menu.lst comments created by bootadm */
 222 #define BAM_BOOTADM_HDR "---------- ADDED BY BOOTADM - DO NOT EDIT ----------"
 223 #define BAM_BOOTADM_FTR "---------------------END BOOTADM--------------------"
 224 
 225 /*
 226  * menu.lst comments create by Live Upgrade.  Note that these are the end of
 227  * the comment strings - there will be other text before them.
 228  */
 229 #define BAM_LU_HDR      " - ADDED BY LIVE UPGRADE - DO NOT EDIT  -----"
 230 #define BAM_LU_FTR      " -------------- END LIVE UPGRADE ------------"
 231 
 232 #define BAM_OLDDEF      "BOOTADM SAVED DEFAULT: "
 233 #define BAM_OLD_RC_DEF  "BOOTADM RC SAVED DEFAULT: "
 234 
 235 /*
 236  * menu.lst comment created by libbe
 237  */
 238 #define BAM_LIBBE_FTR   "============ End of LIBBE entry ============="
 239 
 240 /* Title used for failsafe entries */
 241 #define FAILSAFE_TITLE  "Solaris failsafe"
 242 
 243 /* ZFS boot option */
 244 #define ZFS_BOOT        "-B $ZFS-BOOTFS"
 245 
 246 /* multiboot */
 247 #define MULTI_BOOT      "/platform/i86pc/multiboot"
 248 #define MULTI_BOOT_FAILSAFE     "/boot/multiboot"
 249 #define MULTI_BOOT_FAILSAFE_UNIX        "kernel/unix"
 250 #define MULTI_BOOT_FAILSAFE_LINE        "/boot/multiboot kernel/unix -s"
 251 
 252 /* directboot kernels */
 253 #define DIRECT_BOOT_32  "/platform/i86pc/kernel/unix"
 254 #define DIRECT_BOOT_64  "/platform/i86pc/kernel/amd64/unix"
 255 #define DIRECT_BOOT_KERNEL      "/platform/i86pc/kernel/$ISADIR/unix"
 256 #define DIRECT_BOOT_FAILSAFE_32 "/boot/platform/i86pc/kernel/unix"
 257 #define DIRECT_BOOT_FAILSAFE_64 "/boot/platform/i86pc/kernel/amd64/unix"
 258 #define DIRECT_BOOT_FAILSAFE_KERNEL \
 259         "/boot/platform/i86pc/kernel/$ISADIR/unix"
 260 #define DIRECT_BOOT_FAILSAFE_LINE       DIRECT_BOOT_FAILSAFE_KERNEL " -s"
 261 #define DIRECT_BOOT_KERNEL_ZFS  DIRECT_BOOT_KERNEL " " ZFS_BOOT
 262 #define DIRECT_BOOT_PREFIX      "/platform/i86pc/"
 263 #define KERNEL_PREFIX   "/platform/i86pc/"
 264 #define AMD_UNIX_SPACE  "/amd64/unix "
 265 #define UNIX_SPACE      "/unix "
 266 
 267 /* Boot archives */
 268 #define ARCHIVE_PREFIX          "/platform/"
 269 #define ARCHIVE_SUFFIX          "/boot_archive"
 270 #define CACHEDIR_SUFFIX         "/archive_cache"
 271 #define UPDATEDIR_SUFFIX        "/updates"
 272 #define DIRECT_BOOT_ARCHIVE     "/platform/i86pc/$ISADIR/boot_archive"
 273 #define DIRECT_BOOT_ARCHIVE_32  "/platform/i86pc/boot_archive"
 274 #define DIRECT_BOOT_ARCHIVE_64  "/platform/i86pc/amd64/boot_archive"
 275 #define MULTIBOOT_ARCHIVE       DIRECT_BOOT_ARCHIVE_32
 276 #define FAILSAFE_ARCHIVE        "/boot/$ISADIR/x86.miniroot-safe"
 277 #define FAILSAFE_ARCHIVE_32     "/boot/x86.miniroot-safe"
 278 #define FAILSAFE_ARCHIVE_64     "/boot/amd64/x86.miniroot-safe"
 279 #define CACHEDIR_32             "/platform/i86pc/archive_cache"
 280 #define CACHEDIR_64             "/platform/i86pc/amd64/archive_cache"
 281 #define UPDATEDIR_32            "/platform/i86pc/updates"
 282 #define UPDATEDIR_64            "/platform/i86pc/amd64/updates"
 283 
 284 /* Helpers */
 285 #define MKISOFS_PATH            "/usr/bin/mkisofs"
 286 #define DD_PATH_USR             "/usr/bin/dd"
 287 #define LOCKFS_PATH             "/usr/sbin/lockfs"
 288 
 289 /* A first guess at the number of entries in a menu */
 290 #define BAM_ENTRY_NUM           10
 291 
 292 /* toggle for whether delete_boot_entry prints an error message or not */
 293 #define DBE_PRINTERR            0
 294 #define DBE_QUIET               1
 295 
 296 /*
 297  * Debugging defines
 298  */
 299 #define INJECT_ERROR1(x, y)     \
 300 { \
 301         if (bam_debug) { \
 302                 char *inj = getenv("_BOOTADM_INJECT"); \
 303                 if (inj && strcmp(inj, (x)) == 0) {  \
 304                         y;      \
 305                 } \
 306         } \
 307 }
 308 
 309 #define INJECT_ERROR2(x, y, z)  \
 310 { \
 311         if (bam_debug) { \
 312                 char *inj = getenv("_BOOTADM_INJECT"); \
 313                 if (inj && strcmp(inj, (x)) == 0) {  \
 314                         y;      \
 315                         z;      \
 316                 } \
 317         } \
 318 }
 319 
 320 #define BAM_DPRINTF(x)  {if (bam_debug)  bam_derror x; }
 321 
 322 #ifdef __cplusplus
 323 }
 324 #endif
 325 
 326 #endif  /* _BOOTADM_H */