Print this page
backup vers
bootadm.c updated
bootadm ba_path->module


 101 
 102 typedef enum {
 103     OPT_ABSENT = 0,     /* No option */
 104     OPT_REQ,            /* option required */
 105     OPT_OPTIONAL        /* option may or may not be present */
 106 } option_t;
 107 
 108 typedef struct {
 109         char    *subcmd;
 110         option_t option;
 111         error_t (*handler)();
 112         int     unpriv;                 /* is this an unprivileged command */
 113 } subcmd_defn_t;
 114 
 115 #define LINE_INIT       0       /* lineNum initial value */
 116 #define ENTRY_INIT      -1      /* entryNum initial value */
 117 #define ALL_ENTRIES     -2      /* selects all boot entries */
 118 
 119 #define GRUB_DIR                "/boot/grub"
 120 #define GRUB_STAGE2             GRUB_DIR "/stage2"
 121 #define GRUB_MENU               "/boot/grub/menu.lst"
 122 #define MENU_TMP                "/boot/grub/menu.lst.tmp"
 123 #define GRUB_BACKUP_MENU        "/etc/lu/GRUB_backup_menu"
 124 #define RAMDISK_SPECIAL         "/ramdisk"
 125 #define STUBBOOT                "/stubboot"
 126 #define MULTIBOOT               "/platform/i86pc/multiboot"
 127 #define GRUBSIGN_DIR            "/boot/grub/bootsign"
 128 #define GRUBSIGN_BACKUP         "/etc/bootsign"
 129 #define GRUBSIGN_UFS_PREFIX     "rootfs"
 130 #define GRUBSIGN_ZFS_PREFIX     "pool_"
 131 #define GRUBSIGN_LU_PREFIX      "BE_"
 132 #define UFS_SIGNATURE_LIST      "/var/run/grub_ufs_signatures"
 133 #define ZFS_LEGACY_MNTPT        "/tmp/bootadm_mnt_zfs_legacy"
 134 
 135 #define BOOTADM_RDONLY_TEST     "BOOTADM_RDONLY_TEST"
 136 
 137 /* lock related */
 138 #define BAM_LOCK_FILE           "/var/run/bootadm.lock"
 139 #define LOCK_FILE_PERMS         (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
 140 
 141 #define CREATE_RAMDISK          "boot/solaris/bin/create_ramdisk"
 142 #define CREATE_DISKMAP          "boot/solaris/bin/create_diskmap"


 161 typedef enum zfs_mnted {
 162         ZFS_MNT_ERROR = -1,
 163         LEGACY_MOUNTED = 1,
 164         LEGACY_ALREADY,
 165         ZFS_MOUNTED,
 166         ZFS_ALREADY
 167 } zfs_mnted_t;
 168 
 169 /*
 170  * Default file attributes
 171  */
 172 #define DEFAULT_DEV_MODE        0644    /* default permissions */
 173 #define DEFAULT_DEV_UID         0       /* user root */
 174 #define DEFAULT_DEV_GID         3       /* group sys */
 175 
 176 /*
 177  * Menu related
 178  * menu_cmd_t and menu_cmds must be kept in sync
 179  */
 180 char *menu_cmds[] = {
 181         "default",      /* DEFAULT_CMD */
 182         "timeout",      /* TIMEOUT_CMD */
 183         "title",        /* TITLE_CMD */
 184         "root",         /* ROOT_CMD */
 185         "kernel",       /* KERNEL_CMD */
 186         "kernel$",      /* KERNEL_DOLLAR_CMD */
 187         "module",       /* MODULE_CMD */
 188         "module$",      /* MODULE_DOLLAR_CMD */
 189         " ",            /* SEP_CMD */
 190         "#",            /* COMMENT_CMD */
 191         "chainloader",  /* CHAINLOADER_CMD */
 192         "args",         /* ARGS_CMD */
 193         "findroot",     /* FINDROOT_CMD */
 194         "bootfs",       /* BOOTFS_CMD */

 195         NULL
 196 };
 197 
 198 #define OPT_ENTRY_NUM   "entry"
 199 
 200 /*
 201  * exec_cmd related
 202  */
 203 typedef struct {
 204         line_t *head;
 205         line_t *tail;
 206 } filelist_t;
 207 
 208 #define BOOT_FILE_LIST  "boot/solaris/filelist.ramdisk"
 209 #define ETC_FILE_LIST   "etc/boot/solaris/filelist.ramdisk"
 210 
 211 #define FILE_STAT       "boot/solaris/filestat.ramdisk"
 212 #define FILE_STAT_TMP   "boot/solaris/filestat.ramdisk.tmp"
 213 #define DIR_PERMS       (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
 214 #define FILE_STAT_MODE  (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)


4673         }
4674 
4675         return (BAM_SUCCESS);
4676 }
4677 
4678 int
4679 add_boot_entry(menu_t *mp,
4680         char *title,
4681         char *findroot,
4682         char *kernel,
4683         char *mod_kernel,
4684         char *module,
4685         char *bootfs)
4686 {
4687         int             lineNum;
4688         int             entryNum;
4689         char            linebuf[BAM_MAXLINE];
4690         menu_cmd_t      k_cmd;
4691         menu_cmd_t      m_cmd;
4692         const char      *fcn = "add_boot_entry()";

4693 
4694         assert(mp);
4695 
4696         INJECT_ERROR1("ADD_BOOT_ENTRY_FINDROOT_NULL", findroot = NULL);
4697         if (findroot == NULL) {
4698                 bam_error(NULL_FINDROOT);
4699                 return (BAM_ERROR);
4700         }
4701 
4702         if (title == NULL) {
4703                 title = "Solaris";      /* default to Solaris */
4704         }
4705         if (kernel == NULL) {
4706                 bam_error(SUBOPT_MISS, menu_cmds[KERNEL_CMD]);
4707                 return (BAM_ERROR);
4708         }
4709         if (module == NULL) {
4710                 if (bam_direct != BAM_DIRECT_DBOOT) {
4711                         bam_error(SUBOPT_MISS, menu_cmds[MODULE_CMD]);
4712                         return (BAM_ERROR);


4739          */
4740         (void) snprintf(linebuf, sizeof (linebuf), "%s%s",
4741             menu_cmds[COMMENT_CMD], BAM_BOOTADM_HDR);
4742         line_parser(mp, linebuf, &lineNum, &entryNum);
4743 
4744         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4745             menu_cmds[TITLE_CMD], menu_cmds[SEP_CMD], title);
4746         line_parser(mp, linebuf, &lineNum, &entryNum);
4747 
4748         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4749             menu_cmds[FINDROOT_CMD], menu_cmds[SEP_CMD], findroot);
4750         line_parser(mp, linebuf, &lineNum, &entryNum);
4751         BAM_DPRINTF((D_ADD_FINDROOT_NUM, fcn, lineNum, entryNum));
4752 
4753         if (bootfs != NULL) {
4754                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4755                     menu_cmds[BOOTFS_CMD], menu_cmds[SEP_CMD], bootfs);
4756                 line_parser(mp, linebuf, &lineNum, &entryNum);
4757         }
4758 




