[PATCH] Add iBFT support to loader

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

 



---
 anaconda.spec          |    2 +
 isys/iface.h           |    3 +-
 iw/netconfig_dialog.py |    4 +-
 loader/Makefile        |    4 +-
 loader/ibft.c          |  105 ++++++++++++++++++++++++++++++++++++++++++++++++
 loader/ibft.h          |   45 ++++++++++++++++++++
 loader/net.c           |  104 ++++++++++++++++++++++++++++++++++++++++++++++-
 7 files changed, 260 insertions(+), 7 deletions(-)
 create mode 100644 loader/ibft.c
 create mode 100644 loader/ibft.h

diff --git a/anaconda.spec b/anaconda.spec
index 010cbf4..fd00cf3 100644
--- a/anaconda.spec
+++ b/anaconda.spec
@@ -38,6 +38,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 %define dbusver 1.2.3
 %define createrepover 0.4.7
 %define yumutilsver 1.1.11-3
+%define iscsiver 6.2.0.870
 
 BuildRequires: audit-libs-devel
 BuildRequires: booty
@@ -75,6 +76,7 @@ BuildRequires: dbus-devel >= %{dbusver}
 %ifarch %livearches
 BuildRequires: desktop-file-utils
 %endif
+BuildRequires: iscsi-initiator-utils-devel >= %{iscsiver}
 
 Requires: policycoreutils
 Requires: rpm-python >= %{rpmpythonver}
diff --git a/isys/iface.h b/isys/iface.h
index 5cd8614..e20c2b4 100644
--- a/isys/iface.h
+++ b/isys/iface.h
@@ -30,7 +30,7 @@
 /* Enumerated types used in iface.c as well as loader's network code */
 enum { IPUNUSED, IPV4, IPV6 };
 
-enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD };
+enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD };
 enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD,
        IPV6_MANUAL_METHOD };
 
@@ -100,6 +100,7 @@ typedef struct _iface_t {
     uint64_t flags;
     int ipv4method;
     int ipv6method;
+    int isiBFT;
 } iface_t;
 
 /* Function prototypes */
diff --git a/iw/netconfig_dialog.py b/iw/netconfig_dialog.py
index 4818171..c87da21 100644
--- a/iw/netconfig_dialog.py
+++ b/iw/netconfig_dialog.py
@@ -67,8 +67,8 @@ class NetworkConfigurator:
         val = combo.get_model().get_value(active, 1)
         netdev = self.network.available()[val]
 
-        bootproto = netdev.get('BOOTPROTO')
-        if not bootproto or bootproto == "dhcp":
+        bootproto = netdev.get("BOOTPROTO")
+        if not bootproto or bootproto == "dhcp" or bootproto == "ibft":
             self.xml.get_widget("dhcpCheckbutton").set_active(True)
         else:
             self.xml.get_widget("dhcpCheckbutton").set_active(False)
diff --git a/loader/Makefile b/loader/Makefile
index 6dc0412..def2bad 100644
--- a/loader/Makefile
+++ b/loader/Makefile
@@ -26,7 +26,7 @@ else
 TARGET=depend $(PROGS)
 endif
 
-LIBS = -lnewt -lslang -lz -lpopt ../isys/libisys.a -lcheckisomd5
+LIBS = -lnewt -lslang -lz -lpopt ../isys/libisys.a -lcheckisomd5 -liscsi
 
 # devmapper
 LIBS   += $(shell pkg-config --libs devmapper)
@@ -57,7 +57,7 @@ METHOBJS = method.o cdinstall.o hdinstall.o nfsinstall.o urlinstall.o
 OBJS = copy.o log.o moduleinfo.o loadermisc.o modules.o windows.o \
 	lang.o kbd.o driverdisk.o selinux.o \
 	mediacheck.o kickstart.o driverselect.o \
-	getparts.o dirbrowser.o fwloader.o \
+	getparts.o dirbrowser.o fwloader.o ibft.o \
 	$(HWOBJS) $(METHOBJS)
 LOADEROBJS = loader.o loader-pcmcia.o
 NETOBJS = net.o urls.o ftp.o telnet.o telnetd.o
