Work around vfs/inet/eth race by avoiding non-blocking ioctl in dhcpd
This commit is contained in:
parent
6312d7238b
commit
d59c49aecb
@ -10,6 +10,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/asynchio.h>
|
#include <sys/asynchio.h>
|
||||||
@ -92,6 +93,11 @@ void closefd(fd_t *fdp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void timeout(int signum)
|
||||||
|
{
|
||||||
|
/* nothing to do, ioctl will be aborted automatically */
|
||||||
|
}
|
||||||
|
|
||||||
int opendev(network_t *np, fdtype_t fdtype, int compete)
|
int opendev(network_t *np, fdtype_t fdtype, int compete)
|
||||||
{
|
{
|
||||||
/* Make sure that a network has the proper device open and configured.
|
/* Make sure that a network has the proper device open and configured.
|
||||||
@ -169,14 +175,19 @@ int opendev(network_t *np, fdtype_t fdtype, int compete)
|
|||||||
|
|
||||||
switch (fdtype) {
|
switch (fdtype) {
|
||||||
case FT_ETHERNET:
|
case FT_ETHERNET:
|
||||||
/* Set NONBLOCK to avoid waiting for a device driver to become ready */
|
/* Cannot use NWIOGETHSTAT in non-blocking mode due to a race between
|
||||||
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) | O_NONBLOCK);
|
* the reply from the ethernet driver and the cancel message from VFS
|
||||||
|
* for reaching inet. Hence, a signal is used to interrupt NWIOGETHSTAT
|
||||||
|
* in case the driver isn't ready yet.
|
||||||
|
*/
|
||||||
|
if (signal(SIGALRM, timeout) == SIG_ERR) fatal("signal(SIGALRM)");
|
||||||
|
if (alarm(1) < 0) fatal("alarm(1)");
|
||||||
if (ioctl(np->fdp->fd, NWIOGETHSTAT, ðstat) < 0) {
|
if (ioctl(np->fdp->fd, NWIOGETHSTAT, ðstat) < 0) {
|
||||||
/* Not an Ethernet. */
|
/* Not an Ethernet. */
|
||||||
close(fdp->fd);
|
close(fdp->fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) & ~O_NONBLOCK);
|
if (alarm(0) < 0) fatal("alarm(0)");
|
||||||
np->eth= ethstat.nwes_addr;
|
np->eth= ethstat.nwes_addr;
|
||||||
ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD
|
ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD
|
||||||
| NWEO_REMANY | NWEO_TYPEANY | NWEO_RWDATALL;
|
| NWEO_REMANY | NWEO_TYPEANY | NWEO_RWDATALL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user