[PATCH master 10/13] Make kickstart network command reconfigure active device in loader

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Port from rhel6-branch.
Resolves: rhbz#668395

If the device has already been activated, reactivate it with new
configuration.

Restores rhel 5 behaviour, changed in master most probably with
commit 1980e9d377aa6089ae96740cd85593ec18d5344d.
---
 loader/net.c |  124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 loader/net.h |    3 +
 2 files changed, 126 insertions(+), 1 deletions(-)

diff --git a/loader/net.c b/loader/net.c
index d54946f..6ea3c7a 100644
--- a/loader/net.c
+++ b/loader/net.c
@@ -1164,6 +1164,22 @@ int writeDisabledNetInfo(void) {
     return 0;
 }
 
+int removeIfcfgFile(char *device) {
+    char *fname = NULL;
+    checked_asprintf(&fname, "%s/ifcfg-%s",
+                     NETWORK_SCRIPTS_PATH,
+                     device);
+
+    if (!access(fname, R_OK|W_OK)) {
+        if (unlink(fname)) {
+            logMessage(ERROR, "error removing %s", fname);
+        }
+    }
+
+    free(fname);
+    return 0;
+}
+
 int removeDhclientConfFile(char *device) {
     char *ofile = NULL;
     if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", device) == -1) {
@@ -1867,6 +1883,35 @@ int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) {
 
 }
 
+int disconnectDevice(char *device) {
+    int rc;
+
+    if ((rc = removeDhclientConfFile(device)) != 0) {
+        logMessage(ERROR, "removeDhclientConfFile failure (%s): %d",
+                   __func__, rc);
+    }
+
+    /*
+     * This will disconnect the device
+     */
+    if ((rc = removeIfcfgFile(device)) != 0) {
+        logMessage(ERROR, "removeIfcfgFile failure (%s): %d",
+                   __func__, rc);
+        return rc;
+    }
+
+    if ((rc = wait_for_iface_disconnection(device)) != 0) {
+        return rc;
+    }
+
+    if ((rc = writeDisabledIfcfgFile(device)) != 0) {
+        logMessage(ERROR, "writeDisabledIfcfgFile failure (%s): %d",
+                   __func__, rc);
+        return rc;
+    }
+    return 0;
+}
+
 int activateDevice(struct loaderData_s * loaderData, iface_t * iface) {
     int rc;
 
@@ -1892,7 +1937,10 @@ int activateDevice(struct loaderData_s * loaderData, iface_t * iface) {
 
         if (is_iface_activated(iface->device)) {
             logMessage(INFO, "device %s is already activated", iface->device);
-            return 0;
+            if ((rc = disconnectDevice(iface->device)) != 0) {
+                logMessage(ERROR, "device disconnection failed with return code %d", rc);
+                return -1;
+            }
         }
 
         /* we don't want to end up asking about interface more than once
@@ -2065,4 +2113,78 @@ int wait_for_iface_activation(char *ifname) {
     return 3;
 }
 
+/*
+ * Wait for disconnection of iface by NetworkManager, return non-zero on error.
+ */
+int wait_for_iface_disconnection(char *ifname) {
+    int count = 0, i;
+    NMClient *client = NULL;
+    GMainLoop *loop;
+    GMainContext *ctx;
+    const GPtrArray *devices;
+    NMDevice *device = NULL;
+
+    if (ifname == NULL) {
+        return 1;
+    }
+
+    logMessage(INFO, "disconnecting device %s", ifname);
+
+    g_type_init();
+
+    client = nm_client_new();
+    if (!client) {
+        logMessage(ERROR, "%s (%d): could not connect to system bus",
+                   __func__, __LINE__);
+        return 2;
+    }
+
+    devices = nm_client_get_devices(client);
+    for (i = 0; i < devices->len; i++) {
+        NMDevice *candidate = g_ptr_array_index(devices, i);
+        const char *name = nm_device_get_iface(candidate);
+        if (!strcmp(name, ifname)) {
+            device = candidate;
+            break;
+        }
+    }
+    if (device == NULL) {
+        logMessage(ERROR, "%s (%d): network device %s not found",
+                   __func__, __LINE__, ifname);
+        g_object_unref(client);
+        return 3;
+    }
+
+    /* Create a loop for processing dbus signals */
+    loop = g_main_loop_new(NULL, FALSE);
+    ctx = g_main_loop_get_context(loop);
+
+    /* pump the loop until all the messages are clear */
+    while (g_main_context_pending (ctx)) {
+        g_main_context_iteration (ctx, FALSE);
+    }
+
+    /* send message and block until a reply or error comes back */
+    while (count < 5) {
+        /* pump the loop again to clear the messages */
+        while (g_main_context_pending (ctx)) {
+            g_main_context_iteration (ctx, FALSE);
+        }
+        if (nm_device_get_state(device) == NM_DEVICE_STATE_DISCONNECTED) {
+            logMessage(INFO, "%s (%d): device %s disconnected",
+                       __func__, __LINE__, ifname);
+            res_init();
+            g_main_loop_unref(loop);
+            g_object_unref(client);
+            return 0;
+        }
+
+        sleep(1);
+        count++;
+    }
+
+    g_main_loop_unref(loop);
+    g_object_unref(client);
+    return 3;
+}
 /* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/loader/net.h b/loader/net.h
index 2a354f9..101beaa 100644
--- a/loader/net.h
+++ b/loader/net.h
@@ -67,6 +67,7 @@ void debugNetworkInfo(iface_t * iface);
 int writeDisabledNetInfo(void);
 int writeDisabledIfcfgFile(char *device);
 int removeDhclientConfFile(char *device);
+int removeIfcfgFile(char *device);
 int writeEnabledNetInfo(iface_t * iface);
 int chooseNetworkInterface(struct loaderData_s * loaderData);
 void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData);
@@ -75,7 +76,9 @@ int kickstartNetworkUp(struct loaderData_s * loaderData,
                        iface_t * iface);
 int activateDevice(struct loaderData_s * loaderData,
                    iface_t * iface);
+int disconnectDevice(char *device);
 void splitHostname (char *str, char **host, char **port);
 int wait_for_iface_activation(char * ifname);
+int wait_for_iface_disconnection(char *ifname);
 
 #endif
-- 
1.7.2

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux