Mercurial > illumos > illumos-gate
changeset 4346:9468114ab29a
6551710 transient reboots don't properly update grub menu, take 2
6559511 eeprom forces update of boot archives, even when it shouldn't
author | rscott |
---|---|
date | Tue, 29 May 2007 16:00:54 -0700 |
parents | 20eb5d8abe27 |
children | 65fb0c27d51e |
files | usr/src/cmd/boot/bootadm/bootadm.c usr/src/cmd/boot/bootadm/message.h usr/src/cmd/eeprom/i386/benv.c |
diffstat | 3 files changed, 75 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/boot/bootadm/bootadm.c Tue May 29 15:54:57 2007 -0700 +++ b/usr/src/cmd/boot/bootadm/bootadm.c Tue May 29 16:00:54 2007 -0700 @@ -3460,7 +3460,7 @@ update_temp(menu_t *mp, char *menupath, char *opt) { int entry; - char *grubdisk, *rootdev, *path; + char *grubdisk, *rootdev, *path, *opt_ptr; char kernbuf[BUFSIZ]; char args_buf[BUFSIZ]; struct stat sb; @@ -3526,14 +3526,62 @@ (void) strlcat(kernbuf, " ", BUFSIZ); (void) strlcat(kernbuf, opt, BUFSIZ); } else if (opt[0] == '/') { - /* It's a full path - write it out and go home */ + /* It's a full path, so write it out. */ (void) strlcpy(kernbuf, opt, BUFSIZ); + + /* + * If someone runs: + * + * # eeprom boot-args='-kd' + * # reboot /platform/i86pc/kernel/unix + * + * we want to use the boot-args as part of the boot + * line. On the other hand, if someone runs: + * + * # reboot "/platform/i86pc/kernel/unix -kd" + * + * we don't need to mess with boot-args. If there's + * no space in the options string, assume we're in the + * first case. + */ + if (strchr(opt, ' ') == NULL) { + if (set_kernel(mp, ARGS_CMD, NULL, args_buf, + BUFSIZ) != BAM_SUCCESS) + return (BAM_ERROR); + + if (args_buf[0] != '\0') { + (void) strlcat(kernbuf, " ", BUFSIZ); + (void) strlcat(kernbuf, args_buf, + BUFSIZ); + } + } } else { + /* + * It may be a partial path, or it may be a partial + * path followed by options. Assume that only options + * follow a space. If someone sends us a kernel path + * that includes a space, they deserve to be broken. + */ + opt_ptr = strchr(opt, ' '); + if (opt_ptr != NULL) { + *opt_ptr = '\0'; + } + path = expand_path(opt); if (path != NULL) { (void) strlcpy(kernbuf, path, BUFSIZ); free(path); - if (strcmp(opt, "kmdb") == 0) { + + /* + * If there were options given, use those. + * Otherwise, copy over the default options. + */ + if (opt_ptr != NULL) { + /* Restore the space in opt string */ + *opt_ptr = ' '; + (void) strlcat(kernbuf, opt_ptr, + BUFSIZ); + } else { if (set_kernel(mp, ARGS_CMD, NULL, args_buf, BUFSIZ) != BAM_SUCCESS) return (BAM_ERROR); @@ -3545,6 +3593,10 @@ args_buf, BUFSIZ); } } + } else { + bam_error(UNKNOWN_KERNEL, opt); + bam_print_stderr(UNKNOWN_KERNEL_REBOOT); + return (BAM_ERROR); } } entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf, @@ -3643,14 +3695,15 @@ free(found->line); found->line = s_calloc(1, len); (void) snprintf(found->line, len, - "%s%s%s%d", prefix, globalcmd, menu_cmds[SEP_CMD], val); + "%s%s%s%d", prefix, globalcmd, menu_cmds[SEP_CMD], val); return (BAM_WRITE); /* need a write to menu */ } /* * partial_path may be anything like "kernel/unix" or "kmdb". Try to - * expand it to a full unix path. + * expand it to a full unix path. The calling function is expected to + * output a message if an error occurs and NULL is returned. */ static char * expand_path(const char *partial_path) @@ -3696,7 +3749,6 @@ return (new_path); } - bam_error(UNKNOWN_KERNEL, partial_path); free(new_path); return (NULL); } @@ -3919,6 +3971,7 @@ if ((optnum == KERNEL_CMD) && (path[0] != '/')) { new_path = expand_path(path); if (new_path == NULL) { + bam_error(UNKNOWN_KERNEL, path); return (BAM_ERROR); } free_new_path = 1;
--- a/usr/src/cmd/boot/bootadm/message.h Tue May 29 15:54:57 2007 -0700 +++ b/usr/src/cmd/boot/bootadm/message.h Tue May 29 16:00:54 2007 -0700 @@ -329,6 +329,9 @@ #define UNKNOWN_KERNEL gettext("Unable to expand %s to a full file path.\n") +#define UNKNOWN_KERNEL_REBOOT \ + gettext("Rebooting with default kernel and options.\n") + #define NOT_DBOOT \ gettext("bootadm set-menu %s may only be run on directboot kernels.\n")
--- a/usr/src/cmd/eeprom/i386/benv.c Tue May 29 15:54:57 2007 -0700 +++ b/usr/src/cmd/eeprom/i386/benv.c Tue May 29 16:00:54 2007 -0700 @@ -589,7 +589,10 @@ } } -static void +/* + * Returns 1 if bootenv.rc was modified, 0 otherwise. + */ +static int set_var(char *name, char *val, eplist_t *list) { benv_ent_t *p; @@ -598,7 +601,7 @@ if ((strcmp(name, "boot-file") == 0) || (strcmp(name, "boot-args") == 0)) { set_bootadm_var(name, val); - return; + return (0); } /* @@ -627,13 +630,14 @@ (void) printf("new:"); print_var(name, list); } + return (1); } /* - * Modified to return 1 if value modified or 0 if no modification - * was necessary. This allows us to implement non super-user - * look up of variables by name without the user being yelled at for - * trying to modify the bootenv.rc file. + * Returns 1 if bootenv.rc is modified or 0 if no modification was + * necessary. This allows us to implement non super-user look-up of + * variables by name without the user being yelled at for trying to + * modify the bootenv.rc file. */ static int proc_var(char *name, eplist_t *list) @@ -645,8 +649,7 @@ return (0); } else { *val++ = '\0'; - set_var(name, val, list); - return (1); + return (set_var(name, val, list)); } } @@ -994,12 +997,12 @@ if (name) { if (bent->val) { (void) fprintf(fp, "%s %s ", - bent->cmd, bent->name); + bent->cmd, bent->name); put_quoted(fp, bent->val); (void) fprintf(fp, "\n"); } else { (void) fprintf(fp, "%s %s\n", - bent->cmd, bent->name); + bent->cmd, bent->name); } } else { (void) fprintf(fp, "%s\n", bent->cmd);