diff options
author | Martin Sivak <msivak@redhat.com> | 2009-01-08 15:03:34 +0100 |
---|---|---|
committer | Martin Sivak <msivak@redhat.com> | 2009-01-08 15:05:55 +0100 |
commit | 89652b6fbe65e5e7922d743a99b07104d071ef42 (patch) | |
tree | 2db006864b0c009aa1529d34b944d8342b637b65 /loader | |
parent | 162efc4dcb767db3b648939876966954ee783984 (diff) | |
download | anaconda-89652b6fbe65e5e7922d743a99b07104d071ef42.tar.gz anaconda-89652b6fbe65e5e7922d743a99b07104d071ef42.tar.xz anaconda-89652b6fbe65e5e7922d743a99b07104d071ef42.zip |
Port the dlabel feature from RHEL5 bug #316481 into Fedora (#436951)
Diffstat (limited to 'loader')
-rw-r--r-- | loader/Makefile | 2 | ||||
-rw-r--r-- | loader/driverdisk.c | 108 | ||||
-rw-r--r-- | loader/driverdisk.h | 12 | ||||
-rw-r--r-- | loader/loader.c | 33 | ||||
-rw-r--r-- | loader/loader.h | 2 |
5 files changed, 156 insertions, 1 deletions
diff --git a/loader/Makefile b/loader/Makefile index 6dc0412f3..923bf9189 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 9e7a30dd2..dc0bb70a2 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 (doPwMount(device, "/tmp/drivers", "vfat", IMOUNT_RDONLY, NULL)) { + if (doPwMount(device, "/tmp/drivers", "ext2", IMOUNT_RDONLY, NULL)) { + if (doPwMount(device, "/tmp/drivers", "iso9660", IMOUNT_RDONLY, 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 4a2c2e6c3..8da64d01b 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 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); |