summaryrefslogtreecommitdiffstats
path: root/loader
diff options
context:
space:
mode:
authorRadek Vykydal <rvykydal@redhat.com>2011-02-16 17:47:33 +0100
committerRadek Vykydal <rvykydal@redhat.com>2011-03-02 13:21:43 +0100
commit4c63f9622650051b9320d6c70ed0bde73145d9b8 (patch)
tree213b9f4de8b2cdc19c15407fd044eed844bd318c /loader
parent8ea759524347b42c134be6edcf78604ad6d54af4 (diff)
downloadanaconda-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.c124
-rw-r--r--loader/net.h3
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