Print this page
botadm patch

@@ -19,10 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2012 Daniil Lunev. All rights reserved.
  */
 
 /*
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  */

@@ -116,12 +117,12 @@
 #define ENTRY_INIT      -1      /* entryNum initial value */
 #define ALL_ENTRIES     -2      /* selects all boot entries */
 
 #define GRUB_DIR                "/boot/grub"
 #define GRUB_STAGE2             GRUB_DIR "/stage2"
-#define GRUB_MENU               "/boot/grub/menu.lst"
-#define MENU_TMP                "/boot/grub/menu.lst.tmp"
+#define GRUB_MENU               "/boot/illumos.cfg"
+#define MENU_TMP                "/boot/illumos.cfg.tmp"
 #define GRUB_BACKUP_MENU        "/etc/lu/GRUB_backup_menu"
 #define RAMDISK_SPECIAL         "/ramdisk"
 #define STUBBOOT                "/stubboot"
 #define MULTIBOOT               "/platform/i86pc/multiboot"
 #define GRUBSIGN_DIR            "/boot/grub/bootsign"

@@ -176,24 +177,25 @@
 /*
  * Menu related
  * menu_cmd_t and menu_cmds must be kept in sync
  */
 char *menu_cmds[] = {
-        "default",      /* DEFAULT_CMD */
+        "default_entry",/* DEFAULT_CMD */
         "timeout",      /* TIMEOUT_CMD */
-        "title",        /* TITLE_CMD */
-        "root",         /* ROOT_CMD */
-        "kernel",       /* KERNEL_CMD */
-        "kernel$",      /* KERNEL_DOLLAR_CMD */
-        "module",       /* MODULE_CMD */
-        "module$",      /* MODULE_DOLLAR_CMD */
-        " ",            /* SEP_CMD */
+        "entry_name",   /* TITLE_CMD */
+        "pool_uuid",    /* ROOT_CMD */
+        "kernel_path$", /* KERNEL_CMD */
+        "kernel_path",  /* KERNEL_DOLLAR_CMD */
+        "module$",      /* MODULE_CMD */
+        "module",       /* MODULE_DOLLAR_CMD */
+        "=",            /* SEP_CMD */
         "#",            /* COMMENT_CMD */
         "chainloader",  /* CHAINLOADER_CMD */
         "args",         /* ARGS_CMD */
-        "findroot",     /* FINDROOT_CMD */
-        "bootfs",       /* BOOTFS_CMD */
+        "pool_label",   /* FINDROOT_CMD */
+        "data_set",     /* BOOTFS_CMD */
+        "kernel_options",/* KERNEL_OPTIONS_CMD */
         NULL
 };
 
 #define OPT_ENTRY_NUM   "entry"
 

@@ -4688,10 +4690,11 @@
         int             entryNum;
         char            linebuf[BAM_MAXLINE];
         menu_cmd_t      k_cmd;
         menu_cmd_t      m_cmd;
         const char      *fcn = "add_boot_entry()";
+        char * options = NULL;
 
         assert(mp);
 
         INJECT_ERROR1("ADD_BOOT_ENTRY_FINDROOT_NULL", findroot = NULL);
         if (findroot == NULL) {

@@ -4754,13 +4757,24 @@
                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
                     menu_cmds[BOOTFS_CMD], menu_cmds[SEP_CMD], bootfs);
                 line_parser(mp, linebuf, &lineNum, &entryNum);
         }
 
+        options = strpbrk(kernel, " \t");
+        if (options)
+                ++options;
+
+        (void) snprintf(linebuf, sizeof (linebuf), "%s%s",
+            menu_cmds[k_cmd], menu_cmds[SEP_CMD]);
+        (void) strncat(linebuf, kernel, options - kernel);
+        line_parser(mp, linebuf, &lineNum, &entryNum);
+
+        if (options) {
         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
-            menu_cmds[k_cmd], menu_cmds[SEP_CMD], kernel);
+                    menu_cmds[KERNEL_OPTIONS_CMD], menu_cmds[SEP_CMD], options);
         line_parser(mp, linebuf, &lineNum, &entryNum);
+        }
 
         if (mod_kernel != NULL) {
                 (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
                     menu_cmds[m_cmd], menu_cmds[SEP_CMD], mod_kernel);
                 line_parser(mp, linebuf, &lineNum, &entryNum);

@@ -7110,22 +7124,23 @@
         }
 
         slice = strrchr(osdev, 's');
 
         grubsign = s_calloc(1, MAXNAMELEN + 10);
