From 04df67ae69d98b0f77f94bf5f7c1514907dd003a Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@laine.org>
Date: Wed, 15 May 2013 14:13:09 -0400
Subject: [PATCH] wait for IFF_UP and IFF_RUNNING after calling ifup
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=961184
Apparently one or the other of IFF_UP and IFF_RUNNING are not always
set by the time /sbin/ifup returns control to netcf, so the subsequent
check to verify that the interface is up may fail. This patch adds a
loop to re-check the status of the interface every 250msec for up to
2.5 seconds (or until both flags are set). If timeout is reached, it
still fails the operation.
(cherry picked from commit 14af66fa2b119f47a23c9a4043ae8fe2441379fc)
---
bootstrap.conf | 3 ++-
src/drv_debian.c | 13 ++++++++++---
src/drv_redhat.c | 11 +++++++++--
src/drv_suse.c | 13 ++++++++++---
4 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/bootstrap.conf b/bootstrap.conf
index fd1c8f7..4736009 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -1,6 +1,6 @@
# Bootstrap configuration.
-# Copyright (C) 2010-2012 Red Hat, Inc.
+# Copyright (C) 2010-2013 Red Hat, Inc.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -43,6 +43,7 @@ sys_ioctl
sys_socket
sys_wait
unistd
+usleep
vasprintf
waitpid
warnings
diff --git a/src/drv_debian.c b/src/drv_debian.c
index ceeed94..d762a5d 100644
--- a/src/drv_debian.c
+++ b/src/drv_debian.c
@@ -1,7 +1,7 @@
/*
- * drv_initscripts.c: the initscripts backend for netcf
+ * drv_debian.c: the debian backend for netcf
*
- * Copyright (C) 2009-2012 Red Hat Inc.
+ * Copyright (C) 2009-2013 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1056,10 +1056,17 @@ int drv_if_up(struct netcf_if *nif) {
static const char *const ifup = IFUP;
struct netcf *ncf = nif->ncf;
int result = -1;
+ int is_active, retries;
run1(ncf, ifup, nif->name);
ERR_BAIL(ncf);
- ERR_THROW(!if_is_active(ncf, nif->name), ncf, EOTHER,
+
+ for (retries = 0; retries < 10; retries++) {
+ if ((is_active = if_is_active(ncf, nif->name)))
+ break;
+ usleep(250000);
+ }
+ ERR_THROW(!is_active, ncf, EOTHER,
"interface %s failed to become active - "
"possible disconnected cable.", nif->name);
result = 0;
diff --git a/src/drv_redhat.c b/src/drv_redhat.c
index 4040f5e..b5b8694 100644
--- a/src/drv_redhat.c
+++ b/src/drv_redhat.c
@@ -1,7 +1,7 @@
/*
* drv_redhat.c: the Red Hat distro family backend for netcf
*
- * Copyright (C) 2009-2012 Red Hat Inc.
+ * Copyright (C) 2009-2013 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1021,6 +1021,7 @@ int drv_if_up(struct netcf_if *nif) {
char **slaves = NULL;
int nslaves = 0;
int result = -1;
+ int is_active, retries;
if (is_bridge(ncf, nif->name)) {
/* Bring up bridge slaves before the bridge */
@@ -1034,7 +1035,13 @@ int drv_if_up(struct netcf_if *nif) {
}
run1(ncf, ifup, nif->name);
ERR_BAIL(ncf);
- ERR_THROW(!if_is_active(ncf, nif->name), ncf, EOTHER,
+
+ for (retries = 0; retries < 10; retries++) {
+ if ((is_active = if_is_active(ncf, nif->name)))
+ break;
+ usleep(250000);
+ }
+ ERR_THROW(!is_active, ncf, EOTHER,
"interface %s failed to become active - "
"possible disconnected cable.", nif->name);
result = 0;
diff --git a/src/drv_suse.c b/src/drv_suse.c
index 0d4a0af..e59d7d3 100644
--- a/src/drv_suse.c
+++ b/src/drv_suse.c
@@ -1,8 +1,8 @@
/*
- * drv_suse.c: the suse backend for suse
+ * drv_suse.c: the suse backend for netcf
*
* Copyright (C) 2010 Novell Inc.
- * Copyright (C) 2009-2012 Red Hat Inc.
+ * Copyright (C) 2009-2013 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1164,6 +1164,7 @@ int drv_if_up(struct netcf_if *nif) {
char **slaves = NULL;
int nslaves = 0;
int result = -1;
+ int is_active, retries;
if (is_bridge(ncf, nif->name)) {
/* Bring up bridge slaves before the bridge */
@@ -1177,7 +1178,13 @@ int drv_if_up(struct netcf_if *nif) {
}
run1(ncf, ifup, nif->name);
ERR_BAIL(ncf);
- ERR_THROW(!if_is_active(ncf, nif->name), ncf, EOTHER,
+
+ for (retries = 0; retries < 10; retries++) {
+ if ((is_active = if_is_active(ncf, nif->name)))
+ break;
+ usleep(250000);
+ }
+ ERR_THROW(!is_active, ncf, EOTHER,
"interface %s failed to become active - "
"possible disconnected cable.", nif->name);
result = 0;
--
1.8.3.1