4759         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4760             menu_cmds[k_cmd], menu_cmds[SEP_CMD], kernel);
4761         line_parser(mp, linebuf, &lineNum, &entryNum);
4762 






4763         if (mod_kernel != NULL) {
4764                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4765                     menu_cmds[m_cmd], menu_cmds[SEP_CMD], mod_kernel);
4766                 line_parser(mp, linebuf, &lineNum, &entryNum);
4767         }
4768 
4769         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4770             menu_cmds[m_cmd], menu_cmds[SEP_CMD], module);
4771         line_parser(mp, linebuf, &lineNum, &entryNum);
4772 
4773         (void) snprintf(linebuf, sizeof (linebuf), "%s%s",
4774             menu_cmds[COMMENT_CMD], BAM_BOOTADM_FTR);
4775         line_parser(mp, linebuf, &lineNum, &entryNum);
4776 
4777         return (entryNum);
4778 }
4779 
4780 error_t
4781 delete_boot_entry(menu_t *mp, int entryNum, int quiet)
4782 {


7095                 (void) unlink(UFS_SIGNATURE_LIST);
7096                 return (NULL);
7097         }
7098 
7099         free(fstype);
7100 
7101         if (bam_verbose)
7102                 bam_print(GRUBSIGN_FOUND_OR_CREATED, sign, osdev);
7103 
7104         fdiskpart = get_partition(osdev);
7105         INJECT_ERROR1("GET_GRUBSIGN_FDISK", fdiskpart = -1);
7106         if (fdiskpart == -1) {
7107                 bam_error(FDISKPART_FAIL, osdev);
7108                 free(sign);
7109                 return (NULL);
7110         }
7111 
7112         slice = strrchr(osdev, 's');
7113 
7114         grubsign = s_calloc(1, MAXNAMELEN + 10);
7115         if (slice) {
7116                 (void) snprintf(grubsign, MAXNAMELEN + 10, "(%s,%d,%c)",
7117                     sign, fdiskpart, slice[1] + 'a' - '0');
7118         } else
7119                 (void) snprintf(grubsign, MAXNAMELEN + 10, "(%s,%d)",
7120                     sign, fdiskpart);

7121 
7122         free(sign);
7123 
7124         BAM_DPRINTF((D_GET_GRUBSIGN_SUCCESS, fcn, grubsign));
7125 
7126         return (grubsign);
7127 }
7128 
7129 static char *
7130 get_title(char *rootdir)
7131 {
7132         static char     title[80];
7133         char            *cp = NULL;
7134         char            release[PATH_MAX];
7135         FILE            *fp;
7136         const char      *fcn = "get_title()";
7137 
7138         /* open the /etc/release file */
7139         (void) snprintf(release, sizeof (release), "%s/etc/release", rootdir);
7140 
7141         fp = fopen(release, "r");
7142         if (fp == NULL) {
7143                 bam_error(OPEN_FAIL, release, strerror(errno));
7144                 cp = NULL;
7145                 goto out;
7146         }


7795                                 BAM_DPRINTF((D_MATCHED_TITLE, fcn, title));
7796                                 break;
7797                         }
7798                         BAM_DPRINTF((D_NOMATCH_TITLE, fcn, title, lp->arg));
7799                         continue;       /* check title only */
7800                 }
7801 
7802                 lp = lp->next;       /* advance to root line */
7803                 if (lp == NULL) {
7804                         continue;
7805                 } else if (lp->cmd != NULL &&
7806                     strcmp(lp->cmd, menu_cmds[FINDROOT_CMD]) == 0) {
7807                         INJECT_ERROR1("FIND_BOOT_ENTRY_NULL_FINDROOT",
7808                             findroot = NULL);
7809                         if (findroot == NULL) {
7810                                 BAM_DPRINTF((D_NOMATCH_FINDROOT_NULL,
7811                                     fcn, lp->arg));
7812                                 continue;
7813                         }
7814                         /* findroot command found, try match  */
7815                         if (strcmp(lp->arg, findroot) != 0) {
7816                                 BAM_DPRINTF((D_NOMATCH_FINDROOT,
7817                                     fcn, findroot, lp->arg));
7818                                 continue;
7819                         }
7820                         BAM_DPRINTF((D_MATCHED_FINDROOT, fcn, findroot));
7821                         lp = lp->next;       /* advance to kernel line */
7822                 } else if (lp->cmd != NULL &&
7823                     strcmp(lp->cmd, menu_cmds[ROOT_CMD]) == 0) {
7824                         INJECT_ERROR1("FIND_BOOT_ENTRY_NULL_ROOT", root = NULL);
7825                         if (root == NULL) {
7826                                 BAM_DPRINTF((D_NOMATCH_ROOT_NULL,
7827                                     fcn, lp->arg));
7828                                 continue;
7829                         }
7830                         /* root cmd found, try match */
7831                         if (strcmp(lp->arg, root) != 0) {
7832                                 BAM_DPRINTF((D_NOMATCH_ROOT,
7833                                     fcn, root, lp->arg));
7834                                 continue;
7835                         }


7853                 }
7854 
7855                 if (kernel &&
7856                     (!check_cmd(lp->cmd, KERNEL_CMD, lp->arg, kernel))) {
7857                         if (!(ent->flags & BAM_ENTRY_FAILSAFE) ||
7858                             !(ent->flags & BAM_ENTRY_DBOOT) ||
7859                             strcmp(kernel, DIRECT_BOOT_FAILSAFE_LINE) != 0)
7860                                 continue;
7861 
7862                         ent->flags |= BAM_ENTRY_UPGFSKERNEL;
7863 
7864                 }
7865                 BAM_DPRINTF((D_KERNEL_MATCH, fcn, kernel, lp->arg));
7866 
7867                 /*
7868                  * Check for matching module entry (failsafe or normal).
7869                  * If it fails to match, we go around the loop again.
7870                  * For xpv entries, there are two module lines, so we
7871                  * do the check twice.
7872                  */

