diff options
author | Radek Vykydal <rvykydal@redhat.com> | 2011-02-16 17:47:33 +0100 |
---|---|---|
committer | Radek Vykydal <rvykydal@redhat.com> | 2011-03-02 13:21:43 +0100 |
commit | 4c63f9622650051b9320d6c70ed0bde73145d9b8 (patch) | |
tree | 213b9f4de8b2cdc19c15407fd044eed844bd318c /loader | |
parent | 8ea759524347b42c134be6edcf78604ad6d54af4 (diff) | |
download | anaconda-4c63f9622650051b9320d6c70ed0bde73145d9b8.tar.gz anaconda-4c63f9622650051b9320d6c70ed0bde73145d9b8.tar.xz anaconda-4c63f9622650051b9320d6c70ed0bde73145d9b8.zip |
Make kickstart network command reconfigure active device in loader
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.
Diffstat (limited to 'loader')
-rw-r--r-- | loader/net.c | 124 | ||||
-rw-r--r-- | loader/net.h | 3 |
2 files changed, 126 insertions, 1 deletions
diff --git a/loader/net.c b/loader/net.c index d54946fd2..6ea3c7a9a 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 2a354f987..101beaaf9 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 |