summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Cantrell <dcantrell@redhat.com>2008-12-18 10:15:20 -1000
committerDavid Cantrell <dcantrell@redhat.com>2008-12-18 10:15:49 -1000
commiteca10a326af815cbb08b306881d559f1da28743f (patch)
treedda9336371243ce542dc567b5b19cc111e1cdc43
parent6d7171b88215c008ea813b9130ca54b0cf3067be (diff)
downloadanaconda-eca10a326af815cbb08b306881d559f1da28743f.tar.gz
anaconda-eca10a326af815cbb08b306881d559f1da28743f.tar.xz
anaconda-eca10a326af815cbb08b306881d559f1da28743f.zip
Allow 'ks' to function as it once did (#471812)
This is a much more readable and reasonable patch to restore the 'ks' boot option functionality. The nextserver and bootfile are read from the DHCP option set and used to build the URL to find the kickstart file. [rawhide]
-rw-r--r--loader/nfsinstall.c101
1 files changed, 78 insertions, 23 deletions
diff --git a/loader/nfsinstall.c b/loader/nfsinstall.c
index 9a61cad69..087c478a6 100644
--- a/loader/nfsinstall.c
+++ b/loader/nfsinstall.c
@@ -35,6 +35,10 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <glib.h>
+#include <nm-client.h>
+#include <nm-device.h>
+#include <nm-dhcp4-config.h>
#include "copy.h"
#include "loader.h"
@@ -369,8 +373,11 @@ 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, i = 0;
iface_t iface;
+ NMClient *client = NULL;
+ NMState state;
+ const GPtrArray *devices;
if (kickstartNetworkUp(loaderData, &iface)) {
logMessage(ERROR, "unable to bring up network");
@@ -380,43 +387,91 @@ 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;
+ g_type_init();
+
+ client = nm_client_new();
+ if (!client) {
+ logMessage(CRITICAL, "%s (%d): failure creating NM proxy",
+ __func__, __LINE__);
+ return 1;
+ }
- if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) {
+ state = nm_client_get_state(client);
+ if (state != NM_STATE_CONNECTED) {
+ logMessage(ERROR, "%s (%d): no active network devices",
+ __func__, __LINE__);
+ g_object_unref(client);
+ return 1;
+ }
+
+ devices = nm_client_get_devices(client);
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *candidate = g_ptr_array_index(devices, i);
+ const char *devname = nm_device_get_iface(candidate);
+ NMDHCP4Config *dhcp = NULL;
+ const char *server_name = NULL;
+ const char *filename = NULL;
+ struct in_addr addr;
+ char nextserver[INET_ADDRSTRLEN+1];
+
+ if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED)
+ continue;
+
+ if (strcmp(iface.device, devname))
+ continue;
+
+ dhcp = nm_device_get_dhcp4_config(candidate);
+ if (!dhcp) {
+ logMessage(ERROR, "no boot options received by DHCP");
+ continue;
+ }
+
+ server_name = nm_dhcp4_config_get_one_option(dhcp, "server_name");
+ if (!server_name) {
logMessage(ERROR, "no bootserver was found");
+ g_object_unref(client);
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));
-
- if (asprintf(&url, "%s:%s", ret, "/kickstart/") == -1) {
- logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
- abort();
+ /* 'server_name' may be a hostname or an IPv4 address */
+ memset(&nextserver, '\0', sizeof(nextserver));
+ if (inet_pton(AF_INET, server_name, &addr) >= 1) {
+ strcpy(nextserver, server_name);
+ } else {
+ struct hostent *he = gethostbyname(server_name);
+ if (he != NULL) {
+ if (inet_ntop(AF_INET, he->h_addr_list[0],
+ nextserver, INET_ADDRSTRLEN) == NULL) {
+ memset(&nextserver, '\0', sizeof(nextserver));
+ }
}
+ }
+
+ filename = nm_dhcp4_config_get_one_option(dhcp, "filename");
+ if (filename == 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", nextserver, filename) == -1) {
+ logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
+ abort();
+ }
- if (asprintf(&url, "%s:%s", ret, netCfg.dev.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", filename);
}
+
+ break;
}
-*/
+
+ g_object_unref(client);
/* get the IP of the target system */
if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) {
- logMessage(ERROR, "nl_ip2str returned NULL");
+ logMessage(ERROR, "iface_ip2str returned NULL");
return 1;
}