[gPXE-devel] [PATCH] [dhcp] Allow multiple interfaces in dhcp command

Stefan Hajnoczi stefanha at gmail.com
Sat Jul 31 13:13:56 EDT 2010


On Sat, Jul 31, 2010 at 4:43 PM, Lars Kellogg-Stedman <lars at oddbit.com> wrote:
>> Looks good.  I would like to merge this commit.
>>
>> Lars, can you please provide your Signed-off-by line (i.e. Signed-off-by: Lars
>> Kellogg-Stedman <lars at oddbit.com>)?
>
> Sure.  I've added it to the text of your message; let me know if this
> isn't the right procedure:

Yes, this is fine thanks!

Stefan

> From: Lars Kellogg-Stedman <lars at oddbit.com>
>
> The "dhcp" command now accepts a list of interfaces and to try until one
> succeeds:
>
>  gPXE> dhcp net0 net1 net2
>
> If an interface does not exist a message is printed and it is skipped.
>
> If given the single parameter "any" as an interface name, all interfaces
> are tried in a manner similar to autoboot:
>
>  gPXE> dhcp any
>  DHCP (net0 xx:xx:xx:xx:xx:xx)........ Connection timed out (...)
>  Could not configure net0: Connection timed out (...)
>  DHCP (net1 xx:xx:xx:xx:xx:xx).... ok
>  gPXE>
>
> Note that interfaces which fail to DHCP are closed.  This is usually
> desirable since an open interface consumes memory.  On machines with
> several interfaces it is possible to exhaust the heap if all interfaces
> are open simultaneously.  This behavior differs from the previous "dhcp"
> command implementation but should not be detectable to user scripts
> since they abort when the dhcp command exits with an error.
>
> Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
> Signed-off-by: Lars Kellogg-Stedman <lars at oddbit.com>
> ---
>
>  src/hci/commands/dhcp_cmd.c |   99 +++++++++++++++++++++++++++++++++----------
>  1 files changed, 77 insertions(+), 22 deletions(-)
>
> diff --git a/src/hci/commands/dhcp_cmd.c b/src/hci/commands/dhcp_cmd.c
> index 96aac8d..6f0a99f 100644
> --- a/src/hci/commands/dhcp_cmd.c
> +++ b/src/hci/commands/dhcp_cmd.c
> @@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
>  #include <gpxe/in.h>
>  #include <gpxe/command.h>
>  #include <usr/dhcpmgmt.h>
> +#include <usr/ifmgmt.h>
>
>  /** @file
>  *
> @@ -45,10 +46,79 @@ FILE_LICENCE ( GPL2_OR_LATER );
>  */
>  static void dhcp_syntax ( char **argv ) {
>        printf ( "Usage:\n"
> -                "  %s <interface>\n"
> +                "  %s <interface> [<interface> ...]\n"
> +                "  %s any\n"
>                 "\n"
>                 "Configure a network interface using DHCP\n",
> -                argv[0] );
> +                argv[0], argv[0] );
> +}
> +
> +/**
> + * Attempt to configure a device with dhcp
> + *
> + * @v netdev           Device to configure
> + * @ret rc             Exit code
> + */
> +static int dhcp_one_device ( struct net_device *netdev ) {
> +       int rc;
> +
> +       /* Perform DHCP */
> +       if ( ( rc = dhcp ( netdev ) ) != 0 ) {
> +               /* Close the device on error to avoid out-of-memory */
> +               netdev_close ( netdev );
> +
> +               printf ( "Could not configure %s: %s\n", netdev->name,
> +                        strerror ( rc ) );
> +               return 1;
> +       }
> +
> +       return 0;
> +}
> +
> +/**
> + * Call dhcp_one_device() for each name in argv
> + *
> + * @v argc             Number of devices
> + * @v argv             List of device names
> + * @ret rc             Exit code
> + */
> +static int dhcp_each_device_name ( int argc, char **argv ) {
> +       int i;
> +       char *netdev_name;
> +       struct net_device *netdev;
> +
> +       for ( i = 0; i < argc; i++ ) {
> +               netdev_name = argv[i];
> +               netdev = find_netdev ( netdev_name );
> +
> +               if ( ! netdev ) {
> +                       printf ( "No such interface: %s\n", netdev_name );
> +                       continue;
> +               }
> +
> +               if ( dhcp_one_device ( netdev ) == 0 )
> +                       return 0;
> +       }
> +
> +       printf ( "Could not configure any interface.\n" );
> +       return 1;
> +}
> +
> +/**
> + * Call dhcp_one_device() for each device in net_devices
> + *
> + * @ret rc             Exit code
> + */
> +static int dhcp_each_device ( void ) {
> +       struct net_device *netdev;
> +
> +       for_each_netdev ( netdev ) {
> +               if ( dhcp_one_device ( netdev ) == 0 )
> +                       return 0;
> +       }
> +
> +       printf ( "Could not configure any interface.\n" );
> +       return 1;
>  }
>
>  /**
> @@ -63,10 +133,7 @@ static int dhcp_exec ( int argc, char **argv ) {
>                { "help", 0, NULL, 'h' },
>                { NULL, 0, NULL, 0 },
>        };
> -       const char *netdev_txt;
> -       struct net_device *netdev;
>        int c;
> -       int rc;
>
>        /* Parse options */
>        while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
> @@ -80,28 +147,16 @@ static int dhcp_exec ( int argc, char **argv ) {
>                }
>        }
>
> -       /* Need exactly one interface name remaining after the options */
> -       if ( optind != ( argc - 1 ) ) {
> +       /* Need one or more interface names remaining after the options */
> +       if ( ( argc - optind ) < 1 ) {
>                dhcp_syntax ( argv );
>                return 1;
>        }
> -       netdev_txt = argv[optind];
>
> -       /* Parse arguments */
> -       netdev = find_netdev ( netdev_txt );
> -       if ( ! netdev ) {
> -               printf ( "No such interface: %s\n", netdev_txt );
> -               return 1;
> -       }
> -
> -       /* Perform DHCP */
> -       if ( ( rc = dhcp ( netdev ) ) != 0 ) {
> -               printf ( "Could not configure %s: %s\n", netdev->name,
> -                        strerror ( rc ) );
> -               return 1;
> -       }
> +       if ( strcmp ( argv[optind], "any" ) == 0 )
> +               return dhcp_each_device();
>
> -       return 0;
> +       return dhcp_each_device_name ( argc - optind, argv + optind );
>  }
>
>  /**
> --
> 1.7.1
>
>


More information about the gPXE-devel mailing list