7873                 lp = lp->next;       /* advance to module line */
7874                 if (check_cmd(lp->cmd, MODULE_CMD, lp->arg, module) ||
7875                     (((lp = lp->next) != NULL) &&
7876                     check_cmd(lp->cmd, MODULE_CMD, lp->arg, module))) {
7877                         /* match found */
7878                         BAM_DPRINTF((D_MODULE_MATCH, fcn, module, lp->arg));
7879                         break;
7880                 }
7881 
7882                 if (strcmp(module, FAILSAFE_ARCHIVE) == 0 &&
7883                     (strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_32) == 0 ||
7884                     strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_64) == 0)) {
7885                         ent->flags |= BAM_ENTRY_UPGFSMODULE;
7886                         break;
7887                 }
7888 
7889         }
7890 
7891         if (ent && entry_num) {
7892                 *entry_num = i;


7894 
7895         if (ent) {
7896                 BAM_DPRINTF((D_RETURN_RET, fcn, i));
7897         } else {
7898                 BAM_DPRINTF((D_RETURN_RET, fcn, BAM_ERROR));
7899         }
7900         return (ent);
7901 }
7902 
7903 static int
7904 update_boot_entry(menu_t *mp, char *title, char *findroot, char *root,
7905     char *kernel, char *mod_kernel, char *module, int root_opt)
7906 {
7907         int             i;
7908         int             change_kernel = 0;
7909         entry_t         *ent;
7910         line_t          *lp;
7911         line_t          *tlp;
7912         char            linebuf[BAM_MAXLINE];
7913         const char      *fcn = "update_boot_entry()";

7914 
7915         /* note: don't match on title, it's updated on upgrade */
7916         ent = find_boot_entry(mp, NULL, kernel, findroot, root, module,
7917             root_opt, &i);
7918         if ((ent == NULL) && (bam_direct == BAM_DIRECT_DBOOT)) {
7919                 /*
7920                  * We may be upgrading a kernel from multiboot to
7921                  * directboot.  Look for a multiboot entry. A multiboot
7922                  * entry will not have a findroot line.
7923                  */
7924                 ent = find_boot_entry(mp, NULL, "multiboot", NULL, root,
7925                     MULTIBOOT_ARCHIVE, root_opt, &i);
7926                 if (ent != NULL) {
7927                         BAM_DPRINTF((D_UPGRADE_FROM_MULTIBOOT, fcn, root));
7928                         change_kernel = 1;
7929                 }
7930         } else if (ent) {
7931                 BAM_DPRINTF((D_FOUND_FINDROOT, fcn, findroot));
7932         }
7933 


7950 
7951         tlp = lp;       /* title line */
7952         lp = lp->next;       /* root line */
7953 
7954         /* if no root or findroot command, create a new line_t */
7955         if ((lp->cmd != NULL) && (strcmp(lp->cmd, menu_cmds[ROOT_CMD]) != 0 &&
7956             strcmp(lp->cmd, menu_cmds[FINDROOT_CMD]) != 0)) {
7957                 lp = s_calloc(1, sizeof (line_t));
7958                 bam_add_line(mp, ent, tlp, lp);
7959         } else {
7960                 if (lp->cmd != NULL)
7961                         free(lp->cmd);
7962 
7963                 free(lp->sep);
7964                 free(lp->arg);
7965                 free(lp->line);
7966         }
7967 
7968         lp->cmd = s_strdup(menu_cmds[FINDROOT_CMD]);
7969         lp->sep = s_strdup(menu_cmds[SEP_CMD]);
7970         lp->arg = s_strdup(findroot);


7971         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
7972             menu_cmds[FINDROOT_CMD], menu_cmds[SEP_CMD], findroot);
7973         lp->line = s_strdup(linebuf);

7974         BAM_DPRINTF((D_ADDING_FINDROOT_LINE, fcn, findroot));
7975 
7976         /* kernel line */
7977         lp = lp->next;
7978 
7979         if (ent->flags & BAM_ENTRY_UPGFSKERNEL) {
7980                 char            *params = NULL;

7981 
7982                 params = strstr(lp->line, "-s");
7983                 if (params != NULL)
7984                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s%s",
7985                             menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
7986                             kernel, params+2);
7987                 else
7988                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
7989                             menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
7990                             kernel);
7991 
7992                 if (lp->cmd != NULL)
7993                         free(lp->cmd);
7994 
7995                 free(lp->arg);
7996                 free(lp->line);
7997                 lp->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]);
7998                 lp->arg = s_strdup(strstr(linebuf, "/"));
7999                 lp->line = s_strdup(linebuf);
8000                 ent->flags &= ~BAM_ENTRY_UPGFSKERNEL;
8001                 BAM_DPRINTF((D_ADDING_KERNEL_DOLLAR, fcn, lp->prev->cmd));













8002         }
8003 
8004         if (change_kernel) {

8005                 /*
8006                  * We're upgrading from multiboot to directboot.
8007                  */


8008                 if (lp->cmd != NULL &&
8009                     strcmp(lp->cmd, menu_cmds[KERNEL_CMD]) == 0) {
8010                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
8011                             menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
8012                             kernel);
8013                         free(lp->cmd);
8014                         free(lp->arg);
8015                         free(lp->line);
8016                         lp->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]);
8017                         lp->arg = s_strdup(kernel);
8018                         lp->line = s_strdup(linebuf);
8019                         lp = lp->next;
8020                         BAM_DPRINTF((D_ADDING_KERNEL_DOLLAR, fcn, kernel));






