[PATCH] Fix the 'ks' boot argument (#471812)

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

 



If you boot with just 'ks', loader will assume the kickstart file
is on NFS and determine the path to it using the nextserver and
bootfile DHCP options.  I neglected to get around to fixing this
for the big NM changeover.

Talking to NetworkManager to get the nextserver and bootfile
options is a bit complex now.  There is no direct way to get to
the Dhcp4Config object.  You have to get ActiveConnections, iterate,
get Devices, iterate, get Hal path, iterate, get Interface property,
match interface name, break, get Dhcp4Config property, recurse, get
Options dict, recurse, recurse, recurse, iterate, get nextserver and
bootfile, combine to form 'url'.
---
 loader/nfsinstall.c |  178 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 162 insertions(+), 16 deletions(-)

diff --git a/loader/nfsinstall.c b/loader/nfsinstall.c
index 9a61cad..b5d4353 100644
--- a/loader/nfsinstall.c
+++ b/loader/nfsinstall.c
@@ -35,6 +35,7 @@
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#include <NetworkManager.h>
 
 #include "copy.h"
 #include "loader.h"
@@ -369,7 +370,17 @@ void setKickstartNfs(struct loaderData_s * loaderData, int argc,
 int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
     char * host = NULL, *path = NULL, * file = NULL, * opts = NULL;
     char * chk = NULL, *ip = NULL;
-    int failed = 0;
+    int failed = 0, found = 0, type = 0;
+    char *interface = NULL;
+    char *key = NULL;
+    char *val = NULL;
+    char nextserver[INET_ADDRSTRLEN+1];
+    char *bootfile = NULL;
+    char *dpath[3];
+    struct in_addr addr;
+    struct hostent *hostent;
+    DBusMessage *reply[4];
+    DBusMessageIter iter[13];
     iface_t iface;
 
     if (kickstartNetworkUp(loaderData, &iface)) {
@@ -380,39 +391,174 @@ int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
     /* if they just did 'linux ks', they want us to figure it out from
      * the dhcp/bootp information
      */
-/* XXX: fixme NetworkManager integration */
-/*
     if (url == NULL) {
-        char ret[47];
-        ip_addr_t *tip;
+        /* get the IP4Config object for the active interface */
 
-        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) {
-            logMessage(ERROR, "no bootserver was found");
+        reply[0] = get_nm_dbus_property(NM_DBUS_INTERFACE,
+                                        NM_DBUS_PATH, "ActiveConnections");
+        if (!reply[0]) {
             return 1;
         }
 
-        tip = &(netCfg.dev.nextServer);
-        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) {
-            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
+        dbus_message_iter_init(reply[0], &iter[0]);
+        dbus_message_iter_recurse(&iter[0], &iter[1]);
+
+        while (dbus_message_iter_get_arg_type(&iter[1]) !=
+               DBUS_TYPE_INVALID) {
+            dbus_message_iter_recurse(&iter[1], &iter[2]);
+
+            while (dbus_message_iter_get_arg_type(&iter[2]) !=
+                   DBUS_TYPE_INVALID) {
+                dbus_message_iter_get_basic(&iter[2], &dpath[0]);
+
+                reply[1] = get_nm_dbus_property(NM_DBUS_INTERFACE,
+                                                dpath[0], "Devices");
+                if (!reply[1]) {
+                    return 1;
+                }
+
+                dbus_message_iter_init(reply[1], &iter[3]);
+                dbus_message_iter_recurse(&iter[3], &iter[4]);
+
+                while (dbus_message_iter_get_arg_type(&iter[4]) !=
+                       DBUS_TYPE_INVALID) {
+                    dbus_message_iter_recurse(&iter[4], &iter[5]);
+
+                    while (dbus_message_iter_get_arg_type(&iter[5]) !=
+                           DBUS_TYPE_INVALID) {
+                        dbus_message_iter_get_basic(&iter[5], &dpath[1]);
+
+                        reply[2] = get_nm_dbus_property(NM_DBUS_INTERFACE,
+                                                        dpath[1], "Interface");
+                        if (!reply[2]) {
+                            return 1;
+                        }
+
+                        dbus_message_iter_init(reply[2], &iter[6]);
+                        dbus_message_iter_recurse(&iter[6],
+                                                  &iter[7]);
+
+                        while (dbus_message_iter_get_arg_type(&iter[7])
+                               != DBUS_TYPE_INVALID) {
+                            dbus_message_iter_get_basic(&iter[7],
+                                                        &interface);
 
-            if (asprintf(&url, "%s:%s", ret, "/kickstart/") == -1) {
+                            if (!strcmp(interface, iface.device)) {
+                                found = 1;
+                                break;
+                            }
+
+                            dbus_message_iter_next(&iter[7]);
+                        }
+
+                        if (found) break;
+                        dbus_message_iter_next(&iter[5]);
+                    }
+
+                    if (found) break;
+                    dbus_message_iter_next(&iter[4]);
+                }
+
+                if (found) break;
+                dbus_message_iter_next(&iter[2]);
+            }
+
+            if (found) break;
+            dbus_message_iter_next(&iter[1]);
+        }
+
+        if (!found) {
+            logMessage(ERROR, "%s has no BOOTP values\n", iface.device);
+            return 1;
+        }
+
+        /* get Dhcp4Config object for this device */
+        reply[2] = get_nm_dbus_property(NM_DBUS_INTERFACE,
+                                        dpath[1], "Dhcp4Config");
+        if (!reply[2]) {
+            return 1;
+        }
+
+        dbus_message_iter_init(reply[2], &iter[6]);
+        dbus_message_iter_recurse(&iter[6], &iter[7]);
+
+        while (dbus_message_iter_get_arg_type(&iter[7]) !=
+               DBUS_TYPE_INVALID) {
+            dbus_message_iter_get_basic(&iter[7], &dpath[2]);
+
+            reply[3] = get_nm_dbus_property(NM_DBUS_INTERFACE,
+                                            dpath[2], "Options");
+            if (!reply[3]) {
+                return 1;
+            }
+
+            dbus_message_iter_init(reply[3], &iter[8]);
+            dbus_message_iter_recurse(&iter[8], &iter[9]);
+
+            if (dbus_message_iter_get_arg_type(&iter[9]) !=
+                DBUS_TYPE_ARRAY) {
+                dbus_message_iter_next(&iter[7]);
+                continue;
+            }
+
+            dbus_message_iter_recurse(&iter[9], &iter[10]);
+            while (dbus_message_iter_get_arg_type(&iter[10]) ==
+                   DBUS_TYPE_DICT_ENTRY) {
+                dbus_message_iter_recurse(&iter[10], &iter[11]);
+                key = NULL;
+                dbus_message_iter_get_basic(&iter[11], &key);
+                dbus_message_iter_next(&iter[11]);
+                dbus_message_iter_recurse(&iter[11], &iter[12]);
+                type = dbus_message_iter_get_arg_type(&iter[12]);
+                dbus_message_iter_get_basic(&iter[12], &val);
+
+                if ((!strcasecmp(key, "server_name")) &&
+                    (type == DBUS_TYPE_STRING)) {
+                    memset(&nextserver, '\0', sizeof(nextserver));
+                    if (inet_pton(AF_INET, val, &addr) >= 1) {
+                        strcpy(nextserver, val);
+                    } else {
+                        hostent = gethostbyname(val);
+                        if (hostent != NULL) {
+                            if (inet_ntop(AF_INET, hostent->h_addr_list[0],
+                                          nextserver,
+                                          INET_ADDRSTRLEN) == NULL) {
+                                memset(&nextserver, '\0', sizeof(nextserver));
+                            }
+                        }
+                    }
+                } else if ((!strcasecmp(key, "filename")) &&
+                           (type == DBUS_TYPE_STRING)) {
+                    bootfile = strdup(val);
+                }
+
+                dbus_message_iter_next(&iter[10]);
+            }
+
+            dbus_message_iter_next(&iter[7]);
+        }
+
+        if (nextserver == NULL) {
+            logMessage(ERROR, "no bootserver was found");
+            return 1;
+        }
+
+        if (bootfile == NULL) {
+            if (asprintf(&url, "%s:/kickstart/", nextserver) == -1) {
                 logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                 abort();
             }
 
             logMessage(ERROR, "bootp: no bootfile received");
         } else {
-            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
-
-            if (asprintf(&url, "%s:%s", ret, netCfg.dev.bootFile) == -1) {
+            if (asprintf(&url, "%s:%s", nextserver, bootfile) == -1) {
                 logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                 abort();
             }
 
-            logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile);
+            logMessage(INFO, "bootp: bootfile is %s", bootfile);
         }
     }
-*/
 
     /* get the IP of the target system */
     if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) {
-- 
1.6.0.3

_______________________________________________
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