Fetch the repository succeeded.
This action will force synchronization from src-anolis-os/grub2, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
Date: Tue, 27 Nov 2012 17:22:07 -0200
Subject: [PATCH] Search for specific config file for netboot
This patch implements a search for a specific configuration when the config
file is on a remoteserver. It uses the following order:
1) DHCP client UUID option.
2) MAC address (in lower case hexadecimal with dash separators);
3) IP (in upper case hexadecimal) or IPv6;
4) The original grub.cfg file.
This procedure is similar to what is used by pxelinux and yaboot:
http://www.syslinux.org/wiki/index.php/PXELINUX#config
This should close the bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=873406
---
grub-core/net/net.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
grub-core/normal/main.c | 18 ++++++--
include/grub/net.h | 3 ++
3 files changed, 135 insertions(+), 4 deletions(-)
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 10773fc34..0769bf850 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -1735,6 +1735,124 @@ grub_net_restore_hw (void)
return GRUB_ERR_NONE;
}
+grub_err_t
+grub_net_search_configfile (char *config)
+{
+ grub_size_t config_len;
+ char *suffix;
+
+ auto int search_through (grub_size_t num_tries, grub_size_t slice_size);
+ int search_through (grub_size_t num_tries, grub_size_t slice_size)
+ {
+ while (num_tries-- > 0)
+ {
+ grub_dprintf ("net", "probe %s\n", config);
+
+ grub_file_t file;
+ file = grub_file_open (config);
+
+ if (file)
+ {
+ grub_file_close (file);
+ grub_dprintf ("net", "found!\n");
+ return 0;
+ }
+ else
+ {
+ if (grub_errno == GRUB_ERR_IO)
+ grub_errno = GRUB_ERR_NONE;
+ }
+
+ if (grub_strlen (suffix) < slice_size)
+ break;
+
+ config[grub_strlen (config) - slice_size] = '\0';
+ }
+
+ return 1;
+ }
+
+ config_len = grub_strlen (config);
+ config[config_len] = '-';
+ suffix = config + config_len + 1;
+
+ struct grub_net_network_level_interface *inf;
+ FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
+ {
+ /* By the Client UUID. */
+
+ char client_uuid_var[sizeof ("net_") + grub_strlen (inf->name) +
+ sizeof ("_clientuuid") + 1];
+ grub_snprintf (client_uuid_var, sizeof (client_uuid_var),
+ "net_%s_clientuuid", inf->name);
+
+ const char *client_uuid;
+ client_uuid = grub_env_get (client_uuid_var);
+
+ if (client_uuid)
+ {
+ grub_strcpy (suffix, client_uuid);
+ if (search_through (1, 0) == 0) return GRUB_ERR_NONE;
+ }
+
+ /* By the MAC address. */
+
+ /* Add ethernet type */
+ grub_strcpy (suffix, "01-");
+
+ grub_net_hwaddr_to_str (&inf->hwaddress, suffix + 3);
+
+ char *ptr;
+ for (ptr = suffix; *ptr; ptr++)
+ if (*ptr == ':')
+ *ptr = '-';
+
+ if (search_through (1, 0) == 0) return GRUB_ERR_NONE;
+
+ /* By IP address */
+
+ switch ((&inf->address)->type)
+ {
+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4:
+ {
+ grub_uint32_t n = grub_be_to_cpu32 ((&inf->address)->ipv4);
+ grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%02X%02X%02X%02X", \
+ ((n >> 24) & 0xff), ((n >> 16) & 0xff), \
+ ((n >> 8) & 0xff), ((n >> 0) & 0xff));
+
+ if (search_through (8, 1) == 0) return GRUB_ERR_NONE;
+ break;
+ }
+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6:
+ {
+ char buf[GRUB_NET_MAX_STR_ADDR_LEN];
+ struct grub_net_network_level_address base;
+ base.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
+ grub_memcpy (&base.ipv6, ((&inf->address)->ipv6), 16);
+ grub_net_addr_to_str (&base, buf);
+
+ for (ptr = buf; *ptr; ptr++)
+ if (*ptr == ':')
+ *ptr = '-';
+
+ grub_snprintf (suffix, GRUB_NET_MAX_STR_ADDR_LEN, "%s", buf);
+ if (search_through (1, 0) == 0) return GRUB_ERR_NONE;
+ break;
+ }
+ case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV:
+ return grub_error (GRUB_ERR_BUG, "shouldn't reach here");
+ default:
+ return grub_error (GRUB_ERR_BUG,
+ "unsupported address type %d", (&inf->address)->type);
+ }
+ }
+
+ /* Remove the remaining minus sign at the end. */
+ config[config_len] = '\0';
+
+ return GRUB_ERR_NONE;
+}
+
static struct grub_preboot *fini_hnd;
static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute;
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index 759c475c4..b2654ef62 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -33,6 +33,7 @@
#include <grub/charset.h>
#include <grub/script_sh.h>
#include <grub/bufio.h>
+#include <grub/net.h>
#ifdef GRUB_MACHINE_IEEE1275
#include <grub/ieee1275/ieee1275.h>
#endif
@@ -365,10 +366,19 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
prefix = grub_env_get ("prefix");
if (prefix)
- {
- config = grub_xasprintf ("%s/grub.cfg", prefix);
- if (! config)
- goto quit;
+ {
+ grub_size_t config_len;
+ config_len = grub_strlen (prefix) +
+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX");
+ config = grub_malloc (config_len);
+
+ if (! config)
+ goto quit;
+
+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix);
+
+ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0)
+ grub_net_search_configfile (config);
grub_enter_normal_mode (config);
grub_free (config);
diff --git a/include/grub/net.h b/include/grub/net.h
index e266bae23..50d62ab0c 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -566,4 +566,7 @@ extern char *grub_net_default_server;
#define VLANTAG_IDENTIFIER 0x8100
+grub_err_t
+grub_net_search_configfile (char *config);
+
#endif /* ! GRUB_NET_HEADER */
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。