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

Re: DAC install fail on bootdisks



Lauri, are you in a position to test my changes on a DAC960 system?
If so, please apply the attached patch to utilities/libfdisk/fdisk.c,
add -DDEBUG to CFLAGS in the Makefile in the same directory and run "make
testing" (which will produce a program named "testing").  Please run it
(as root) and let me know what output it generates, and if it is accurate.

I don't expect there's any danger, but you would probably only want to do
this on a test system ... please don't put any important system at risk.

Erik (or anyone else listening) would you kindly try it also on a SCSI
system?  Can anyone try it on a non-i386 architecture?  I'd appreciate
any feedback before committing these changes.

Thanks,

Mark.
Index: utilities/libfdisk/fdisk.c
===================================================================
RCS file: /cvs/debian-boot/boot-floppies/utilities/libfdisk/fdisk.c,v
retrieving revision 1.34
diff -u -H -r1.34 fdisk.c
--- utilities/libfdisk/fdisk.c	2000/01/05 20:50:56	1.34
+++ utilities/libfdisk/fdisk.c	2000/01/07 13:12:56
@@ -26,6 +26,11 @@
 
 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
 
+/* Sparc does not define this, we will try it like this though */
+#ifndef MAX_DISKNAME_LEN
+#define MAX_DISKNAME_LEN 32
+#endif
+
 /* this array translates partition type numbers to file system types */
 static struct fstypes {
     int ptype;
@@ -441,24 +446,83 @@
     return fstype_name[fstype];
 }
 
+
+/* get_part_info: read and parse line in /proc/partitions format */
+static int get_part_info(FILE *f, dev_t *dev, char *name)
+{
+    char line[64];
+    unsigned int major, minor;
+
+    while (fgets(line, sizeof line, f)) {
+	if (sscanf(line, "%4u  %4u %*u %s", &major, &minor, name) == 3) {
+	    *dev = MKDEV(major, minor);
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+
+/* part_name: return partition device name from disk and partition number */
+static char *part_name(struct fdisk_disk *disk, int part)
+{
+    FILE *f;
+    char *pname = NULL, *dname = disk->name + 5;
+
+    assert(strncmp(disk->name, "/dev/", 5) == 0);
+
+#ifdef DEBUG
+    printf( "looking for partition %d of disk %s\n", part, dname );
+#endif
+
+    /* scan /proc/partitions for likely devices */
+    f = fopen("/proc/partitions", "r");
+    if (f) {
+	char name[MAX_DISKNAME_LEN];
+	dev_t dev, disk_dev = 0;
+
+	while (get_part_info(f, &dev, name)) {
+	    /* look for target partition or real disk containing it */
+	    if (! disk_dev) {
+		/* look for real disk containing target partition */
+		if (strcmp(name, dname) == 0)
+		    disk_dev = dev;
+	    } else {
+		/* look for partition with same number as target */
+		if (disk_dev + part == dev) {
+		    static char path[] = "/dev/";
+
+#ifdef DEBUG
+		    printf("found partition %s: major=%d, minor=%d\n",
+			   pname, (int)MAJOR(dev), (int)MINOR(dev));
+#endif
+
+		    /* build full path for partition device */
+		    pname = malloc(sizeof path + sizeof name);
+		    if (pname) {
+			strcpy(pname, path);
+			strcat(pname, name);
+		    }
+		    break;
+		}
+	    }
+	}
+	fclose(f);
+    }
+    return pname;
+}
+
+
 struct fdisk_partition *
 fdisk_add_partition(const char *name, int minor, unsigned int type,
-		    unsigned long size){
-
-  struct fdisk_partition *partition;
-  struct fdisk_disk *disk;
+		    unsigned long size)
+{
   int fstype;
+  struct fdisk_partition *partition = malloc(sizeof(struct fdisk_partition));
 
-  partition = (struct fdisk_partition *) 
-    malloc(sizeof(struct fdisk_partition));
-  if (!partition) return NULL;
-
-  if (minor != -1){
-    partition->name= malloc(strlen(name)+4);
-    sprintf(partition->name,"%s%d", name, minor);
-  } else {
-    partition->name=strdup(name);
-  }
+  if (!partition)
+    return NULL;
+
   partition->mount_point= NULL;
   partition->type = type;
   partition->size = size;
@@ -467,9 +531,14 @@
   partition->next_by_disk = NULL;
   partition->next_by_type = NULL;
   partition->next_in_use = NULL;
-  
-  if (minor != -1){
-    disk=fdisk_find_disk(name);
+
+  if (minor != -1) {
+    struct fdisk_disk *disk = fdisk_find_disk(name);
+
+    assert(disk);
+    partition->name = part_name(disk, minor);
+    assert(partition->name);
+
 #ifdef DEBUG
     printf( "adding partition %s, to disk %s\n", partition->name, disk->name );
 #endif
@@ -478,6 +547,9 @@
     if (NULL != disk->last_partition)
       (disk->last_partition)->next_by_disk = partition;
     disk->last_partition = partition;
+  } else {
+    partition->name = strdup(name);
+    assert(partition->name);
   }
   
   if (NULL == fdisk_partitions)
@@ -975,7 +1047,14 @@
 		size = 0;   /* don't complain, size not really used yet */
 	    size >>= 1;     /* convert from 512-byte sectors to kB */
 	    fdisk_add_disk(device, size);
+
 	    parse_partition(device, fd);
+	} else {
+	    /* Don't need to do anything for individual partitions because   */
+	    /* parse_partition() above calls fdisk_add_partition() for every */
+	    /* partition on the 'whole-disk' device.  We could eliminate a   */
+	    /* huge amount of code and complexity if we knew the partition   */
+	    /* type right now.						     */
 	}
 	close(fd);
     }
@@ -1018,11 +1097,6 @@
     return 0;
 }
 
-/* Sparc does not define this, we will try it like this though */
-#ifndef MAX_DISKNAME_LEN
-#define MAX_DISKNAME_LEN 32
-#endif
-
 /* fdisk_reread: build up disk/partition lists from scratch */
 void fdisk_reread(void)
 {
@@ -1033,14 +1107,12 @@
     /* scan /proc/partitions for likely device names */
     f = fopen("/proc/partitions", "r");
     if (f) {
-	char line[64];
-	while (fgets(line, sizeof line, f)) {
-	    unsigned int major, minor;
-	    char name[MAX_DISKNAME_LEN];
-
-	    /* check device major.minor against known 'whole-disk' devices */
-	    if (sscanf(line, "%4u  %4u %*u %s", &major, &minor, name) == 3
-	     && is_drive((major << 8) + minor)) {
+	char name[MAX_DISKNAME_LEN];
+	dev_t dev;
+
+	while (get_part_info(f, &dev, name)) {
+	    /* check device number against known 'whole-disk' devices */
+	    if (is_drive(dev)) {
 		static char path[] = "/dev/";
 		char dev_name[sizeof path + sizeof name];
 

Reply to: