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