[PATCH] Port of RHEL5 dlabel/autodd functionality for Fedora (#436951)

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

 



Hi,

the only think i do not like is the hardcoded RHEL name detection. Do we have any way how to pass arguments/flags in the .discinfo or some similarfile?

and before you start asking questions, I already have some answers from discussion with Jeremy:

> First of all, I still have strong reservations about this as I really
> don't like the hard-coded, something called by this name getting used
> and would much prefer it being explicitly specified...

Me too, but we can't just drop the feature now, because Dell will scream.. again..

> We really need to stop polluting the flags namespace and come up with a
> better way of passing this around.  If we're going to do it, it could at
> least be in the anaconda class instead

Right now we do not have any other "information object" to store this kind of information

> We use actual mount(8) now instead of calling mount(2).  This means that
> we can just do 'mount LABEL=foo /bar' and don't need any of the blkid
> bits.

We do, because there might be more driverdiscs with the same "oemdrv" label

> As I said in the intro, I really don't want auto-mounting code -- we
> should instead just use dd=LABEL=foo and let them pass that...

I agree with you, but the problem is Dell, they think that passing arguments is
"bad customer experience". We tried very hard to avoid it.. and the only compromise
we were able to negotiate was that, this will be disabled by default in Fedora.

>... at which point, this can just flow into being the regular driver disk code.

The dlabel is now official feature in RHEL5, sorry but I'm not going through the
discussion again now, I've spent half a year in trying to persuade Dell, that this
is bad idea.. and if they do not see this in RHEL6, they will be at my throat again...

>> -        if self.anaconda.id.extraModules:
>> +        if self.anaconda.id.extraModules or flags.dlabel:

It is the second RFE they have, sometimes their driverdisc doesn't contain any modules,
so extraModules is empty, but the repository on the driverdisc is not. And they want to
install some stuff using it. Again without any user interaction and without kickstart.

We were at least able to tell them a way, which didn't need any code chnages, except this
one (using comps.xml file in the repo). Look at #316631.



diff --git a/anaconda b/anaconda
index a0f2ff1..a5b51a1 100755
--- a/anaconda
+++ b/anaconda
@@ -246,6 +246,7 @@ def parseOptions():
     op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False)
     op.add_option("--updates", dest="updateSrc", action="store", type="string")
     op.add_option("--dogtail", dest="dogtail",   action="store", type="string")
+    op.add_option("--dlabel", action="store_true", default=False)
 
     return op.parse_args()
 
@@ -668,6 +669,9 @@ if __name__ == "__main__":
     # Default is to prompt to mount the installed system.
     anaconda.rescue_mount = not opts.rescue_nomount
 
+    if opts.dlabel: #autodetected driverdisc in use
+        flags.dlabel = True
+
     if opts.noipv4:
         flags.useIPv4 = False
 
diff --git a/flags.py b/flags.py
index 2d77bd7..3343b02 100644
--- a/flags.py
+++ b/flags.py
@@ -64,6 +64,7 @@ class Flags:
 	self.__dict__['flags']['test'] = 0
 	self.__dict__['flags']['rootpath'] = 0
 	self.__dict__['flags']['livecdInstall'] = 0
+        self.__dict__['flags']['dlabel'] = 0
 	self.__dict__['flags']['ibft'] = 1
 	self.__dict__['flags']['iscsi'] = 0
 	self.__dict__['flags']['serial'] = 0
diff --git a/loader/Makefile b/loader/Makefile
index 6dc0412..923bf91 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 -lblkid -luuid
 
 # devmapper
 LIBS   += $(shell pkg-config --libs devmapper)
diff --git a/loader/driverdisk.c b/loader/driverdisk.c
index 9e7a30d..dc0bb70 100644
--- a/loader/driverdisk.c
+++ b/loader/driverdisk.c
@@ -30,6 +30,8 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <blkid/blkid.h>
+
 #include "copy.h"
 #include "loader.h"
 #include "log.h"
@@ -510,6 +512,112 @@ static void loadFromLocation(struct loaderData_s * loaderData, char * dir) {
     busProbe(0);
 }
 
