Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 May 2004 21:22:11 +1000 (EST)
From:      Edwin Groothuis <edwin@mavetju.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/66984: patch: teach sysinstall about larger disks
Message-ID:  <20040521112211.E283761CD@k7.mavetju>
Resent-Message-ID: <200405211130.i4LBUHu8044031@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         66984
>Category:       bin
>Synopsis:       patch: teach sysinstall about larger disks
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 21 04:30:17 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Edwin Groothuis
>Release:        FreeBSD 5.2.1-RELEASE i386
>Organization:
BarNetwork Pty Limited
>Environment:
FreeBSD frigga.barnet.com.au 4.10-RC3 FreeBSD 4.10-RC3 #0: Sun May 16 19:26:39 GMT 2004     root@perseus.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

>Description:

On a machine which has to act as a backup server, we have a 3Ware
raid card with 10 200Mb harddisks. The twe(4) driver sees it properly
and shows 1717030MB (which is 9x200Gb because of RAID5).

During sysinstall, fdisk and disklabel complain about a couple of things:

- fdisk says that the geomtry (218890x255x63) is unlikely to be the
  right one. The maximum geometry is 65536x256x63 which is 1TB.
  With current harddisk sizes increasing (200Gb is easily affordable),
  I think we should increase the maximum size to 4*65536 cylinders.

- fdisk gives a lot of negative values for offsets due to the fact
  that the size variable is often an integer instead of an u_long.
  Replaced some %d and %ld with %lu. Also replaced strtol() with
  strtoul() because the amount of cylinders was more than LONG_MAX.

- with the increasing of the sizes of harddisks, it's easier to see
  see the values in Gb, so added a Gb unit to the "cycle units"
  functions in fdisk.

- also in fdisk, with the space on the screen it is taken, sizes >
  100Gb are shown in Gb instead of Mb.

- When entering the size of a disks to allocate it in fdisk, the
  suffix G was magical (did work, didn't appear in the dialogbox)


- disklabel had the same integer variables and didn't want to start
  because it thought I had a negative amount of diskspace.

- the input box to enter the partition size didn't accept huge
  amount of cylinders (via strtoul()),

- the input box to enter the partition size had the free size in
  Mb, now show it in Gb if there is more than 100Gb free.


- What isn't resolved is some sanity check for partitions too big,
  tjr@ explained that the maximum partition size could be at most
  2^40 bytes. If bigger, newfs will choke on it.


>How-To-Repeat:
>Fix:

diff -u sysinstall.orig/disks.c sysinstall/disks.c
--- sysinstall.orig/disks.c	Fri May 21 19:31:53 2004
+++ sysinstall/disks.c	Fri May 21 20:45:31 2004
@@ -40,7 +40,7 @@
 #include <sys/stat.h>
 #include <sys/disklabel.h>
 
-enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_SIZE };
+enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_GIG, UNIT_SIZE };
 
 #ifdef PC98
 #define	SUBTYPE_FREEBSD		50324
