From 16632332b3a49994edf0016a3c5c3200d32cf6ac Mon Sep 17 00:00:00 2001 From: Martin Sivak Date: Tue, 24 Mar 2009 14:14:56 +0100 Subject: Port the dlabel feature from RHEL (#489314) --- anaconda | 4 ++ flags.py | 1 + loader/Makefile | 2 +- loader/driverdisk.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ loader/driverdisk.h | 12 ++++++ loader/loader.c | 33 +++++++++++++++++ loader/loader.h | 2 + yuminstall.py | 2 +- 8 files changed, 158 insertions(+), 2 deletions(-) diff --git a/anaconda b/anaconda index 3bbf0fec6..28893e29e 100755 --- a/anaconda +++ b/anaconda @@ -251,6 +251,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() @@ -673,6 +674,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 8dbcc9f9d..5ee0a9fe1 100644 --- a/flags.py +++ b/flags.py @@ -70,6 +70,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 def2badea..cbdf03777 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 -liscsi +LIBS = -lnewt -lslang -lz -lpopt ../isys/libisys.a -lcheckisomd5 -liscsi -lblkid -luuid # devmapper LIBS += $(shell pkg-config --libs devmapper) diff --git a/loader/driverdisk.c b/loader/driverdisk.c index 9e7a30dd2..948ab9eec 100644 --- a/loader/driverdisk.c +++ b/loader/driverdisk.c @@ -48,6 +48,8 @@ #include "nfsinstall.h" #include "urlinstall.h" +#include + #include "../isys/isys.h" #include "../isys/imount.h" #include "../isys/eddsupport.h" @@ -510,6 +512,108 @@ 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 e6e919dd2..0e88ca4ac 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 98ea24cba..178f9250b 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -930,6 +930,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")) @@ -1795,7 +1799,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 }, @@ -1879,6 +1887,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); @@ -1939,6 +1953,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); @@ -2135,6 +2165,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 a6e2d057c..b5252c32e 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 963303256..3bcb78d1f 100644 --- a/yuminstall.py +++ b/yuminstall.py @@ -592,7 +592,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 -- cgit