reassign 238091 libparted1.6-0 retitle 238091 libparted: misparses certain old sun disklabels tags 238091 patch thanks [I wrote] > Actually, no. I investigated a bit; it seems fdisk is right and > partman (actually libparted) is wrong. I've got a patch, but it's > incomplete, and only lightly tested. OK, finally got a chance to test the patch. It certainly seems to fix the debian-installer problem. Here's the deal. Sun disklabels have a bunch of geometry information in them, including three different numbers of cylinders: pcylcount physical number of cylinders ncyl number of data cylinders nacyl number of alternate cylinders nacyl seems to always be 2. ncyl is how many cylinders are usable. pcylcount is normally ncyl+nacyl. However, on some old disks, Solaris puts pcylcount as some higher number. I don't know why, but Solaris and util-linux fdisk both do it, so it's best not to argue. As far as I can tell, pcylcount is useless. This patch tells libparted to do basically what util-linux fdisk does: for reading, ignore it in favor of ncyl; for writing, give it the value of ncyl+2. Peter
diff -urN parted-1.6.6/libparted/disk_sun.c parted-work/libparted/disk_sun.c --- parted-1.6.6/libparted/disk_sun.c 2004-03-21 18:17:51.000000000 -0500 +++ parted-work/libparted/disk_sun.c 2004-03-21 18:23:26.000000000 -0500 @@ -184,19 +184,19 @@ defaults since most people do anyway...sue me. */ label->magic = PED_CPU_TO_BE16 (SUN_DISK_MAGIC); label->nacyl = PED_CPU_TO_BE16 (2); - label->pcylcount = PED_CPU_TO_BE16 (dev->cylinders); + label->pcylcount = PED_CPU_TO_BE16 (dev->cylinders + 2); label->rspeed = PED_CPU_TO_BE16 (5400); label->ilfact = PED_CPU_TO_BE16 (1); - label->sparecyl = PED_CPU_TO_BE16 (dev->sectors); + label->sparecyl = 0; label->ntrks = PED_CPU_TO_BE16 (dev->heads); label->nsect = PED_CPU_TO_BE16 (dev->sectors); - label->ncyl = PED_CPU_TO_BE16 (dev->cylinders - 2); + label->ncyl = PED_CPU_TO_BE16 (dev->cylinders); /* Add a whole disk partition at a minimum */ label->infos[WHOLE_DISK_PART].id = WHOLE_DISK_ID; label->partitions[WHOLE_DISK_PART].start_cylinder = 0; label->partitions[WHOLE_DISK_PART].num_sectors = - PED_CPU_TO_BE32((dev->cylinders-2) * dev->heads * dev->sectors); + PED_CPU_TO_BE32(dev->cylinders * dev->heads * dev->sectors); /* Now a neato string to describe this label */ snprintf(label->info, sizeof(label->info) - 1, @@ -241,8 +241,11 @@ { PedDevice* dev = disk->dev; - if (PED_BE16_TO_CPU(label->nsect) != dev->sectors || - PED_BE16_TO_CPU(label->ntrks) != dev->heads) { + unsigned short cylinders = PED_BE16_TO_CPU(label->ncyl); + unsigned short heads = PED_BE16_TO_CPU(label->ntrks); + unsigned short sectors = PED_BE16_TO_CPU(label->nsect); + + if (sectors != dev->sectors || heads != dev->heads) { #ifndef DISCOVER_ONLY if (ped_exception_throw ( PED_EXCEPTION_WARNING, @@ -251,17 +254,15 @@ "match the geometry stored on the disk " "label (%d,%d,%d)."), dev->cylinders, dev->heads, dev->sectors, - PED_BE16_TO_CPU(label->pcylcount), - PED_BE16_TO_CPU(label->ntrks), - PED_BE16_TO_CPU(label->nsect)) + cylinders, heads, sectors) == PED_EXCEPTION_CANCEL) return 0; #endif - dev->sectors = PED_BE16_TO_CPU(label->nsect); - dev->heads = PED_BE16_TO_CPU(label->ntrks); - dev->cylinders = PED_BE16_TO_CPU(label->pcylcount); + dev->sectors = sectors; + dev->heads = heads; + dev->cylinders = cylinders; - if (dev->sectors * dev->heads * dev->cylinders > dev->length) { + if (cylinders * heads * sectors > dev->length) { if (ped_exception_throw ( PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL, @@ -301,8 +302,7 @@ goto error; block = disk->dev->sectors * disk->dev->heads; - disk_data->length = block * (disk->dev->cylinders - - PED_BE16_TO_CPU(label->nacyl)); + disk_data->length = block * disk->dev->cylinders; for (i = 0; i < SUN_DISK_MAXPARTITIONS; i++) { if (!PED_BE32_TO_CPU(label->partitions[i].num_sectors)) @@ -416,9 +416,9 @@ smaller than it really is, but we'll have that problem even if we don't do this. */ - label->pcylcount = PED_CPU_TO_BE16 (disk->dev->cylinders); - label->ncyl = PED_CPU_TO_BE16 (disk->dev->cylinders - - PED_BE32_TO_CPU(label->nacyl)); + label->pcylcount = PED_CPU_TO_BE16 (disk->dev->cylinders + + PED_BE32_TO_CPU(label->nacyl)); + label->ncyl = PED_CPU_TO_BE16 (disk->dev->cylinders); sun_compute_checksum (label);
Attachment:
signature.asc
Description: Digital signature