diff --git a/loader/ibft.c b/loader/ibft.c
new file mode 100644
index 0000000..b3a3827
--- /dev/null
+++ b/loader/ibft.c
@@ -0,0 +1,105 @@
+/*
+   File name: ibft.c
+   Date:      2008/09/02
+   Author:    Martin Sivak <msivak@xxxxxxxxxx>
+
+   Copyright (C) 2008 Red Hat
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   in a file called COPYING along with this program; if not, write to
+   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+   02139, USA.
+*/
+
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libiscsi.h>
+#include "ibft.h"
+
+struct libiscsi_network_config ibft_context;
+int ibft_ispresent = 0;
+int ibft_initialized = 0;
+
+int ibft_init(void)
+{
+  int ret;
+
+  memset(&ibft_context, 0, sizeof(ibft_context));
+
+  ret = libiscsi_get_firmware_network_config(&ibft_context);
+
+  /* ret == 0 -> OK */
+  ibft_ispresent = !ret;
+  ibft_initialized = 1;
+
+  return ibft_initialized;
+}
+
+/* Is iBFT available on this system */
+int ibft_present()
+{
+  if(!ibft_initialized)
+    ibft_init();
+
+  return ibft_ispresent;
+}
+
+/* Is the iBFT network configured to use DHCP */
+int ibft_iface_dhcp()
+{
+  if(!ibft_initialized)
+    ibft_init();
+
+  if(!ibft_present())
+    return -1;
+
+  return ibft_context.dhcp;
+}
+
+#define ibft_iface_charfunc(name, var) char* ibft_iface_##name()\
+{\
+  if(!ibft_initialized)\
+    ibft_init();\
+\
+  if(!ibft_present())\
+    return NULL;\
+\
+  if(!strlen(ibft_context.var))\
+    return NULL;\
+\
+  return ibft_context.var;\
+}
+
+
+/* Get the iBFT MAC address */
+ibft_iface_charfunc(mac, mac_address)
+
+/* Get the iBFT ip address */
+ibft_iface_charfunc(ip, ip_address)
+
+/* Get the iBFT subnet mask */
+ibft_iface_charfunc(mask, netmask)
+
+/* Get the iBFT gateway */
+ibft_iface_charfunc(gw, gateway)
+
+/* Get the iBFT iface name */
+ibft_iface_charfunc(iface, iface_name)
+
+/* Get the iBFT dns servers */
+ibft_iface_charfunc(dns1, primary_dns)
+ibft_iface_charfunc(dns2, secondary_dns)
+
diff --git a/loader/ibft.h b/loader/ibft.h
new file mode 100644
index 0000000..a922c91
--- /dev/null
+++ b/loader/ibft.h
@@ -0,0 +1,45 @@
+/*
+   File name: ibft.h
+   Date:      2008/09/02
+   Author:    Martin Sivak
+
+   Copyright (C) 2008 Red Hat
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   in a file called COPYING along with this program; if not, write to
+   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+   02139, USA.
+*/
+
+
+#ifndef __IBFT_H__
+#define __IBFT_H__
+
+
+int ibft_init();
+int ibft_present();
+
+int ibft_iface_dhcp();
+
+char* ibft_iface_mac();
+char* ibft_iface_ip();
+char* ibft_iface_mask();
+char* ibft_iface_gw();
+char* ibft_iface_iface();
+char* ibft_iface_dns1();
+char* ibft_iface_dns2();
+
+
+#endif
+
+/* end of ibft.h */
diff --git a/loader/net.c b/loader/net.c
index 4d08d34..7ee0053 100644
--- a/loader/net.c
+++ b/loader/net.c
@@ -53,6 +53,7 @@
 #include "method.h"
 #include "net.h"
 #include "windows.h"
+#include "ibft.h"
 
 /* boot flags */
 extern uint64_t flags;
@@ -237,8 +238,26 @@ void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) {
     }
 
     if (loaderData->ipinfo_set && loaderData->ipv4 != NULL) {
+	/* this is iBFT configured device */
+	if (!strncmp(loaderData->ip, "ibft", 4)) {
+	    char *devmacaddr = nl_mac2str(loaderData->netDev);
+	    iface->ipv4method = IPV4_IBFT_METHOD;
+	    iface->isiBFT = 1;
+
+	    /* Problems with getting the info from iBFT or iBFT uses dhcp*/
+	    if(!devmacaddr || !ibft_present() || ibft_iface_dhcp()){
+		iface->ipv4method = IPV4_DHCP_METHOD;
+		logMessage(INFO, "iBFT is not present or is configured to use DHCP");
+	    }
+	    /* MAC address doesn't match */
+	    else if(strcasecmp(ibft_iface_mac(), devmacaddr)){
+		iface->ipv4method = IPV4_DHCP_METHOD;
+		logMessage(INFO, "iBFT doesn't know what NIC to use - falling back to DHCP");
+	    }
+	    if(devmacaddr) free(devmacaddr);
+	}
         /* this is how we specify dhcp */
-        if (!strncmp(loaderData->ipv4, "dhcp", 4)) {
+        else if (!strncmp(loaderData->ipv4, "dhcp", 4)) {
             iface->dhcptimeout = loaderData->dhcpTimeout;
             iface->ipv4method = IPV4_DHCP_METHOD;
         } else if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) {
@@ -289,6 +308,24 @@ void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) {
     }
 #endif
 
+    /* iBFT configured DNS */
+    if(iface->ipv4method == IPV4_IBFT_METHOD){
+	if(iface->numdns<MAXNS){
+	    if(ibft_iface_dns1() && inet_pton(AF_INET, ibft_iface_dns1(), &addr)>=1){
+		iface->dns[iface->numdns] = strdup(ibft_iface_dns1());
+		iface->numdns++;
+		logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns1());
+	    }
+	}
+	if(iface->numdns<MAXNS){
+	    if(ibft_iface_dns2() && inet_pton(AF_INET, ibft_iface_dns2(), &addr)>=1){
+		iface->dns[iface->numdns] = strdup(ibft_iface_dns2());
+		iface->numdns++;
+		logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns2());
+	    }
+	}
+    }
+
     if (loaderData->dns) {
         char * buf;
         char ret[INET6_ADDRSTRLEN+1];
@@ -320,6 +357,8 @@ void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) {
             }
         }
 