-        if (slice) {
+/*      if (slice) {
                 (void) snprintf(grubsign, MAXNAMELEN + 10, "(%s,%d,%c)",
                     sign, fdiskpart, slice[1] + 'a' - '0');
         } else
                 (void) snprintf(grubsign, MAXNAMELEN + 10, "(%s,%d)",
-                    sign, fdiskpart);
+                    sign, fdiskpart);*/
+        grubsign = strdup(sign);
 
         free(sign);
 
         BAM_DPRINTF((D_GET_GRUBSIGN_SUCCESS, fcn, grubsign));
 
-        return (grubsign);
+        return (strchr(grubsign,'_') + 1);
 }
 
 static char *
 get_title(char *rootdir)
 {

@@ -7810,11 +7825,11 @@
                                 BAM_DPRINTF((D_NOMATCH_FINDROOT_NULL,
                                     fcn, lp->arg));
                                 continue;
                         }
                         /* findroot command found, try match  */
-                        if (strcmp(lp->arg, findroot) != 0) {
+                        if (strncmp(lp->arg, strchr(findroot, '_') + 1, strlen(lp->arg)) != 0) {
                                 BAM_DPRINTF((D_NOMATCH_FINDROOT,
                                     fcn, findroot, lp->arg));
                                 continue;
                         }
                         BAM_DPRINTF((D_MATCHED_FINDROOT, fcn, findroot));

@@ -7868,10 +7883,11 @@
                  * Check for matching module entry (failsafe or normal).
                  * If it fails to match, we go around the loop again.
                  * For xpv entries, there are two module lines, so we
                  * do the check twice.
                  */
+                lp = lp->next;  /* advance to options line */
                 lp = lp->next;  /* advance to module line */
                 if (check_cmd(lp->cmd, MODULE_CMD, lp->arg, module) ||
                     (((lp = lp->next) != NULL) &&
                     check_cmd(lp->cmd, MODULE_CMD, lp->arg, module))) {
                         /* match found */

@@ -7909,10 +7925,11 @@
         entry_t         *ent;
         line_t          *lp;
         line_t          *tlp;
         char            linebuf[BAM_MAXLINE];
         const char      *fcn = "update_boot_entry()";
+        char            *label;
 
         /* note: don't match on title, it's updated on upgrade */
         ent = find_boot_entry(mp, NULL, kernel, findroot, root, module,
             root_opt, &i);
         if ((ent == NULL) && (bam_direct == BAM_DIRECT_DBOOT)) {

@@ -7965,28 +7982,28 @@
                 free(lp->line);
         }
 
         lp->cmd = s_strdup(menu_cmds[FINDROOT_CMD]);
         lp->sep = s_strdup(menu_cmds[SEP_CMD]);
-        lp->arg = s_strdup(findroot);
+        label = s_strdup(strchr(findroot, '_') + 1);
+        *(strchr(label,',')) = 0;
+        lp->arg = s_strdup(label);
         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
-            menu_cmds[FINDROOT_CMD], menu_cmds[SEP_CMD], findroot);
+            menu_cmds[FINDROOT_CMD], menu_cmds[SEP_CMD], label);
         lp->line = s_strdup(linebuf);
+        free(label);
         BAM_DPRINTF((D_ADDING_FINDROOT_LINE, fcn, findroot));
 
         /* kernel line */
         lp = lp->next;
 
         if (ent->flags & BAM_ENTRY_UPGFSKERNEL) {
                 char            *params = NULL;
+                char            *opts = NULL;
 
-                params = strstr(lp->line, "-s");
-                if (params != NULL)
-                        (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s%s",
-                            menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
-                            kernel, params+2);
-                else
+                opts = strpbrk(kernel, " \t");
+                *opts++ = '\0';
                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
                             menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
                             kernel);
 
                 if (lp->cmd != NULL)

@@ -7997,16 +8014,32 @@
                 lp->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]);
                 lp->arg = s_strdup(strstr(linebuf, "/"));
                 lp->line = s_strdup(linebuf);
                 ent->flags &= ~BAM_ENTRY_UPGFSKERNEL;
                 BAM_DPRINTF((D_ADDING_KERNEL_DOLLAR, fcn, lp->prev->cmd));