8021                 }
8022                 if (lp->cmd != NULL &&
8023                     strcmp(lp->cmd, menu_cmds[MODULE_CMD]) == 0) {
8024                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
8025                             menu_cmds[MODULE_DOLLAR_CMD], menu_cmds[SEP_CMD],
8026                             module);
8027                         free(lp->cmd);
8028                         free(lp->arg);
8029                         free(lp->line);
8030                         lp->cmd = s_strdup(menu_cmds[MODULE_DOLLAR_CMD]);
8031                         lp->arg = s_strdup(module);
8032                         lp->line = s_strdup(linebuf);
8033                         lp = lp->next;
8034                         BAM_DPRINTF((D_ADDING_MODULE_DOLLAR, fcn, module));
8035                 }
8036         }
8037 
8038         /* module line */
8039         lp = lp->next;
8040 


8929                     sizeof (DIRECT_BOOT_KERNEL) - 1) == 0))) {
8930                         kernelp = NULL;
8931                         (void) delete_boot_entry(mp, entryNum, DBE_PRINTERR);
8932                         restore_default_entry(mp, BAM_OLD_RC_DEF,
8933                             mp->old_rc_default);
8934                         mp->old_rc_default = NULL;
8935                         rv = BAM_WRITE;
8936                         BAM_DPRINTF((D_GET_SET_KERNEL_RESTORE_DEFAULT, fcn));
8937                         goto done;
8938                 }
8939 
8940                 if (optnum == KERNEL_CMD) {
8941                         /*
8942                          * At this point, we've already checked that old_args
8943                          * and entryp are valid pointers.  The "+ 2" is for
8944                          * a space a the string termination character.
8945                          */
8946                         new_str_len = (sizeof (DIRECT_BOOT_KERNEL) - 1) +
8947                             strlen(old_args) + 2;
8948                         new_arg = s_calloc(1, new_str_len);
8949                         (void) snprintf(new_arg, new_str_len, "%s %s",
8950                             DIRECT_BOOT_KERNEL, old_args);
8951                         free(kernelp->arg);
8952                         kernelp->arg = new_arg;
8953 
8954                         /*
8955                          * We have changed the kernel line, so we may need
8956                          * to update the archive line as well.
8957                          */
8958                         set_archive_line(entryp, kernelp);
8959                         BAM_DPRINTF((D_GET_SET_KERNEL_RESET_KERNEL_SET_ARG,
8960                             fcn, kernelp->arg));
8961                 } else {
8962                         /*
8963                          * We're resetting the boot args to nothing, so
8964                          * we only need to copy the kernel.  We've already
8965                          * checked that the kernel is not the default.
8966                          */
8967                         new_arg = s_calloc(1, old_kernel_len + 1);
8968                         (void) snprintf(new_arg, old_kernel_len + 1, "%s",
8969                             kernelp->arg);
8970                         free(kernelp->arg);


9091 
9092         /*
9093          * There was already an bootenv entry which we need to edit.
9094          */
9095         if (optnum == KERNEL_CMD) {
9096                 new_str_len = strlen(new_path) + strlen(old_args) + 2;
9097                 new_arg = s_calloc(1, new_str_len);
9098                 (void) snprintf(new_arg, new_str_len, "%s %s", new_path,
9099                     old_args);
9100                 free(kernelp->arg);
9101                 kernelp->arg = new_arg;
9102 
9103                 /*
9104                  * If we have changed the kernel line, we may need to update
9105                  * the archive line as well.
9106                  */
9107                 set_archive_line(entryp, kernelp);
9108                 BAM_DPRINTF((D_GET_SET_KERNEL_REPLACED_KERNEL_SAME_ARG, fcn,
9109                     kernelp->arg));
9110         } else {
9111                 new_str_len = old_kernel_len + strlen(path) + 8;

9112                 new_arg = s_calloc(1, new_str_len);
9113                 (void) strncpy(new_arg, kernelp->arg, old_kernel_len);
9114                 (void) strlcat(new_arg, " ", new_str_len);
9115                 (void) strlcat(new_arg, path, new_str_len);
9116                 free(kernelp->arg);
9117                 kernelp->arg = new_arg;
9118                 BAM_DPRINTF((D_GET_SET_KERNEL_SAME_KERNEL_REPLACED_ARG, fcn,
9119                     kernelp->arg));
9120         }
9121         rv = BAM_WRITE;
9122 
9123 done:
9124         if ((rv == BAM_WRITE) && kernelp)
9125                 update_line(kernelp);
9126         if (free_new_path)
9127                 free(new_path);
9128         if (rv == BAM_WRITE) {
9129                 BAM_DPRINTF((D_RETURN_SUCCESS, fcn));
9130         } else {
9131                 BAM_DPRINTF((D_RETURN_FAILURE, fcn));
9132         }
9133         return (rv);




 101 
 102 typedef enum {
 103     OPT_ABSENT = 0,     /* No option */
 104     OPT_REQ,            /* option required */
 105     OPT_OPTIONAL        /* option may or may not be present */
 106 } option_t;
 107 
 108 typedef struct {
 109         char    *subcmd;
 110         option_t option;
 111         error_t (*handler)();
 112         int     unpriv;                 /* is this an unprivileged command */
 113 } subcmd_defn_t;
 114 
 115 #define LINE_INIT       0       /* lineNum initial value */
 116 #define ENTRY_INIT      -1      /* entryNum initial value */
 117 #define ALL_ENTRIES     -2      /* selects all boot entries */
 118 
 119 #define GRUB_DIR                "/boot/grub"
 120 #define GRUB_STAGE2             GRUB_DIR "/stage2"
 121 #define GRUB_MENU               "/boot/illumos.cfg"
 122 #define MENU_TMP                "/boot/illumos.cfg.tmp"
 123 #define GRUB_BACKUP_MENU        "/etc/lu/GRUB_backup_menu"
 124 #define RAMDISK_SPECIAL         "/ramdisk"
 125 #define STUBBOOT                "/stubboot"
 126 #define MULTIBOOT               "/platform/i86pc/multiboot"
 127 #define GRUBSIGN_DIR            "/boot/grub/bootsign"
 128 #define GRUBSIGN_BACKUP         "/etc/bootsign"
 129 #define GRUBSIGN_UFS_PREFIX     "rootfs"
 130 #define GRUBSIGN_ZFS_PREFIX     "pool_"
 131 #define GRUBSIGN_LU_PREFIX      "BE_"
 132 #define UFS_SIGNATURE_LIST      "/var/run/grub_ufs_signatures"
 133 #define ZFS_LEGACY_MNTPT        "/tmp/bootadm_mnt_zfs_legacy"
 134 
 135 #define BOOTADM_RDONLY_TEST     "BOOTADM_RDONLY_TEST"
 136 
 137 /* lock related */
 138 #define BAM_LOCK_FILE           "/var/run/bootadm.lock"
 139 #define LOCK_FILE_PERMS         (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
 140 
 141 #define CREATE_RAMDISK          "boot/solaris/bin/create_ramdisk"
 142 #define CREATE_DISKMAP          "boot/solaris/bin/create_diskmap"


 161 typedef enum zfs_mnted {
 162         ZFS_MNT_ERROR = -1,
 163         LEGACY_MOUNTED = 1,
 164         LEGACY_ALREADY,
 165         ZFS_MOUNTED,
 166         ZFS_ALREADY
 167 } zfs_mnted_t;
 168 
 169 /*
 170  * Default file attributes
 171  */
 172 #define DEFAULT_DEV_MODE        0644    /* default permissions */
 173 #define DEFAULT_DEV_UID         0       /* user root */
 174 #define DEFAULT_DEV_GID         3       /* group sys */
 175 
 176 /*
 177  * Menu related
 178  * menu_cmd_t and menu_cmds must be kept in sync
 179  */
 180 char *menu_cmds[] = {
 181         "default_entry",/* DEFAULT_CMD */
 182         "timeout",      /* TIMEOUT_CMD */
 183         "entry_name",   /* TITLE_CMD */
 184         "pool_uuid",    /* ROOT_CMD */
 185         "kernel_path$", /* KERNEL_CMD */
 186         "kernel_path",  /* KERNEL_DOLLAR_CMD */
 187         "module$",      /* MODULE_CMD */
 188         "module",       /* MODULE_DOLLAR_CMD */
 189         "=",            /* SEP_CMD */
 190         "#",            /* COMMENT_CMD */
 191         "chainloader",  /* CHAINLOADER_CMD */
 192         "args",         /* ARGS_CMD */
 193         "pool_label",   /* FINDROOT_CMD */
 194         "dataset",      /* BOOTFS_CMD */
 195         "kernel_options",/* KERNEL_OPTIONS_CMD */
 196         NULL
 197 };
 198 
 199 #define OPT_ENTRY_NUM   "entry"
 200 
 201 /*
 202  * exec_cmd related
 203  */
 204 typedef struct {
 205         line_t *head;
 206         line_t *tail;
 207 } filelist_t;
 208 
 209 #define BOOT_FILE_LIST  "boot/solaris/filelist.ramdisk"
 210 #define ETC_FILE_LIST   "etc/boot/solaris/filelist.ramdisk"
 211 
 212 #define FILE_STAT       "boot/solaris/filestat.ramdisk"
 213 #define FILE_STAT_TMP   "boot/solaris/filestat.ramdisk.tmp"
 214 #define DIR_PERMS       (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
 215 #define FILE_STAT_MODE  (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)


4674         }
4675 
4676         return (BAM_SUCCESS);
4677 }
4678 
4679 int
4680 add_boot_entry(menu_t *mp,
4681         char *title,
4682         char *findroot,
4683         char *kernel,
4684         char *mod_kernel,
4685         char *module,
4686         char *bootfs)
4687 {
4688         int             lineNum;
4689         int             entryNum;
4690         char            linebuf[BAM_MAXLINE];
4691         menu_cmd_t      k_cmd;
4692         menu_cmd_t      m_cmd;
4693         const char      *fcn = "add_boot_entry()";
4694         char * options;
4695 
4696         assert(mp);
4697 
4698         INJECT_ERROR1("ADD_BOOT_ENTRY_FINDROOT_NULL", findroot = NULL);
4699         if (findroot == NULL) {
4700                 bam_error(NULL_FINDROOT);
4701                 return (BAM_ERROR);
4702         }
4703 
4704         if (title == NULL) {
4705                 title = "Solaris";      /* default to Solaris */
4706         }
4707         if (kernel == NULL) {
4708                 bam_error(SUBOPT_MISS, menu_cmds[KERNEL_CMD]);
4709                 return (BAM_ERROR);
4710         }
4711         if (module == NULL) {
4712                 if (bam_direct != BAM_DIRECT_DBOOT) {
4713                         bam_error(SUBOPT_MISS, menu_cmds[MODULE_CMD]);
4714                         return (BAM_ERROR);


4741          */
4742         (void) snprintf(linebuf, sizeof (linebuf), "%s%s",
4743             menu_cmds[COMMENT_CMD], BAM_BOOTADM_HDR);
4744         line_parser(mp, linebuf, &lineNum, &entryNum);
4745 
4746         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4747             menu_cmds[TITLE_CMD], menu_cmds[SEP_CMD], title);
4748         line_parser(mp, linebuf, &lineNum, &entryNum);
4749 
4750         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4751             menu_cmds[FINDROOT_CMD], menu_cmds[SEP_CMD], findroot);
4752         line_parser(mp, linebuf, &lineNum, &entryNum);
4753         BAM_DPRINTF((D_ADD_FINDROOT_NUM, fcn, lineNum, entryNum));
4754 
4755         if (bootfs != NULL) {
4756                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4757                     menu_cmds[BOOTFS_CMD], menu_cmds[SEP_CMD], bootfs);
4758                 line_parser(mp, linebuf, &lineNum, &entryNum);
4759         }
4760 
4761         options = strpbrk(kernel, " \t");
4762         if (options)
4763                 *options++ = 0;
4764 
4765         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4766             menu_cmds[k_cmd], menu_cmds[SEP_CMD], kernel);
4767         line_parser(mp, linebuf, &lineNum, &entryNum);
4768 
4769         if (options) {
4770                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4771                     menu_cmds[KERNEL_OPTIONS_CMD], menu_cmds[SEP_CMD], options);
4772                 line_parser(mp, linebuf, &lineNum, &entryNum);
4773         }
4774 
4775         if (mod_kernel != NULL) {
4776                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4777                     menu_cmds[m_cmd], menu_cmds[SEP_CMD], mod_kernel);
4778                 line_parser(mp, linebuf, &lineNum, &entryNum);
4779         }
4780 
4781         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
4782             menu_cmds[m_cmd], menu_cmds[SEP_CMD], module);
4783         line_parser(mp, linebuf, &lineNum, &entryNum);
4784 
4785         (void) snprintf(linebuf, sizeof (linebuf), "%s%s",
4786             menu_cmds[COMMENT_CMD], BAM_BOOTADM_FTR);
4787         line_parser(mp, linebuf, &lineNum, &entryNum);
4788 
4789         return (entryNum);
4790 }
4791 
4792 error_t
4793 delete_boot_entry(menu_t *mp, int entryNum, int quiet)
4794 {


7107                 (void) unlink(UFS_SIGNATURE_LIST);
7108                 return (NULL);
7109         }
7110 
7111         free(fstype);
7112 
7113         if (bam_verbose)
7114                 bam_print(GRUBSIGN_FOUND_OR_CREATED, sign, osdev);
7115 
7116         fdiskpart = get_partition(osdev);
7117         INJECT_ERROR1("GET_GRUBSIGN_FDISK", fdiskpart = -1);
7118         if (fdiskpart == -1) {
7119                 bam_error(FDISKPART_FAIL, osdev);
7120                 free(sign);
7121                 return (NULL);
7122         }
7123 
7124         slice = strrchr(osdev, 's');
7125 
7126         grubsign = s_calloc(1, MAXNAMELEN + 10);
7127 /*      if (slice) {
7128                 (void) snprintf(grubsign, MAXNAMELEN + 10, "(%s,%d,%c)",
7129                     sign, fdiskpart, slice[1] + 'a' - '0');
7130         } else
7131                 (void) snprintf(grubsign, MAXNAMELEN + 10, "(%s,%d)",
7132                     sign, fdiskpart);*/
7133         grubsign = strdup(sign);
7134 
7135         free(sign);
7136 
7137         BAM_DPRINTF((D_GET_GRUBSIGN_SUCCESS, fcn, grubsign));
7138 
7139         return (strchr(grubsign,'_') + 1);
7140 }
7141 
7142 static char *
7143 get_title(char *rootdir)
7144 {
7145         static char     title[80];
7146         char            *cp = NULL;
7147         char            release[PATH_MAX];
7148         FILE            *fp;
7149         const char      *fcn = "get_title()";
7150 
7151         /* open the /etc/release file */
7152         (void) snprintf(release, sizeof (release), "%s/etc/release", rootdir);
7153 
7154         fp = fopen(release, "r");
7155         if (fp == NULL) {
7156                 bam_error(OPEN_FAIL, release, strerror(errno));
7157                 cp = NULL;
7158                 goto out;
7159         }


7808                                 BAM_DPRINTF((D_MATCHED_TITLE, fcn, title));
7809                                 break;
7810                         }
7811                         BAM_DPRINTF((D_NOMATCH_TITLE, fcn, title, lp->arg));
7812                         continue;       /* check title only */
7813                 }
7814 
7815                 lp = lp->next;       /* advance to root line */
7816                 if (lp == NULL) {
7817                         continue;
7818                 } else if (lp->cmd != NULL &&
7819                     strcmp(lp->cmd, menu_cmds[FINDROOT_CMD]) == 0) {
7820                         INJECT_ERROR1("FIND_BOOT_ENTRY_NULL_FINDROOT",
7821                             findroot = NULL);
7822                         if (findroot == NULL) {
7823                                 BAM_DPRINTF((D_NOMATCH_FINDROOT_NULL,
7824                                     fcn, lp->arg));
7825                                 continue;
7826                         }
7827                         /* findroot command found, try match  */
7828                         if (strncmp(lp->arg, strchr(findroot, '_') + 1, strlen(lp->arg)) != 0) {
7829                                 BAM_DPRINTF((D_NOMATCH_FINDROOT,
7830                                     fcn, findroot, lp->arg));
7831                                 continue;
7832                         }
7833                         BAM_DPRINTF((D_MATCHED_FINDROOT, fcn, findroot));
7834                         lp = lp->next;       /* advance to kernel line */
7835                 } else if (lp->cmd != NULL &&
7836                     strcmp(lp->cmd, menu_cmds[ROOT_CMD]) == 0) {
7837                         INJECT_ERROR1("FIND_BOOT_ENTRY_NULL_ROOT", root = NULL);
7838                         if (root == NULL) {
7839                                 BAM_DPRINTF((D_NOMATCH_ROOT_NULL,
7840                                     fcn, lp->arg));
7841                                 continue;
7842                         }
7843                         /* root cmd found, try match */
7844                         if (strcmp(lp->arg, root) != 0) {
7845                                 BAM_DPRINTF((D_NOMATCH_ROOT,
7846                                     fcn, root, lp->arg));
7847                                 continue;
7848                         }


7866                 }
7867 
7868                 if (kernel &&
7869                     (!check_cmd(lp->cmd, KERNEL_CMD, lp->arg, kernel))) {
7870                         if (!(ent->flags & BAM_ENTRY_FAILSAFE) ||
7871                             !(ent->flags & BAM_ENTRY_DBOOT) ||
7872                             strcmp(kernel, DIRECT_BOOT_FAILSAFE_LINE) != 0)
7873                                 continue;
7874 
7875                         ent->flags |= BAM_ENTRY_UPGFSKERNEL;
7876 
7877                 }
7878                 BAM_DPRINTF((D_KERNEL_MATCH, fcn, kernel, lp->arg));
7879 
7880                 /*
7881                  * Check for matching module entry (failsafe or normal).
7882                  * If it fails to match, we go around the loop again.
7883                  * For xpv entries, there are two module lines, so we
7884                  * do the check twice.
7885                  */
7886                 lp = lp->next;       /* advance to options line */
7887                 lp = lp->next;       /* advance to module line */
7888                 if (check_cmd(lp->cmd, MODULE_CMD, lp->arg, module) ||
7889                     (((lp = lp->next) != NULL) &&
7890                     check_cmd(lp->cmd, MODULE_CMD, lp->arg, module))) {
7891                         /* match found */
7892                         BAM_DPRINTF((D_MODULE_MATCH, fcn, module, lp->arg));
7893                         break;
7894                 }
7895 
7896                 if (strcmp(module, FAILSAFE_ARCHIVE) == 0 &&
7897                     (strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_32) == 0 ||
7898                     strcmp(lp->prev->arg, FAILSAFE_ARCHIVE_64) == 0)) {
7899                         ent->flags |= BAM_ENTRY_UPGFSMODULE;
7900                         break;
7901                 }
7902 
7903         }
7904 
7905         if (ent && entry_num) {
7906                 *entry_num = i;


7908 
7909         if (ent) {
7910                 BAM_DPRINTF((D_RETURN_RET, fcn, i));
7911         } else {
7912                 BAM_DPRINTF((D_RETURN_RET, fcn, BAM_ERROR));
7913         }
7914         return (ent);
7915 }
7916 
7917 static int
7918 update_boot_entry(menu_t *mp, char *title, char *findroot, char *root,
7919     char *kernel, char *mod_kernel, char *module, int root_opt)
7920 {
7921         int             i;
7922         int             change_kernel = 0;
7923         entry_t         *ent;
7924         line_t          *lp;
7925         line_t          *tlp;
7926         char            linebuf[BAM_MAXLINE];
7927         const char      *fcn = "update_boot_entry()";
7928         char            *label;
7929 
7930         /* note: don't match on title, it's updated on upgrade */
7931         ent = find_boot_entry(mp, NULL, kernel, findroot, root, module,
7932             root_opt, &i);
7933         if ((ent == NULL) && (bam_direct == BAM_DIRECT_DBOOT)) {
7934                 /*
7935                  * We may be upgrading a kernel from multiboot to
7936                  * directboot.  Look for a multiboot entry. A multiboot
7937                  * entry will not have a findroot line.
7938                  */
7939                 ent = find_boot_entry(mp, NULL, "multiboot", NULL, root,
7940                     MULTIBOOT_ARCHIVE, root_opt, &i);
7941                 if (ent != NULL) {
7942                         BAM_DPRINTF((D_UPGRADE_FROM_MULTIBOOT, fcn, root));
7943                         change_kernel = 1;
7944                 }
7945         } else if (ent) {
7946                 BAM_DPRINTF((D_FOUND_FINDROOT, fcn, findroot));
7947         }
7948 


7965 
7966         tlp = lp;       /* title line */
7967         lp = lp->next;       /* root line */
7968 
7969         /* if no root or findroot command, create a new line_t */
7970         if ((lp->cmd != NULL) && (strcmp(lp->cmd, menu_cmds[ROOT_CMD]) != 0 &&
7971             strcmp(lp->cmd, menu_cmds[FINDROOT_CMD]) != 0)) {
7972                 lp = s_calloc(1, sizeof (line_t));
7973                 bam_add_line(mp, ent, tlp, lp);
7974         } else {
7975                 if (lp->cmd != NULL)
7976                         free(lp->cmd);
7977 
7978                 free(lp->sep);
7979                 free(lp->arg);
7980                 free(lp->line);
7981         }
7982 
7983         lp->cmd = s_strdup(menu_cmds[FINDROOT_CMD]);
7984         lp->sep = s_strdup(menu_cmds[SEP_CMD]);
7985         label = s_strdup(strchr(findroot, '_') + 1);
7986         *(strchr(label,',')) = 0;
7987         lp->arg = s_strdup(label);
7988         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
7989             menu_cmds[FINDROOT_CMD], menu_cmds[SEP_CMD], label);
7990         lp->line = s_strdup(linebuf);
7991         free(label);
7992         BAM_DPRINTF((D_ADDING_FINDROOT_LINE, fcn, findroot));
7993 
7994         /* kernel line */
7995         lp = lp->next;
7996 
7997         if (ent->flags & BAM_ENTRY_UPGFSKERNEL) {
7998                 char            *params = NULL;
7999                 char            *opts = NULL;
8000 
8001                 opts = strpbrk(kernel, " \t");
8002                 *opts++ = '\0';




8003                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
8004                     menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
8005                     kernel);
8006 
8007                 if (lp->cmd != NULL)
8008                         free(lp->cmd);
8009 
8010                 free(lp->arg);
8011                 free(lp->line);
8012                 lp->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]);
8013                 lp->arg = s_strdup(strstr(linebuf, "/"));
8014                 lp->line = s_strdup(linebuf);
8015                 ent->flags &= ~BAM_ENTRY_UPGFSKERNEL;
8016                 BAM_DPRINTF((D_ADDING_KERNEL_DOLLAR, fcn, lp->prev->cmd));
8017 
8018                 lp = lp->next;
8019                 params = strstr(lp->arg, "-s");
8020                 free(lp->arg);
8021                 free(lp->line);
8022                 if (params)
8023                         (void) snprintf(linebuf, sizeof(linebuf), "%s%s%s -s",
8024                                 lp->cmd, menu_cmds[SEP_CMD],opts);
8025                 else
8026                         (void) snprintf(linebuf, sizeof(linebuf), "%s%s%s",
8027                                 lp->cmd, menu_cmds[SEP_CMD],opts);
8028                 lp->line = s_strdup(linebuf);
8029                 lp->arg = s_strdup(strchr(linebuf, '=') + 1);
8030         }
8031 
8032         if (change_kernel) {
8033                 char            *opts = NULL;
8034                 /*
8035                  * We're upgrading from multiboot to directboot.
8036                  */
8037                 opts = strpbrk(kernel, " \t");
8038                 *opts++ = '\0';
8039                 if (lp->cmd != NULL &&
8040                     strcmp(lp->cmd, menu_cmds[KERNEL_CMD]) == 0) {
8041                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
8042                             menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
8043                             kernel);
8044                         free(lp->cmd);
8045                         free(lp->arg);
8046                         free(lp->line);
8047                         lp->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]);
8048                         lp->arg = s_strdup(kernel);
8049                         lp->line = s_strdup(linebuf);
8050                         lp = lp->next;
8051                         BAM_DPRINTF((D_ADDING_KERNEL_DOLLAR, fcn, kernel));
8052                         (void) snprintf(linebuf, sizeof(linebuf), "%s%s%s",
8053                                 lp->cmd, menu_cmds[SEP_CMD],opts);
8054                         free(lp->arg);
8055                         free(lp->line);
8056                         lp->line = s_strdup(linebuf);
8057                         lp->arg = s_strdup(strchr(linebuf, '=') + 1);
8058                 }
8059                 if (lp->cmd != NULL &&
8060                     strcmp(lp->cmd, menu_cmds[MODULE_CMD]) == 0) {
8061                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
8062                             menu_cmds[MODULE_DOLLAR_CMD], menu_cmds[SEP_CMD],
8063                             module);
8064                         free(lp->cmd);
8065                         free(lp->arg);
8066                         free(lp->line);
8067                         lp->cmd = s_strdup(menu_cmds[MODULE_DOLLAR_CMD]);
8068                         lp->arg = s_strdup(module);
8069                         lp->line = s_strdup(linebuf);
8070                         lp = lp->next;
8071                         BAM_DPRINTF((D_ADDING_MODULE_DOLLAR, fcn, module));
8072                 }
8073         }
8074 
8075         /* module line */
8076         lp = lp->next;
8077 