+
+
         logMessage(INFO, "dnsservers is %s", loaderData->dns);
     }
 
@@ -1221,7 +1260,15 @@ int writeEnabledNetInfo(iface_t *iface) {
     fprintf(fp, "ONBOOT=yes\n");
 
     if (!FL_NOIPV4(flags)) {
-        if (iface->ipv4method == IPV4_DHCP_METHOD) {
+        if (iface->ipv4method == IPV4_IBFT_METHOD) {
+	    /* When initrd and NM support iBFT, we should just write
+	     * BOOTPROTO=ibft and let NM deal with it. Until than,
+	     * just use static and do it ourselves. */
+            fprintf(fp, "BOOTPROTO=static\n");
+	    if(ibft_iface_ip()) fprintf(fp, "IPADDR=%s\n", ibft_iface_ip());
+	    if(ibft_iface_mask()) fprintf(fp, "NETMASK=%s\n", ibft_iface_mask());
+	    if(ibft_iface_gw()) fprintf(fp, "GATEWAY=%s\n", ibft_iface_gw());
+        else if (iface->ipv4method == IPV4_DHCP_METHOD) {
             fprintf(fp, "BOOTPROTO=dhcp\n");
         } else if (iface->ipv4method == IPV4_MANUAL_METHOD) {
             fprintf(fp, "BOOTPROTO=static\n");
@@ -1580,6 +1627,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) {
     char **deviceNames;
     char *ksMacAddr = NULL, *seconds = strdup("10"), *idstr = NULL;
     struct device **devs;
+    int lookForLink = 0;
     struct newtWinEntry entry[] = {{N_("Seconds:"), (char **) &seconds, 0},
                                    {NULL, NULL, 0 }};
 
@@ -1669,8 +1717,60 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) {
         return LOADER_NOOP;
     }
 
+    while((loaderData->netDev && (loaderData->netDev_set == 1)) &&
+	    !strcmp(loaderData->netDev, "ibft")){
+	char *devmacaddr = NULL;
+	char *ibftmacaddr = "";
+
+	/* get MAC from the iBFT table */
+	if(!(ibftmacaddr = ibft_iface_mac())){ /* iBFT not present or error */
+	    lookForLink = 0;
+	    break;
+	}
+
+	logMessage(INFO, "looking for iBFT configured device %s with link", ibftmacaddr);
+	lookForLink = 0;
+
+	for (i = 0; devs[i]; i++) {
+	    if (!devs[i]->device)
+		continue;
+	    devmacaddr = nl_mac2str(devs[i]->device);
+	    if(!strcasecmp(devmacaddr, ibftmacaddr)){
+		logMessage(INFO, "%s has the right MAC (%s), checking for link", devmacaddr, devices[i]);
+		free(devmacaddr);
+		if(get_link_status(devices[i]) == 1){
+		    lookForLink = 0;
+		    loaderData->netDev = devices[i];
+		    logMessage(INFO, "%s has link, using it", devices[i]);
+
+		    /* set the IP method to ibft if not requested differently */
+		    if(loaderData->ip==NULL){
+			loaderData->ip = strdup("ibft");
+			logMessage(INFO, "%s will be configured using iBFT values", devices[i]);
+		    }
+		    return LOADER_NOOP;
+		}
+		else{
+		    logMessage(INFO, "%s has no link, skipping it", devices[i]);
+		}
+
+		break;
+	    }
+	    else{
+		free(devmacaddr);
+	    }
+	}
+
+	break;
+    }
+
+
     if ((loaderData->netDev && (loaderData->netDev_set == 1)) &&
         !strcmp(loaderData->netDev, "link")) {
+	lookForLink = 1;
+    }
+
+    if(lookForLink){
         logMessage(INFO, "looking for first netDev with link");
         for (rc = 0; rc < 5; rc++) {
             for (i = 0; i < deviceNums; i++) {
-- 
1.5.4.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