bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 3/4] Search for specific config file for netboot


From: Vladimir 'φ-coder/phcoder' Serbinenko
Subject: Re: [PATCH 3/4] Search for specific config file for netboot
Date: Wed, 22 Jan 2014 15:47:42 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.2.0

On 20.01.2014 22:32, Lubomir Rintel wrote:
> From: Paulo Flabiano Smorigo <address@hidden>
> 
> 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
> 
This should be done by constructions like
if [ -s "$prefix/grub.cfg.$net_default_mac" ]; then
        source "$prefix/grub.cfg.$net_default_mac"
fi
not by modifying source
> Link: http://www.syslinux.org/wiki/index.php/PXELINUX#config
> Link: https://bugzilla.redhat.com/show_bug.cgi?id=873406
> 
> address@hidden: Add Changelog]
> ---
>  ChangeLog               |   8 ++++
>  grub-core/net/net.c     | 118 
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  grub-core/normal/main.c |  18 ++++++--
>  include/grub/net.h      |   3 ++
>  4 files changed, 143 insertions(+), 4 deletions(-)
> 
> diff --git a/ChangeLog b/ChangeLog
> index f74f9a4..f877a2a 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,5 +1,13 @@
>  2014-01-20  Paulo Flabiano Smorigo  <address@hidden>
>  
> +     * grub-core/net/net.c (grub_net_search_configfile): Add.
> +     * grub-core/normal/main.c: Include grub/net.h.
> +     * (grub_cmd_normal): Call grub_net_search_configfile() to look up
> +     configuration file name if loaded via tftp.
> +     * include/grub/net.h: Add grub_net_search_configfile() prototype.
> +
> +2014-01-20  Gustavo Luiz Duarte  <address@hidden>
> +
>       * grub-core/net/bootp.c (hexdigit): Move.
>       * (parse_dhcp_vendor): Grok GRUB_NET_BOOTP_CLIENT_ID and
>       GRUB_NET_BOOTP_CLIENT_UUID.
> diff --git a/grub-core/net/net.c b/grub-core/net/net.c
> index 0e57e93..f1eefe0 100644
> --- a/grub-core/net/net.c
> +++ b/grub-core/net/net.c
> @@ -1663,6 +1663,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 3a926fc..a90cc38 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>
>  
>  GRUB_MOD_LICENSE ("GPLv3+");
>  
> @@ -323,10 +324,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 64e2125..6a1156b 100644
> --- a/include/grub/net.h
> +++ b/include/grub/net.h
> @@ -535,4 +535,7 @@ extern char *grub_net_default_server;
>  #define GRUB_NET_TRIES 40
>  #define GRUB_NET_INTERVAL 400
>  
> +grub_err_t
> +grub_net_search_configfile (char *config);
> +
>  #endif /* ! GRUB_NET_HEADER */
> 


Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]