+/*
+ * Utility functions to maintain linked-list of device names
+ * */
+
+struct ddlist* ddlist_add(struct ddlist *list, const char* device)
+{
+  struct ddlist* item;
+
+  item = (struct ddlist*)malloc(sizeof(struct ddlist));
+  if(item==NULL){
+    return list;
+  }
+
+  item->device = strdup(device);
+  item->next = list;
+
+  return item;
+}
+
+int ddlist_free(struct ddlist *list)
+{
+  struct ddlist *next;
+  int count = 0;
+
+  while(list!=NULL){
+    next = list->next;
+    free(list->device);
+    free(list);
+    list = next;
+    count++;
+  }
+
+  return count;
+}
+
+
+/*
+ * Look for partition with specific label (part of #316481)
+ */
+struct ddlist* findDriverDiskByLabel(void)
+{
+    char *ddLabel = "OEMDRV";
+    struct ddlist *ddDevice = NULL;
+    blkid_cache bCache;
+    
+    int res;
+    blkid_dev_iterate bIter;
+    blkid_dev bDev;
+
+    if(blkid_get_cache(&bCache, NULL)<0){
+      logMessage(ERROR, _("Cannot initialize cache instance for blkid"));
+      return NULL;
+    }
+    if((res = blkid_probe_all(bCache))<0){
+      logMessage(ERROR, _("Cannot probe devices in blkid: %d"), res);
+      return NULL;
+    }
+
+    bIter = blkid_dev_iterate_begin(bCache);
+    blkid_dev_set_search(bIter, "LABEL", ddLabel);
+    while((res = blkid_dev_next(bIter, &bDev))!=0){
+	bDev = blkid_verify(bCache, bDev);
+	if(!bDev)
+	  continue;
+	logMessage(DEBUGLVL, _("Adding driver disc %s to the list of available DDs."), blkid_dev_devname(bDev));
+	ddDevice = ddlist_add(ddDevice, blkid_dev_devname(bDev));
+	/*blkid_free_dev(bDev); -- probably taken care of by the put cache call.. it is not exposed in the API */
+    }
+    blkid_dev_iterate_end(bIter);
+    
+    blkid_put_cache(bCache);
+
+    return ddDevice;
+}
+
+int loadDriverDiskFromPartition(struct loaderData_s *loaderData, char* device)
+{
+    int rc;
+
+    logMessage(INFO, "trying to mount %s", device);
+    if (doMultiMount(device, "/tmp/drivers", ddFsTypes, "ro", NULL)) {
+	    logMessage(ERROR, _("Failed to mount driver disk."));
+	    return -1;
+    }
+
+    rc = verifyDriverDisk("/tmp/drivers");
+    if (rc == LOADER_BACK) {
+	logMessage(ERROR, _("Driver disk is invalid for this "
+			 "release of %s."), getProductName());
+	umount("/tmp/drivers");
+	return -2;
+    }
+
+    rc = loadDriverDisk(loaderData, "/tmp/drivers");
+    umount("/tmp/drivers");
+    if (rc == LOADER_BACK) {
+	return -3;
+    }
+
+    return 0;
+}
+
 void getDDFromSource(struct loaderData_s * loaderData, char * src) {
     char *path = "/tmp/dd.img";
     int unlinkf = 0;
diff --git a/loader/driverdisk.h b/loader/driverdisk.h
index e6e919d..0e88ca4 100644
--- a/loader/driverdisk.h
+++ b/loader/driverdisk.h
@@ -39,4 +39,16 @@ void useKickstartDD(struct loaderData_s * loaderData, int argc,
 
 void getDDFromSource(struct loaderData_s * loaderData, char * src);
 
+int loadDriverDiskFromPartition(struct loaderData_s *loaderData, char* device);
+
+struct ddlist {
+  char* device;
+  struct ddlist* next;
+};
+
+struct ddlist* ddlist_add(struct ddlist *list, const char* device);
+int ddlist_free(struct ddlist *list);
+
+struct ddlist* findDriverDiskByLabel(void);
+
 #endif
diff --git a/loader/loader.c b/loader/loader.c
index 4a2c2e6..8da64d0 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -928,6 +928,10 @@ static void parseCmdLineFlags(struct loaderData_s * loaderData,
         else if (!strcasecmp(argv[i], "dd") || 
                  !strcasecmp(argv[i], "driverdisk"))
             flags |= LOADER_FLAGS_MODDISK;
+        else if (!strcasecmp(argv[i], "dlabel=on"))
+            flags |= LOADER_FLAGS_AUTOMODDISK;
+        else if (!strcasecmp(argv[i], "dlabel=off"))
+            flags &= ~LOADER_FLAGS_AUTOMODDISK;
         else if (!strcasecmp(argv[i], "rescue"))
             flags |= LOADER_FLAGS_RESCUE;
         else if (!strcasecmp(argv[i], "nopass"))
@@ -1788,7 +1792,11 @@ int main(int argc, char ** argv) {
     int testing = 0;
     int mediacheck = 0;
     char * virtpcon = NULL;
+    
+    struct ddlist *dd, *dditer;
+
     poptContext optCon;
+
     struct poptOption optionTable[] = {
         { "cmdline", '\0', POPT_ARG_STRING, &cmdLine, 0, NULL, NULL },
         { "ksfile", '\0', POPT_ARG_STRING, &ksFile, 0, NULL, NULL },
@@ -1852,6 +1860,12 @@ int main(int argc, char ** argv) {
     flags |= LOADER_FLAGS_NOSHELL | LOADER_FLAGS_NOUSB;
 #endif
 
+    /* XXX if RHEL, enable the AUTODD feature by default,
+     * but we should come with more general way how to control this */
+    if(!strncmp(getProductName(), "Red Hat", 7)){
+        flags |= LOADER_FLAGS_AUTOMODDISK;
+    }
+
     openLog(FL_TESTING(flags));
     if (!FL_TESTING(flags))
         openlog("loader", 0, LOG_LOCAL0);
@@ -1912,6 +1926,22 @@ int main(int argc, char ** argv) {
     /* FIXME: this is a bit of a hack */
     loaderData.modInfo = modInfo;
 
+    if(FL_AUTOMODDISK(flags)){
+        logMessage(INFO, "Trying to detect vendor driver discs");
+        dd = findDriverDiskByLabel();
+        dditer = dd;
+        while(dditer){
+            if(loadDriverDiskFromPartition(&loaderData, dditer->device)){
+                logMessage(ERROR, "Automatic driver disk loader failed for %s.", dditer->device);
+            }
+            else{
+                logMessage(INFO, "Automatic driver disk loader succeeded for %s.", dditer->device);
+            }
+            dditer = dditer->next;
+        }
+        ddlist_free(dd);
+    }
+
     if (FL_MODDISK(flags)) {
         startNewt();
         loadDriverDisks(DEVICE_ANY, &loaderData);
@@ -2108,6 +2138,9 @@ int main(int argc, char ** argv) {
         tmparg++;
     }
 
+    if (FL_AUTOMODDISK(flags))
+        *argptr++ = "--dlabel";
+
     if (FL_NOIPV4(flags))
         *argptr++ = "--noipv4";
 
diff --git a/loader/loader.h b/loader/loader.h
index a6e2d05..b5252c3 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -68,6 +68,7 @@
 #define LOADER_FLAGS_IS_KICKSTART       (((uint64_t) 1) << 35)
 #define LOADER_FLAGS_ALLOW_WIRELESS     (((uint64_t) 1) << 36)
 #define LOADER_FLAGS_HAVE_CMSCONF       (((uint64_t) 1) << 37)
+#define LOADER_FLAGS_AUTOMODDISK        (((uint64_t) 1) << 38)
 
 #define FL_TESTING(a)            ((a) & LOADER_FLAGS_TESTING)
 #define FL_TEXT(a)               ((a) & LOADER_FLAGS_TEXT)
@@ -103,6 +104,7 @@
 #define FL_IS_KICKSTART(a)       ((a) & LOADER_FLAGS_IS_KICKSTART)
 #define FL_ALLOW_WIRELESS(a)     ((a) & LOADER_FLAGS_ALLOW_WIRELESS)
 #define FL_HAVE_CMSCONF(a)       ((a) & LOADER_FLAGS_HAVE_CMSCONF)
+#define FL_AUTOMODDISK(a)        ((a) & LOADER_FLAGS_AUTOMODDISK)
 
 void startNewt(void);
 void stopNewt(void);
diff --git a/yuminstall.py b/yuminstall.py
index c62c09b..a097ef1 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -586,7 +586,7 @@ class AnacondaYum(YumSorter):
 
         extraRepos = []
 
-        if self.anaconda.id.extraModules:
+        if self.anaconda.id.extraModules or flags.dlabel:
             for d in glob.glob("/tmp/DD-*/rpms"):
                 dirname = os.path.basename(os.path.dirname(d))
                 rid = "anaconda-%s" % dirname
_______________________________________________
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