diff options
author | Micha Nelissen <micha@neli.hopto.org> | 2011-05-19 06:14:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-19 17:13:04 -0400 |
commit | 3fb72f1e6e6165c5f495e8dc11c5bbd14c73385c (patch) | |
tree | e47295482bb91c6f837de040cb4abe5b79be7019 /net/ipv4 | |
parent | c182f90bc1f22ce5039b8722e45621d5f96862c2 (diff) |
ipconfig wait for carrier
v3 -> v4: fix return boolean false instead of 0 for ic_is_init_dev
Currently the ip auto configuration has a hardcoded delay of 1 second.
When (ethernet) link takes longer to come up (e.g. more than 3 seconds),
nfs root may not be found.
Remove the hardcoded delay, and wait for carrier on at least one network
device.
Signed-off-by: Micha Nelissen <micha@neli.hopto.org>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ipconfig.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index cbff2ecccf3d..ab7e5542c1cf 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -87,8 +87,8 @@ | |||
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | /* Define the friendly delay before and after opening net devices */ | 89 | /* Define the friendly delay before and after opening net devices */ |
90 | #define CONF_PRE_OPEN 500 /* Before opening: 1/2 second */ | 90 | #define CONF_POST_OPEN 10 /* After opening: 10 msecs */ |
91 | #define CONF_POST_OPEN 1 /* After opening: 1 second */ | 91 | #define CONF_CARRIER_TIMEOUT 120000 /* Wait for carrier timeout */ |
92 | 92 | ||
93 | /* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */ | 93 | /* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */ |
94 | #define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */ | 94 | #define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */ |
@@ -188,14 +188,14 @@ struct ic_device { | |||
188 | static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ | 188 | static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ |
189 | static struct net_device *ic_dev __initdata = NULL; /* Selected device */ | 189 | static struct net_device *ic_dev __initdata = NULL; /* Selected device */ |
190 | 190 | ||
191 | static bool __init ic_device_match(struct net_device *dev) | 191 | static bool __init ic_is_init_dev(struct net_device *dev) |
192 | { | 192 | { |
193 | if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : | 193 | if (dev->flags & IFF_LOOPBACK) |
194 | return false; | ||
195 | return user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : | ||
194 | (!(dev->flags & IFF_LOOPBACK) && | 196 | (!(dev->flags & IFF_LOOPBACK) && |
195 | (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) && | 197 | (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) && |
196 | strncmp(dev->name, "dummy", 5))) | 198 | strncmp(dev->name, "dummy", 5)); |
197 | return true; | ||
198 | return false; | ||
199 | } | 199 | } |
200 | 200 | ||
201 | static int __init ic_open_devs(void) | 201 | static int __init ic_open_devs(void) |
@@ -203,6 +203,7 @@ static int __init ic_open_devs(void) | |||
203 | struct ic_device *d, **last; | 203 | struct ic_device *d, **last; |
204 | struct net_device *dev; | 204 | struct net_device *dev; |
205 | unsigned short oflags; | 205 | unsigned short oflags; |
206 | unsigned long start; | ||
206 | 207 | ||
207 | last = &ic_first_dev; | 208 | last = &ic_first_dev; |
208 | rtnl_lock(); | 209 | rtnl_lock(); |
@@ -216,9 +217,7 @@ static int __init ic_open_devs(void) | |||
216 | } | 217 | } |
217 | 218 | ||
218 | for_each_netdev(&init_net, dev) { | 219 | for_each_netdev(&init_net, dev) { |
219 | if (dev->flags & IFF_LOOPBACK) | 220 | if (ic_is_init_dev(dev)) { |
220 | continue; | ||
221 | if (ic_device_match(dev)) { | ||
222 | int able = 0; | 221 | int able = 0; |
223 | if (dev->mtu >= 364) | 222 | if (dev->mtu >= 364) |
224 | able |= IC_BOOTP; | 223 | able |= IC_BOOTP; |
@@ -252,6 +251,17 @@ static int __init ic_open_devs(void) | |||
252 | dev->name, able, d->xid)); | 251 | dev->name, able, d->xid)); |
253 | } | 252 | } |
254 | } | 253 | } |
254 | |||
255 | /* wait for a carrier on at least one device */ | ||
256 | start = jiffies; | ||
257 | while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) { | ||
258 | for_each_netdev(&init_net, dev) | ||
259 | if (ic_is_init_dev(dev) && netif_carrier_ok(dev)) | ||
260 | goto have_carrier; | ||
261 | |||
262 | msleep(1); | ||
263 | } | ||
264 | have_carrier: | ||
255 | rtnl_unlock(); | 265 | rtnl_unlock(); |
256 | 266 | ||
257 | *last = NULL; | 267 | *last = NULL; |
@@ -1324,14 +1334,13 @@ static int __init wait_for_devices(void) | |||
1324 | { | 1334 | { |
1325 | int i; | 1335 | int i; |
1326 | 1336 | ||
1327 | msleep(CONF_PRE_OPEN); | ||
1328 | for (i = 0; i < DEVICE_WAIT_MAX; i++) { | 1337 | for (i = 0; i < DEVICE_WAIT_MAX; i++) { |
1329 | struct net_device *dev; | 1338 | struct net_device *dev; |
1330 | int found = 0; | 1339 | int found = 0; |
1331 | 1340 | ||
1332 | rtnl_lock(); | 1341 | rtnl_lock(); |
1333 | for_each_netdev(&init_net, dev) { | 1342 | for_each_netdev(&init_net, dev) { |
1334 | if (ic_device_match(dev)) { | 1343 | if (ic_is_init_dev(dev)) { |
1335 | found = 1; | 1344 | found = 1; |
1336 | break; | 1345 | break; |
1337 | } | 1346 | } |
@@ -1378,7 +1387,7 @@ static int __init ip_auto_config(void) | |||
1378 | return err; | 1387 | return err; |
1379 | 1388 | ||
1380 | /* Give drivers a chance to settle */ | 1389 | /* Give drivers a chance to settle */ |
1381 | ssleep(CONF_POST_OPEN); | 1390 | msleep(CONF_POST_OPEN); |
1382 | 1391 | ||
1383 | /* | 1392 | /* |
1384 | * If the config information is insufficient (e.g., our IP address or | 1393 | * If the config information is insufficient (e.g., our IP address or |