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;