@@ -89,17 +89,17 @@
 {
     int row;
     int i;
-    int sz;
+    u_long sz;
     char *szstr;
 
-    szstr = (u == UNIT_MEG ? "MB" : (u == UNIT_KILO ? "KB" : "ST"));
+    szstr = (u == UNIT_GIG ? "GB" : u == UNIT_MEG ? "MB" : (u == UNIT_KILO ? "KB" : "ST"));
 
     for (i = Total = 0; chunk_info[i]; i++)
 	Total += chunk_info[i]->size;
 #ifdef PC98
     if (d->bios_cyl >= 65536 || d->bios_hd > 16 || d->bios_sect >= 256) {
 #else
-    if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
+    if (d->bios_cyl > 262144 || d->bios_hd > 256 || d->bios_sect >= 64) {
 #endif
 	dialog_clear_norefresh();
 	msgConfirm("WARNING:  A geometry of %lu/%lu/%lu for %s is incorrect.  Using\n"
@@ -139,10 +139,13 @@
 	case UNIT_MEG:
 	    sz = chunk_info[i]->size / (1024/512) / 1024;
 	    break;
+	case UNIT_GIG:
+	    sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
+	    break;
 	}
 	if (i == current_chunk)
 	    attrset(ATTR_SELECTED);
-	mvprintw(row, 0, "%10ld %10lu %10lu %8s %6d %10s %8d\t%-6s",
+	mvprintw(row, 0, "%10lu %10lu %10lu %8s %6d %10s %8d\t%-6s",
 		 chunk_info[i]->offset, sz,
 		 chunk_info[i]->end, chunk_info[i]->name,
 		 chunk_info[i]->type, 
@@ -399,7 +402,7 @@
 		msg = "Slice in use, delete it first or move to an unused one.";
 	    else {
 		char *val, tmp[20], *cp;
-		int size;
+		u_long size;
 #ifdef PC98
 		char name[16];
 
@@ -413,9 +416,11 @@
 		chunk_e partitiontype;
 #endif
 		snprintf(tmp, 20, "%lu", chunk_info[current_chunk]->size);
-		val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
-				  "or append a trailing `M' for megabytes (e.g. 20M).");
-		if (val && (size = strtol(val, &cp, 0)) > 0) {
+		val = msgGetInput(tmp,
+			"Please specify the size for new FreeBSD slice in blocks\n"
+			"or append a trailing `M' or 'G' for megabytes or gigabytes\n"
+			"respectively (e.g. 20M, 40G).");
+		if (val && (size = strtoul(val, &cp, 0)) > 0) {
 		    if (*cp && toupper(*cp) == 'M')
 			size *= ONE_MEG;
 		    else if (*cp && toupper(*cp) == 'G')
@@ -850,7 +855,8 @@
 diskPartitionNonInteractive(Device *dev)
 {
     char *cp;
-    int i, sz, all_disk = 0;
+    u_long sz;
+    int i, all_disk = 0;
 #ifdef PC98
     u_char *bootipl;
     size_t bootipl_size;
@@ -909,7 +915,7 @@
 
 	    All_FreeBSD(d, all_disk = TRUE);
 	}
-	else if ((sz = strtol(cp, &cp, 0))) {
+	else if ((sz = strtoul(cp, &cp, 0))) {
 	    /* Look for sz bytes free */
 	    if (*cp && toupper(*cp) == 'M')
 		sz *= ONE_MEG;
@@ -931,7 +937,7 @@
 		}
 	    }
 	    if (!chunk_info[i]) {
-		msgConfirm("Unable to find %d free blocks on this disk!", sz);
+		msgConfirm("Unable to find %lu free blocks on this disk!", sz);
 		return;
 	    }
 	}
Binary files sysinstall.orig/disks.o and sysinstall/disks.o differ
Common subdirectories: sysinstall.orig/help and sysinstall/help
diff -u sysinstall.orig/label.c sysinstall/label.c
--- sysinstall.orig/label.c	Fri May 21 19:31:53 2004
+++ sysinstall/label.c	Fri May 21 20:46:23 2004
@@ -248,7 +248,7 @@
 space_free(struct chunk *c)
 {
     struct chunk *c1;
-    int sz = c->size;
+    u_long sz = c->size;
 
     for (c1 = c->part; c1; c1 = c1->next) {
 	if (c1->type != unused)
@@ -455,7 +455,7 @@
 print_label_chunks(void)
 {
     int  i, j, srow, prow, pcol;
-    int  sz;
+    u_long  sz;
     char clrmsg[80];
     int ChunkPartStartRow;
     WINDOW *ChunkWin;
@@ -550,10 +550,18 @@
             if (i == pslice_focus)
                 pslice_focus_found = -1;
 
-	    mvprintw(srow++, 0, 
-		     "Disk: %s\tPartition name: %s\tFree: %d blocks (%dMB)",
+
+	    if (sz > 100 * ONE_GIG) {
+		mvprintw(srow++, 0, 
+		     "Disk: %s\tPartition name: %s\tFree: %lu blocks (%luGB)",
+		     label_chunk_info[i].c->disk->name, label_chunk_info[i].c->name, 
+		     sz, (sz / ONE_GIG));
+	    } else {
+		mvprintw(srow++, 0, 
+		     "Disk: %s\tPartition name: %s\tFree: %lu blocks (%luMB)",
 		     label_chunk_info[i].c->disk->name, label_chunk_info[i].c->name, 
 		     sz, (sz / ONE_MEG));
+	    }
 	    attrset(A_NORMAL);
 	    clrtoeol();
 	    move(0, 0);
@@ -617,7 +625,14 @@
 		strcpy(newfs, "*");
 	    for (j = 0; j < MAX_MOUNT_NAME && mountpoint[j]; j++)
 		onestr[PART_MOUNT_COL + j] = mountpoint[j];
-	    snprintf(num, 10, "%5ldMB", label_chunk_info[i].c->size ? label_chunk_info[i].c->size / ONE_MEG : 0);
+
+	    if (label_chunk_info[i].c->size == 0)
+		snprintf(num, 10, "0MB");
+	    else if (label_chunk_info[i].c->size < 100 * ONE_GIG)
+		snprintf(num, 10, "%5luMB", label_chunk_info[i].c->size / ONE_MEG);
+	    else
+		snprintf(num, 10, "%5luGB", label_chunk_info[i].c->size / ONE_GIG);
+
 	    memcpy(onestr + PART_SIZE_COL, num, strlen(num));
 	    memcpy(onestr + PART_NEWFS_COL, newfs, strlen(newfs));
 	    onestr[PART_NEWFS_COL + strlen(newfs)] = '\0';
@@ -709,7 +724,8 @@
 static int
 diskLabel(Device *dev)
 {
-    int sz, key = 0;
+    u_long sz;
+    int key = 0;
     Boolean labeling;
     char *msg = NULL;
     PartInfo *p, *oldp;
@@ -844,18 +860,25 @@
 	    }
 	    else {
 		char *val;
-		int size;
+		u_long size;
 		struct chunk *tmp;
 		char osize[80];
 		u_long flags = 0;
 
-		sprintf(osize, "%d", sz);
-		val = msgGetInput(osize,
+		sprintf(osize, "%lu", sz);
+		if (sz > 100 * ONE_GIG)
+		    val = msgGetInput(osize,
+				  "Please specify the partition size in blocks or append a trailing G for\n"
+				  "gigabytes, M for megabytes, or C for cylinders.\n"
+				  "%lu blocks (%luGB) are free.",
+				  sz, sz / ONE_GIG);
+		else
+		    val = msgGetInput(osize,
 				  "Please specify the partition size in blocks or append a trailing G for\n"
 				  "gigabytes, M for megabytes, or C for cylinders.\n"
-				  "%d blocks (%dMB) are free.",
+				  "%lu blocks (%luMB) are free.",
 				  sz, sz / ONE_MEG);
-		if (!val || (size = strtol(val, &cp, 0)) <= 0) {
+		if (!val || (size = strtoul(val, &cp, 0)) <= 0) {
 		    clear_wins();
 		    break;
 		}
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040521112211.E283761CD>