Mercurial > illumos > illumos-gate
changeset 9037:6ea398b88b25
6816519 pxegrub: infer configfile from bootfile to reduce reliance on site option 150
author | Jan Setje-Eilers <Jan.Setje-Eilers@Sun.COM> |
---|---|
date | Fri, 13 Mar 2009 17:58:24 -0700 |
parents | 49811247ffb0 |
children | b9402db13c0f |
files | usr/src/grub/grub-0.97/netboot/nic.c usr/src/grub/grub-0.97/stage2/builtins.c usr/src/grub/grub-0.97/stage2/shared.h |
diffstat | 3 files changed, 132 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/grub/grub-0.97/netboot/nic.c Fri Mar 13 16:23:41 2009 -0700 +++ b/usr/src/grub/grub-0.97/netboot/nic.c Fri Mar 13 17:58:24 2009 -0700 @@ -99,6 +99,11 @@ int vci_etherboot; #endif +char *bootfile = NULL; +configfile_origin_t configfile_origin = CFG_HARDCODED; +char *vendor_configfile = NULL; +char vendor_configfile_len; + static void update_network_configuration(void); static int dummy(void *unused __unused) @@ -558,7 +563,7 @@ memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */ arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr; memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */ - /* We don't care bootpreply->bp_file, it must be 'pxegrub':-) */ + bootfile = bootpreply->bp_file; memcpy((char *)rfc1533_venddata, (char *)(bootpreply->bp_vend), len); decode_rfc1533(rfc1533_venddata, 0, len, 1); return(1); @@ -648,7 +653,6 @@ dhcpack_length = len + sizeof (struct dhcp_t) - DHCP_OPT_LEN; memcpy((char *)dhcpack_buf, (char *)dhcpreply, dhcpack_length); #endif - arptable[ARP_CLIENT].ipaddr.s_addr = dhcpreply->bp_yiaddr.s_addr; dhcp_addr.s_addr = dhcpreply->bp_yiaddr.s_addr; netmask = default_netmask(); @@ -656,7 +660,7 @@ memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */ arptable[ARP_GATEWAY].ipaddr.s_addr = dhcpreply->bp_giaddr.s_addr; memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */ - /* We don't care bootpreply->bp_file. It must be 'pxegrub' */ + bootfile = dhcpreply->bp_file; memcpy((char *)rfc1533_venddata, (char *)(dhcpreply->bp_vend), len); decode_rfc1533(rfc1533_venddata, 0, len, 1); return(1); @@ -1096,6 +1100,9 @@ in GRUB 1.0. */ memcpy (config_file, p + 2, l); config_file[l] = 0; + vendor_configfile = p + 2; + vendor_configfile_len = l; + configfile_origin = CFG_150; } else { ; @@ -1211,10 +1218,52 @@ if (! network_ready) grub_printf ("Network interface not initialized yet.\n"); else { + if (hostnamelen == 0) + etherboot_printf ("Hostname: not set\n"); + else + etherboot_printf ("Hostname: %s\n", hostname); + etherboot_printf ("Address: %@\n", arptable[ARP_CLIENT].ipaddr.s_addr); etherboot_printf ("Netmask: %@\n", netmask); + etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr); etherboot_printf ("Server: %@\n", arptable[ARP_SERVER].ipaddr.s_addr); - etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr); + if (vendor_configfile == NULL) { + etherboot_printf ("Site Option 150: not set\n"); + } else { + /* + * vendor_configfile points into the packet and + * is not NULL terminated, so it needs to be + * patched up before printing it out + */ + char c = vendor_configfile[vendor_configfile_len]; + vendor_configfile[vendor_configfile_len] = '\0'; + etherboot_printf ("Site Option 150: %s\n", + vendor_configfile); + vendor_configfile[vendor_configfile_len] = c; + } + + if (bootfile == NULL) + etherboot_printf ("BootFile: not set\n"); + else + etherboot_printf ("BootFile: %s\n", bootfile); + + etherboot_printf ("GRUB menu file: %s", config_file); + switch (configfile_origin) { + case CFG_HARDCODED: + etherboot_printf (" from hardcoded default\n"); + break; + case CFG_150: + etherboot_printf (" from Site Option 150\n"); + break; + case CFG_MAC: + etherboot_printf (" inferred from system MAC\n"); + break; + case CFG_BOOTFILE: + etherboot_printf (" inferred from BootFile\n"); + break; + default: + etherboot_printf ("\n"); + } } LeaveFunction("print_network_configuration"); } @@ -1293,7 +1342,7 @@ memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */ arptable[ARP_GATEWAY].ipaddr.s_addr = dhcpreply->bp_giaddr.s_addr; memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */ - /* We don't care bootpreply->bp_file. It must be 'pxegrub' */ + bootfile = dhcpreply->bp_file; memcpy((char *)rfc1533_venddata, (char *)(dhcpreply->bp_vend), len); decode_rfc1533(rfc1533_venddata, 0, len, 1); }
--- a/usr/src/grub/grub-0.97/stage2/builtins.c Fri Mar 13 16:23:41 2009 -0700 +++ b/usr/src/grub/grub-0.97/stage2/builtins.c Fri Mar 13 17:58:24 2009 -0700 @@ -944,28 +944,11 @@ return 0; } -static void solaris_config_file (void) +static int +test_config_file(char *menufile) { - static char menufile[64]; - static char hexdigit[] = "0123456789ABCDEF"; - char *c = menufile; - int i; int err; - /* if config_file is from DHCP option 150, keep the setting */ - if (grub_strcmp(config_file, "/boot/grub/menu.lst") != 0) - return; - - /* default solaris configfile name menu.lst.01<ether_addr> */ - grub_strcpy(c, "menu.lst.01"); - c += grub_strlen(c); - for (i = 0; i < ETH_ALEN; i++) { - unsigned char b = arptable[ARP_CLIENT].node[i]; - *c++ = hexdigit[b >> 4]; - *c++ = hexdigit[b & 0xf]; - } - *c = 0; - /* * If the file exists, make it the default. Else, fallback * to what it was. Make sure we don't change errnum in the @@ -975,14 +958,74 @@ if (grub_open(menufile)) { grub_strcpy(config_file, menufile); grub_close(); - } else { - char *cp = config_file; - /* skip leading slashes for tftp */ - while (*cp == '/') - ++cp; - grub_memmove (config_file, cp, strlen(cp) + 1); + errnum = err; + return (1); } errnum = err; + return (0); +} + +static void solaris_config_file (void) +{ + static char menufile[64]; + static char hexdigit[] = "0123456789ABCDEF"; + char *c = menufile; + int i; + + /* + * if DHCP option 150 has been provided, config_file will + * already contain the string, try it. + */ + if (configfile_origin == CFG_150) { + if (test_config_file(config_file)) + return; + } + + /* + * try to find host (MAC address) specific configfile: + * menu.lst.01<ether_addr> + */ + grub_strcpy(c, "menu.lst.01"); + c += grub_strlen(c); + for (i = 0; i < ETH_ALEN; i++) { + unsigned char b = arptable[ARP_CLIENT].node[i]; + *c++ = hexdigit[b >> 4]; + *c++ = hexdigit[b & 0xf]; + } + *c = 0; + configfile_origin = CFG_MAC; + if (test_config_file(menufile)) + return; + + /* + * try to find a configfile derived from the DHCP/bootp + * BootFile string: menu.lst.<BootFile> + */ + if (bootfile != NULL && bootfile[0] != 0) { + c = menufile; + grub_strcpy(c, "menu.lst."); + c += grub_strlen("menu.lst."); + i = grub_strlen("pxegrub."); + if (grub_memcmp(bootfile, "pxegrub.", i) == 0) + grub_strcpy(c, bootfile + i); + else + grub_strcpy(c, bootfile); + configfile_origin = CFG_BOOTFILE; + if (test_config_file(menufile)) + return; + } + + /* + * Default to hard coded "/boot/grub/menu.lst" config file. + * This is the last resort, so there's no need to test it, + * as there's nothing else to try. + */ + char *cp = config_file; + /* skip leading slashes for tftp */ + while (*cp == '/') + ++cp; + grub_memmove (config_file, cp, strlen(cp) + 1); + configfile_origin = CFG_HARDCODED; } static struct builtin builtin_dhcp =
--- a/usr/src/grub/grub-0.97/stage2/shared.h Fri Mar 13 16:23:41 2009 -0700 +++ b/usr/src/grub/grub-0.97/stage2/shared.h Fri Mar 13 17:58:24 2009 -0700 @@ -587,6 +587,14 @@ MAX_ERR_NUM } grub_error_t; +typedef enum +{ + CFG_HARDCODED, + CFG_150, + CFG_MAC, + CFG_BOOTFILE +} configfile_origin_t; + extern unsigned long install_partition; extern unsigned long boot_drive; extern unsigned long install_second_sector; @@ -596,6 +604,8 @@ extern unsigned char force_lba; extern char version_string[]; extern char config_file[]; +extern char *bootfile; +extern configfile_origin_t configfile_origin; extern unsigned char md5hash[]; extern char pkg_version[]; extern unsigned long linux_text_len;