Delay IP autoconfiguration until network boot devices have been initialized. This depends on the boot device discovery code and on the asynchronous function call infrastructure. Signed-off-by: David VomLehn <dvomlehn@xxxxxxxxx> --- net/core/dev.c | 2 + net/ipv4/ipconfig.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 308a7d0..2796764 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -93,6 +93,7 @@ #include <linux/ethtool.h> #include <linux/notifier.h> #include <linux/skbuff.h> +#include <linux/device.h> #include <net/net_namespace.h> #include <net/sock.h> #include <linux/rtnetlink.h> @@ -4497,6 +4498,7 @@ int register_netdevice(struct net_device *dev) dev->reg_state = NETREG_UNREGISTERED; } + initdev_registered(INITDEV_NETDEV_TYPE); out: return ret; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 90d22ae..3b1a381 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -53,6 +53,7 @@ #include <linux/root_dev.h> #include <linux/delay.h> #include <linux/nfs_fs.h> +#include <linux/async.h> #include <net/net_namespace.h> #include <net/arp.h> #include <net/ip.h> @@ -182,12 +183,48 @@ struct ic_device { static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ static struct net_device *ic_dev __initdata = NULL; /* Selected device */ +/* + * Wait for required network devices to come up + * If the networking device name was specified on the kernel command line + * and that device is now registered, we have the device we want to configure + * and we return true. Otherwise, we return false. So, if no device was + * specified on the command line, we wait for all possible network devices to + * be initialized. + */ +static bool have_all_netdevs(void) +{ + struct net_device *dev; + bool result = false; + + rtnl_lock(); + + for_each_netdev(&init_net, dev) { + if (dev->flags & IFF_LOOPBACK) + continue; + + /* If a specific device name was specified and that name is + * registered, we have the device we need. */ + if (user_dev_name[0] && !strcmp(dev->name, user_dev_name)) { + result = true; + break; + } + } + + rtnl_unlock(); + + return result; + +} + static int __init ic_open_devs(void) { struct ic_device *d, **last; struct net_device *dev; unsigned short oflags; + /* Wait for networking devices */ + initdev_wait(INITDEV_NETDEV_TYPE, have_all_netdevs); + last = &ic_first_dev; rtnl_lock(); @@ -1263,6 +1300,7 @@ __be32 __init root_nfs_parse_addr(char *name) /* * IP Autoconfig dispatcher. + * Return zero on success, negative one on failure */ static int __init ip_auto_config(void) @@ -1397,7 +1435,22 @@ static int __init ip_auto_config(void) return 0; } -late_initcall(ip_auto_config); +static void __init ip_auto_config_async(void *data, async_cookie_t cookie) +{ + ip_auto_config(); +} + +/* + * Start a thread to do IP autoconfiguration + */ +static int __init ip_auto_configurator(void) +{ + async_schedule(ip_auto_config_async, NULL); + + return 0; +} + +late_initcall(ip_auto_configurator); /* -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html