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: