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

Bug#238091: woody install created bad sun disklabels?



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


Reply to: