[PATCH] Device nodes are created according to /sys/block information. (#485060)

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

 



/sys/block contains removable devices as well. /proc/partitions does not, so we have to use the newer interface to make cdrom based driverdiscs work.
---
 loader2/getparts.c |  169 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 107 insertions(+), 62 deletions(-)

diff --git a/loader2/getparts.c b/loader2/getparts.c
index d58ff93..c0474c0 100644
--- a/loader2/getparts.c
+++ b/loader2/getparts.c
@@ -24,6 +24,8 @@
 #include <errno.h>
 #include <ctype.h>
 #include <string.h>
+#include <dirent.h>
+#include <errno.h>
 
 #include "log.h"
 
@@ -157,80 +159,123 @@ int lenPartitionsList(char **list) {
     return rc;
 }
 
-/* Ensure all the device nodes from /proc/partitions exist in /dev
- * returns number of partitions found
- */
-int createPartitionNodes() {
+int createDevNode(const char *dname, const char *devname)
+{
+    char *dnode;
     FILE *f;
-    int numfound = 0;
+    int major, minor;
+
+    f = fopen(dname, "r");
+    logMessage(DEBUGLVL, "Trying to get device info %s from %s.", devname, dname);
 
-    f = fopen("/proc/partitions", "r");
     if (!f) {
-	logMessage(ERROR, "getPartitionsList: could not open /proc/partitions");
-	return -1;
+        logMessage(ERROR, "Could not open %s.", dname);
+        return -1;
     }
 
-    /* read through /proc/partitions and parse out partitions */
-    while (1) {
-	char *tmpptr, *pptr;
-	char tmpstr[4096];
-
-	tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
-
-	if (tmpptr) {
-	    char *a, *b;
-	    int toknum = 0;
-	    int major, minor;
+    if(fscanf(f, "%i:%i", &major, &minor)<2){
+        logMessage(ERROR, "Could not get major/minor from %s.", devname);
+        fclose(f);
+        return -2;
+    }
 
-	    a = tmpstr;
-	    while (1) {
-		b = strsep(&a, " \n");
+    fclose(f);
+   
+    if(asprintf(&dnode, "/dev/%s", devname)<=0) {
+        logMessage(ERROR, "Cannot allocate memory for device node (%s).", devname);
+        return -3;
+    }
+    
+    if(mknod(dnode, 0600 | S_IFBLK, makedev(major, minor))<0) {
+        if(errno!=EEXIST) {
+            logMessage(ERROR, "Failed to create device node (%s %i:%i).", dnode, major, minor);
+        }
+
+        free(dnode);
+        return -4;
+    }
+    else {
+        logMessage(DEBUGLVL, "Device node (%s %i:%i) created.", dnode, major, minor);
+        free(dnode);
+        return 0;
+    }
+}
 
-		/* if no fields left abort */
-		if (!b)
-		    break;
+/* Ensure all the device nodes from /sys/block exist in /dev
+ * returns number of partitions found
+ */
+int createPartitionNodes()
+{
+    DIR *d, *subd;
+    int numfound = 0;
+    struct dirent *dirp;
+    struct dirent *subdirp;
 
-		/* if field was empty means we hit another delimiter */
-		if (!*b)
-		    continue;
+    logMessage(DEBUGLVL, "Creating device nodes...");
 
-		/* make sure this is a valid partition line, should start */
-		/* with a numeral */
-		if (toknum == 0) {
-		    if (!isdigit(*b))
-			break;
-		    else
-		        major = atoi(b);
-		/* minor number */
-		} else if (toknum == 1) {
-		    if (!isdigit(*b))
-			break;
-		    else
-		        minor = atoi(b);
-		} else if (toknum == 2) {
-		    /* if size is exactly 1 then ignore it as an extended */
-		    if (!strcmp(b, "1"))
-			break;
-		} else if (toknum == 3) {
-		    /* this is block device or partition name */
-		    /* lets create devnode! */
-		    pptr = (char *) malloc(strlen(b) + 7);
-		    sprintf(pptr, "/dev/%s", b);
-		    mknod(pptr, 0600 | S_IFBLK, makedev(major, minor));
-		    logMessage(INFO, "creating device node for %s as b %d %d", pptr, major, minor);
-		    free(pptr);
+    d = opendir("/sys/block");
+    if(!d) {
+        logMessage(ERROR, "Cannot read /sys/block. Device nodes will not be created and driver discs may not work");
+        return -1;
+    }
 
-		    numfound++;
-		    break;
-		}
-		toknum++;
-	    }
-	} else {
-	    break;
-	}
+    /* Go through /sys/block */
+    while((dirp = readdir(d)) != NULL) {
+        char *dname;
+
+        if(!strcmp(dirp->d_name, "..") || !strcmp(dirp->d_name, "."))
+            continue;
+        
+        logMessage(DEBUGLVL, "Trying to create device nodes for %s.", dirp->d_name);
+
+        if(asprintf(&dname, "/sys/block/%s/dev", dirp->d_name)<=0) {
+            logMessage(ERROR, "Cannot allocate memory for device info (%s).", dirp->d_name);
+            continue;
+        }
+
+        if(!createDevNode(dname, dirp->d_name))
+            numfound++;
+        free(dname);
+
+        /* Look for partitions */
+        if(asprintf(&dname, "/sys/block/%s", dirp->d_name)<=0) {
+            logMessage(ERROR, "Cannot allocate memory for device subdirectory (%s).", dirp->d_name);
+            continue;
+        }
+
+        subd = opendir(dname);
+        if(!subd) {
+            logMessage(ERROR, "Cannot read /sys/block/%s. Partition nodes will not be created and driver discs may not work", dirp->d_name);
+            free(dname);
+            continue;
+        }
+
+        /* Go through /sys/block/$dname */
+        while((subdirp = readdir(subd)) != NULL) {
+            char *subdirname;
+
+            /* check if it is a partition */
+            if(strncmp(subdirp->d_name, dirp->d_name, dirp->d_reclen)){
+                /* not a partition, check next.. */
+                continue;
+            }
+
+            logMessage(DEBUGLVL, "Trying to create device nodes for %s.", subdirp->d_name);
+            if(asprintf(&subdirname, "/sys/block/%s/%s/dev", dirp->d_name, subdirp->d_name)<=0) {
+                logMessage(ERROR, "Cannot allocate memory for device info (%s).", subdirp->d_name);
+                continue;
+            }
+
+            if(!createDevNode(subdirname, subdirp->d_name))
+                numfound++;
+            free(subdirname);
+        }
+        
+        closedir(subd);
+        free(dname);
     }
 
-    fclose(f);
+    closedir(d);
 
     return numfound;
 }
-- 
1.6.6.1

_______________________________________________
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