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>