8966                     sizeof (DIRECT_BOOT_KERNEL) - 1) == 0))) {
8967                         kernelp = NULL;
8968                         (void) delete_boot_entry(mp, entryNum, DBE_PRINTERR);
8969                         restore_default_entry(mp, BAM_OLD_RC_DEF,
8970                             mp->old_rc_default);
8971                         mp->old_rc_default = NULL;
8972                         rv = BAM_WRITE;
8973                         BAM_DPRINTF((D_GET_SET_KERNEL_RESTORE_DEFAULT, fcn));
8974                         goto done;
8975                 }
8976 
8977                 if (optnum == KERNEL_CMD) {
8978                         /*
8979                          * At this point, we've already checked that old_args
8980                          * and entryp are valid pointers.  The "+ 2" is for
8981                          * a space a the string termination character.
8982                          */
8983                         new_str_len = (sizeof (DIRECT_BOOT_KERNEL) - 1) +
8984                             strlen(old_args) + 2;
8985                         new_arg = s_calloc(1, new_str_len);
8986                         (void) snprintf(new_arg, new_str_len, "%s",
8987                             DIRECT_BOOT_KERNEL);
8988                         free(kernelp->arg);
8989                         kernelp->arg = new_arg;
8990 
8991                         /*
8992                          * We have changed the kernel line, so we may need
8993                          * to update the archive line as well.
8994                          */
8995                         set_archive_line(entryp, kernelp);
8996                         BAM_DPRINTF((D_GET_SET_KERNEL_RESET_KERNEL_SET_ARG,
8997                             fcn, kernelp->arg));
8998                 } else {
8999                         /*
9000                          * We're resetting the boot args to nothing, so
9001                          * we only need to copy the kernel.  We've already
9002                          * checked that the kernel is not the default.
9003                          */
9004                         new_arg = s_calloc(1, old_kernel_len + 1);
9005                         (void) snprintf(new_arg, old_kernel_len + 1, "%s",
9006                             kernelp->arg);
9007                         free(kernelp->arg);


9128 
9129         /*
9130          * There was already an bootenv entry which we need to edit.
9131          */
9132         if (optnum == KERNEL_CMD) {
9133                 new_str_len = strlen(new_path) + strlen(old_args) + 2;
9134                 new_arg = s_calloc(1, new_str_len);
9135                 (void) snprintf(new_arg, new_str_len, "%s %s", new_path,
9136                     old_args);
9137                 free(kernelp->arg);
9138                 kernelp->arg = new_arg;
9139 
9140                 /*
9141                  * If we have changed the kernel line, we may need to update
9142                  * the archive line as well.
9143                  */
9144                 set_archive_line(entryp, kernelp);
9145                 BAM_DPRINTF((D_GET_SET_KERNEL_REPLACED_KERNEL_SAME_ARG, fcn,
9146                     kernelp->arg));
9147         } else {
9148                 kernelp = kernelp->next;
9149                 new_str_len = strlen(kernelp->arg) + strlen(path) + 8;
9150                 new_arg = s_calloc(1, new_str_len);
9151                 (void) strncpy(new_arg, kernelp->arg, strlen(kernelp->arg));
9152                 (void) strlcat(new_arg, " ", new_str_len);
9153                 (void) strlcat(new_arg, path, new_str_len);
9154                 free(kernelp->arg);
9155                 kernelp->arg = new_arg;
9156                 BAM_DPRINTF((D_GET_SET_KERNEL_SAME_KERNEL_REPLACED_ARG, fcn,
9157                     kernelp->arg));
9158         }
9159         rv = BAM_WRITE;
9160 
9161 done:
9162         if ((rv == BAM_WRITE) && kernelp)
9163                 update_line(kernelp);
9164         if (free_new_path)
9165                 free(new_path);
9166         if (rv == BAM_WRITE) {
9167                 BAM_DPRINTF((D_RETURN_SUCCESS, fcn));
9168         } else {
9169                 BAM_DPRINTF((D_RETURN_FAILURE, fcn));
9170         }
9171         return (rv);