+
+                lp = lp->next;
+                params = strstr(lp->arg, "-s");
+                free(lp->arg);
+                free(lp->line);
+                if (params)
+                        (void) snprintf(linebuf, sizeof(linebuf), "%s%s%s -s",
+                                lp->cmd, menu_cmds[SEP_CMD],opts);
+                else
+                        (void) snprintf(linebuf, sizeof(linebuf), "%s%s%s",
+                                lp->cmd, menu_cmds[SEP_CMD],opts);
+                lp->line = s_strdup(linebuf);
+                lp->arg = s_strdup(strchr(linebuf, '=') + 1);
         }
 
         if (change_kernel) {
+                char            *opts = NULL;
                 /*
                  * We're upgrading from multiboot to directboot.
                  */
+                opts = strpbrk(kernel, " \t");
+                *opts++ = '\0';
                 if (lp->cmd != NULL &&
                     strcmp(lp->cmd, menu_cmds[KERNEL_CMD]) == 0) {
                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
                             menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD],
                             kernel);

@@ -8016,10 +8049,16 @@
                         lp->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]);
                         lp->arg = s_strdup(kernel);
                         lp->line = s_strdup(linebuf);
                         lp = lp->next;
                         BAM_DPRINTF((D_ADDING_KERNEL_DOLLAR, fcn, kernel));
+                        (void) snprintf(linebuf, sizeof(linebuf), "%s%s%s",
+                                lp->cmd, menu_cmds[SEP_CMD],opts);
+                        free(lp->arg);
+                        free(lp->line);
+                        lp->line = s_strdup(linebuf);
+                        lp->arg = s_strdup(strchr(linebuf, '=') + 1);
                 }
                 if (lp->cmd != NULL &&
                     strcmp(lp->cmd, menu_cmds[MODULE_CMD]) == 0) {
                         (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s",
                             menu_cmds[MODULE_DOLLAR_CMD], menu_cmds[SEP_CMD],

@@ -8408,10 +8447,11 @@
                 bam_error(REBOOT_SPECIAL_FAILED);
                 return (BAM_ERROR);
         }
 
         sign = find_existing_sign("/", osdev, fstype);
+        sign = strchr(sign, '_') + 1;
         INJECT_ERROR1("REBOOT_SIGN_NULL", sign = NULL);
         if (sign == NULL) {
                 free(fstype);
                 free(osdev);
                 bam_error(REBOOT_SIGN_FAILED);

@@ -8856,11 +8896,11 @@
 
         if (entryp != NULL) {
                 for (ptr = entryp->start; ptr && ptr != entryp->end;
                     ptr = ptr->next) {
                         if (strncmp(ptr->cmd, menu_cmds[KERNEL_CMD],
-                            sizeof (menu_cmds[KERNEL_CMD]) - 1) == 0) {
+                            sizeof (menu_cmds[KERNEL_CMD]) - 2) == 0) {
                                 kernelp = ptr;
                                 break;
                         }
                 }
                 if (kernelp == NULL) {

@@ -8944,12 +8984,12 @@
                          * a space a the string termination character.
                          */
                         new_str_len = (sizeof (DIRECT_BOOT_KERNEL) - 1) +
                             strlen(old_args) + 2;
                         new_arg = s_calloc(1, new_str_len);
-                        (void) snprintf(new_arg, new_str_len, "%s %s",
-                            DIRECT_BOOT_KERNEL, old_args);
+                        (void) snprintf(new_arg, new_str_len, "%s",
+                            DIRECT_BOOT_KERNEL);
                         free(kernelp->arg);
                         kernelp->arg = new_arg;
 
                         /*
                          * We have changed the kernel line, so we may need

@@ -9106,13 +9146,14 @@
                  */
                 set_archive_line(entryp, kernelp);
                 BAM_DPRINTF((D_GET_SET_KERNEL_REPLACED_KERNEL_SAME_ARG, fcn,
                     kernelp->arg));
         } else {
-                new_str_len = old_kernel_len + strlen(path) + 8;
+                kernelp = kernelp->next;
+                new_str_len = strlen(kernelp->arg) + strlen(path) + 8;
                 new_arg = s_calloc(1, new_str_len);
-                (void) strncpy(new_arg, kernelp->arg, old_kernel_len);
+                (void) strncpy(new_arg, kernelp->arg, strlen(kernelp->arg));
                 (void) strlcat(new_arg, " ", new_str_len);
                 (void) strlcat(new_arg, path, new_str_len);
                 free(kernelp->arg);
                 kernelp->arg = new_arg;
                 BAM_DPRINTF((D_GET_SET_KERNEL_SAME_KERNEL_REPLACED_ARG, fcn,