From owner-freebsd-arch Fri Dec 7 19:50:23 2001 Delivered-To: freebsd-arch@freebsd.org Received: from apollo.backplane.com (apollo.backplane.com [216.240.41.2]) by hub.freebsd.org (Postfix) with ESMTP id 96C9137B416 for ; Fri, 7 Dec 2001 19:49:53 -0800 (PST) Received: (from dillon@localhost) by apollo.backplane.com (8.11.6/8.9.1) id fB83nWU00292; Fri, 7 Dec 2001 19:49:32 -0800 (PST) (envelope-from dillon) Date: Fri, 7 Dec 2001 19:49:32 -0800 (PST) From: Matthew Dillon Message-Id: <200112080349.fB83nWU00292@apollo.backplane.com> To: Garance A Drosihn Cc: "Louis A. Mamakos" , Sheldon Hearn , Kirk McKusick , freebsd-arch@FreeBSD.ORG Subject: Proposed auto-sizing patch to sysinstall (was Re: Using a larger block size on large filesystems) References: <31807.1007732134@axl.seasidesoftware.co.za> <200112072257.fB7MvjE95211@apollo.backplane.com> <200112072311.fB7NB2723789@whizzo.transsys.com> Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Ok, I've finally gone and done it... cleaned up the sysinstall 'Auto' option. The jist of it is that I have added a bunch of DEFAULT and NOMINAL partition sizes. DEFAULT is the target 'A'uto tries to achieve, but if the disk is not large enough it will loop and scale the auto partitions down based on a fraction of NOMINAL to DEFAULT. I added "vn" to libdisk (not in this patch, just so I could test) and did some tests and it appears to work quite well. (Note: if using the VN device for testing you have to use file-backed rather then swap-backed because sysinstall gets really confused when the sector size is not 512). I also added two more 'typical' partitions: /var/tmp, and /home. I have not done anything with /tmp yet but I recommend that we have sysinstall create a softlink /tmp -> /var/tmp. I also fixed auto mode to not create more then 4G of swap. Auto now attempts to create the following partitions: / 128M swap 2 x phys memory, 32MB minimum /var 128M /var/tmp 128M /usr 3G max /home all remaining space Of course, these are all #defines so we can argue about them separately from comments on the patchset itself. NOTE!! This code will scale sizes down to fit the disk. For example if you only have a 4G disk then /usr will wind up being around 1.5G and /home around 1.5G. My reasoning for the partition sizes: / 128M - Big enough to store a couple of debug kernels and not have make install trip over a softupdates root (at least if you don't run 'make install' twice in a row). swap Default: 2 x main memory, 32MB min. Nominal: 50% main memory (if the disk isn't big enough). /var 128M - lets discuss this. I would actually like to make /var larger if the disk itself is huge, because the mail boxes and spool is on /var. /var/tmp 128M. /usr 3G default size, 512M nominal. I've found 3G to be a good size. /usr requires a considerable amount of space if you install linux emulation, X11, and various (large) ports like KDE, a browser, Apache, and so forth. We do not have enough partition id's to make a separate /usr/local. /home 3G default size, 512M nominal, *ALL* remaining space if the disk is large enough. -Matt Index: install.c =================================================================== RCS file: /home/ncvs/src/release/sysinstall/Attic/install.c,v retrieving revision 1.268.2.29 diff -u -r1.268.2.29 install.c --- install.c 2001/10/26 08:26:34 1.268.2.29 +++ install.c 2001/12/08 02:42:03 @@ -66,12 +66,12 @@ static void installConfigure(void); Boolean -checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vdev) +checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vdev, Chunk **vtdev, Chunk **hdev) { Device **devs; Boolean status; Disk *disk; - Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev; + Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev, *vartmpdev, *homedev; int i; /* Don't allow whinging if noWarn is set */ @@ -79,7 +79,19 @@ whinge = FALSE; status = TRUE; - *rdev = *sdev = *udev = *vdev = rootdev = swapdev = usrdev = vardev = NULL; + if (rdev) + *rdev = NULL; + if (sdev) + *sdev = NULL; + if (udev) + *udev = NULL; + if (vdev) + *vdev = NULL; + if (vtdev) + *vtdev = NULL; + if (hdev) + *hdev = NULL; + rootdev = swapdev = usrdev = vardev = vartmpdev = homedev = NULL; /* We don't need to worry about root/usr/swap if we're already multiuser */ if (!RunningAsInit) @@ -136,6 +148,30 @@ if (isDebug()) msgDebug("Found vardev at %s!\n", vardev->name); } + } else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/var/tmp")) { + if (vartmpdev) { + if (whinge) + msgConfirm("WARNING: You have more than one /var/tmp filesystem.\n" + "Using the first one found."); + continue; + } + else { + vartmpdev = c2; + if (isDebug()) + msgDebug("Found vartmpdev at %s!\n", vartmpdev->name); + } + } else if (!strcmp(((PartInfo *)c2->private_data)->mountpoint, "/home")) { + if (homedev) { + if (whinge) + msgConfirm("WARNING: You have more than one /home filesystem.\n" + "Using the first one found."); + continue; + } + else { + homedev = c2; + if (isDebug()) + msgDebug("Found homedev at %s!\n", homedev->name); + } } } } @@ -166,10 +202,18 @@ } /* Copy our values over */ - *rdev = rootdev; - *sdev = swapdev; - *udev = usrdev; - *vdev = vardev; + if (rdev) + *rdev = rootdev; + if (sdev) + *sdev = swapdev; + if (udev) + *udev = usrdev; + if (vdev) + *vdev = vardev; + if (vtdev) + *vtdev = vartmpdev; + if (hdev) + *hdev = homedev; if (!rootdev && whinge) { msgConfirm("No root device found - you must label a partition as /\n" @@ -868,7 +912,7 @@ { int i; Disk *disk; - Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev; + Chunk *c1, *c2, *rootdev, *swapdev; Device **devs; PartInfo *root; char dname[80]; @@ -880,7 +924,7 @@ return DITEM_SUCCESS; upgrade = !variable_cmp(SYSTEM_STATE, "upgrade"); - if (!checkLabels(TRUE, &rootdev, &swapdev, &usrdev, &vardev)) + if (!checkLabels(TRUE, &rootdev, &swapdev, NULL, NULL, NULL, NULL)) return DITEM_FAILURE; if (rootdev) Index: label.c =================================================================== RCS file: /home/ncvs/src/release/sysinstall/Attic/label.c,v retrieving revision 1.98.2.5 diff -u -r1.98.2.5 label.c --- label.c 2001/05/09 08:00:30 1.98.2.5 +++ label.c 2001/12/08 03:43:38 @@ -54,29 +54,47 @@ /* The smallest filesystem we're willing to create */ #define FS_MIN_SIZE ONE_MEG -/* The smallest root filesystem we're willing to create */ +/* + * Minimum partition sizes + */ #ifdef __alpha__ #define ROOT_MIN_SIZE 40 #else #define ROOT_MIN_SIZE 30 #endif - -/* The default root filesystem size */ -#ifdef __alpha__ -#define ROOT_DEFAULT_SIZE 110 -#else -#define ROOT_DEFAULT_SIZE 100 -#endif - -/* The smallest swap partition we want to create by default */ #define SWAP_MIN_SIZE 32 - -/* The smallest /usr partition we're willing to create by default */ #define USR_MIN_SIZE 80 - -/* The smallest /var partition we're willing to create by default */ #define VAR_MIN_SIZE 20 +#define VARTMP_MIN_SIZE 20 +#define HOME_MIN_SIZE 20 +/* + * Swap size limit for auto-partitioning + */ +#define SWAP_AUTO_LIMIT_SIZE 4096 + +/* + * Default partition sizes. If we do not have sufficient disk space + * for this configuration we scale things relative to the NOM vs DEFAULT + * sizes. If the disk is larger then /home will get any remaining space. + */ +#define ROOT_DEFAULT_SIZE 128 +#define USR_DEFAULT_SIZE 3072 +#define VAR_DEFAULT_SIZE 128 +#define VARTMP_DEFAULT_SIZE 128 +#define HOME_DEFAULT_SIZE USR_DEFAULT_SIZE + +/* + * Nominal partition sizes. These are used to scale the default sizes down + * when we have insufficient disk space. If this isn't sufficient we scale + * down using the MIN sizes instead. + */ +#define ROOT_NOMINAL_SIZE 128 +#define USR_NOMINAL_SIZE 512 +#define VAR_NOMINAL_SIZE 64 +#define VARTMP_NOMINAL_SIZE 64 +#define HOME_NOMINAL_SIZE USR_NOMINAL_SIZE + /* The bottom-most row we're allowed to scribble on */ #define CHUNK_ROW_MAX 16 @@ -93,6 +111,7 @@ static int diskLabel(Device *dev); static int diskLabelNonInteractive(Device *dev); +static char *try_auto_label(Device **devs, Device *dev, int perc, int *req); static int labelHook(dialogMenuItem *selected) @@ -781,110 +800,23 @@ msg = "You can only do this in a disk slice (at top of screen)"; break; } - sz = space_free(label_chunk_info[here].c); - if (sz <= FS_MIN_SIZE) - msg = "Not enough free space to create a new partition in the slice"; - else { - struct chunk *tmp; - int mib[2]; - int physmem; - size_t size, swsize; - char *cp; - Chunk *rootdev, *swapdev, *usrdev, *vardev; - - (void)checkLabels(FALSE, &rootdev, &swapdev, &usrdev, &vardev); - if (!rootdev) { - cp = variable_get(VAR_ROOT_SIZE); - tmp = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, - (cp ? atoi(cp) : ROOT_DEFAULT_SIZE) * ONE_MEG, part, FS_BSDFFS, CHUNK_IS_ROOT); - if (!tmp) { - msgConfirm("Unable to create the root partition. Too big?"); - clear_wins(); - break; - } - tmp->private_data = new_part("/", TRUE, tmp->size); - tmp->private_free = safe_free; - record_label_chunks(devs, dev); - } - - if (!swapdev) { - cp = variable_get(VAR_SWAP_SIZE); - if (cp) - swsize = atoi(cp) * ONE_MEG; - else { - mib[0] = CTL_HW; - mib[1] = HW_PHYSMEM; - size = sizeof physmem; - sysctl(mib, 2, &physmem, &size, (void *)0, (size_t)0); - swsize = 16 * ONE_MEG + (physmem * 2 / 512); - } - tmp = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, - swsize, part, FS_SWAP, 0); - if (!tmp) { - msgConfirm("Unable to create the swap partition. Too big?"); - clear_wins(); + { + int perc; + int req; + + req = 0; + for (perc = 100; perc > 0; perc -= 10) { + req = 0; /* reset for each loop */ + if ((msg = try_auto_label(devs, dev, perc, &req)) == NULL) break; - } - tmp->private_data = 0; - tmp->private_free = safe_free; - record_label_chunks(devs, dev); } - - if (!vardev) { - cp = variable_get(VAR_VAR_SIZE); - if (cp) - sz = atoi(cp) * ONE_MEG; - else - sz = variable_get(VAR_NO_USR) - ? space_free(label_chunk_info[here].c) - : VAR_MIN_SIZE * ONE_MEG; - - tmp = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, - sz, part, FS_BSDFFS, 0); - if (!tmp) { - msgConfirm("Less than %dMB free for /var - you will need to\n" - "partition your disk manually with a custom install!", - (cp ? atoi(cp) : VAR_MIN_SIZE)); + if (msg) { + if (req) { + msgConfirm(msg); clear_wins(); - break; - } - tmp->private_data = new_part("/var", TRUE, tmp->size); - tmp->private_free = safe_free; - record_label_chunks(devs, dev); - } - - if (!usrdev && !variable_get(VAR_NO_USR)) { - cp = variable_get(VAR_USR_SIZE); - if (cp) - sz = atoi(cp) * ONE_MEG; - else - sz = space_free(label_chunk_info[here].c); - if (sz) { - if (sz < (USR_MIN_SIZE * ONE_MEG)) { - msgConfirm("Less than %dMB free for /usr - you will need to\n" - "partition your disk manually with a custom install!", USR_MIN_SIZE); - clear_wins(); - break; - } - - tmp = Create_Chunk_DWIM(label_chunk_info[here].c->disk, - label_chunk_info[here].c, - sz, part, FS_BSDFFS, 0); - if (!tmp) { - msgConfirm("Unable to create the /usr partition. Not enough space?\n" - "You will need to partition your disk manually with a custom install!"); - clear_wins(); - break; - } - tmp->private_data = new_part("/usr", TRUE, tmp->size); - tmp->private_free = safe_free; - record_label_chunks(devs, dev); + msg = NULL; } } - - /* At this point, we're reasonably "labelled" */ - if (variable_cmp(DISK_LABELLED, "written")) - variable_set2(DISK_LABELLED, "yes", 0); } break; @@ -1172,6 +1104,189 @@ } restorescr(w); return DITEM_SUCCESS; +} + +static __inline int +requested_part_size(char *varName, int nom, int def, int perc) +{ + char *cp; + int sz; + + if ((cp = variable_get(VAR_ROOT_SIZE)) != NULL) + sz = atoi(cp); + else + sz = nom + (def - nom) * perc / 100; + return(sz * ONE_MEG); +} + +static char * +try_auto_label(Device **devs, Device *dev, int perc, int *req) +{ + int sz; + struct chunk *root_chunk = NULL; + struct chunk *swap_chunk = NULL; + struct chunk *usr_chunk = NULL; + struct chunk *var_chunk = NULL; + struct chunk *vartmp_chunk = NULL; + struct chunk *home_chunk = NULL; + int mib[2]; + unsigned int physmem; + size_t size; + Chunk *rootdev, *swapdev, *usrdev, *vardev; + Chunk *vartmpdev, *homedev; + char *msg = NULL; + + sz = space_free(label_chunk_info[here].c); + if (sz <= FS_MIN_SIZE) + return("Not enough free space to create a new partition in the slice"); + + (void)checkLabels(FALSE, &rootdev, &swapdev, &usrdev, + &vardev, &vartmpdev, &homedev); + if (!rootdev) { + sz = requested_part_size(VAR_ROOT_SIZE, ROOT_NOMINAL_SIZE, ROOT_DEFAULT_SIZE, perc); + + root_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, + sz, part, FS_BSDFFS, CHUNK_IS_ROOT); + if (!root_chunk) { + *req = 1; + msg = "Unable to create the root partition. Too big?"; + goto done; + } + root_chunk->private_data = new_part("/", TRUE, root_chunk->size); + root_chunk->private_free = safe_free; + record_label_chunks(devs, dev); + } + if (!swapdev) { + sz = requested_part_size(VAR_SWAP_SIZE, 0, 0, perc); + if (sz == 0) { + int nom; + int def; + + mib[0] = CTL_HW; + mib[1] = HW_PHYSMEM; + size = sizeof physmem; + sysctl(mib, 2, &physmem, &size, (void *)0, (size_t)0); + def = 2 * (int)(physmem / 512); + if (def < SWAP_MIN_SIZE * ONE_MEG) + def = SWAP_MIN_SIZE * ONE_MEG; + if (def > SWAP_AUTO_LIMIT_SIZE * ONE_MEG) + def = SWAP_AUTO_LIMIT_SIZE * ONE_MEG; + nom = (int)(physmem / 512) / 2; + sz = nom + (def - nom) * perc / 100; + } + swap_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, + sz, part, FS_SWAP, 0); + if (!swap_chunk) { + *req = 1; + msg = "Unable to create the swap partition. Too big?"; + goto done; + } + swap_chunk->private_data = 0; + swap_chunk->private_free = safe_free; + record_label_chunks(devs, dev); + } + if (!vardev) { + sz = requested_part_size(VAR_VAR_SIZE, VAR_NOMINAL_SIZE, VAR_DEFAULT_SIZE, perc); + + var_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, + sz, part, FS_BSDFFS, 0); + if (!var_chunk) { + *req = 1; + msg = "Not enough free space for /var - you will need to\n" + "partition your disk manually with a custom install!"; + goto done; + } + var_chunk->private_data = new_part("/var", TRUE, var_chunk->size); + var_chunk->private_free = safe_free; + record_label_chunks(devs, dev); + } + if (!vartmpdev && !variable_get(VAR_NO_VARTMP)) { + sz = requested_part_size(VAR_VARTMP_SIZE, VARTMP_NOMINAL_SIZE, VARTMP_DEFAULT_SIZE, perc); + + vartmp_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, label_chunk_info[here].c, + sz, part, FS_BSDFFS, 0); + if (!vartmp_chunk) { + *req = 1; + msg = "Not enough free space for /var/tmp - you will need to\n" + "partition your disk manually with a custom install!"; + goto done; + } + vartmp_chunk->private_data = new_part("/var/tmp", TRUE, vartmp_chunk->size); + vartmp_chunk->private_free = safe_free; + record_label_chunks(devs, dev); + } + if (!usrdev && !variable_get(VAR_NO_USR)) { + sz = requested_part_size(VAR_USR_SIZE, USR_NOMINAL_SIZE, USR_DEFAULT_SIZE, perc); +#if 0 + sz = space_free(label_chunk_info[here].c); +#endif + if (sz) { + if (sz < (USR_MIN_SIZE * ONE_MEG)) { + *req = 1; + msg = "Not enough free space for /usr - you will need to\n" + "partition your disk manually with a custom install!"; + } + + usr_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, + label_chunk_info[here].c, + sz, part, FS_BSDFFS, 0); + if (!usr_chunk) { + msg = "Unable to create the /usr partition. Not enough space?\n" + "You will need to partition your disk manually with a custom install!"; + goto done; + } + usr_chunk->private_data = new_part("/usr", TRUE, usr_chunk->size); + usr_chunk->private_free = safe_free; + record_label_chunks(devs, dev); + } + } + if (!homedev && !variable_get(VAR_NO_HOME)) { + sz = requested_part_size(VAR_HOME_SIZE, HOME_NOMINAL_SIZE, HOME_DEFAULT_SIZE, perc); + if (sz < space_free(label_chunk_info[here].c)) + sz = space_free(label_chunk_info[here].c); + if (sz) { + if (sz < (HOME_MIN_SIZE * ONE_MEG)) { + *req = 1; + msg = "Not enough free space for /home - you will need to\n" + "partition your disk manually with a custom install!"; + goto done; + } + + home_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, + label_chunk_info[here].c, + sz, part, FS_BSDFFS, 0); + if (!home_chunk) { + msg = "Unable to create the /home partition. Not enough space?\n" + "You will need to partition your disk manually with a custom install!"; + goto done; + } + home_chunk->private_data = new_part("/home", TRUE, home_chunk->size); + home_chunk->private_free = safe_free; + record_label_chunks(devs, dev); + } + } + + /* At this point, we're reasonably "labelled" */ + if (variable_cmp(DISK_LABELLED, "written")) + variable_set2(DISK_LABELLED, "yes", 0); + +done: + if (msg) { + if (root_chunk) + Delete_Chunk(root_chunk->disk, root_chunk); + if (swap_chunk) + Delete_Chunk(swap_chunk->disk, swap_chunk); + if (var_chunk) + Delete_Chunk(var_chunk->disk, var_chunk); + if (vartmp_chunk) + Delete_Chunk(vartmp_chunk->disk, vartmp_chunk); + if (usr_chunk) + Delete_Chunk(usr_chunk->disk, usr_chunk); + if (home_chunk) + Delete_Chunk(home_chunk->disk, home_chunk); + record_label_chunks(devs, dev); + } + return(msg); } static int Index: sysinstall.h =================================================================== RCS file: /home/ncvs/src/release/sysinstall/Attic/sysinstall.h,v retrieving revision 1.186.2.25 diff -u -r1.186.2.25 sysinstall.h --- sysinstall.h 2001/10/26 09:25:01 1.186.2.25 +++ sysinstall.h 2001/12/08 02:22:31 @@ -150,6 +150,8 @@ #define VAR_NO_HOLOSHELL "noHoloShell" #define VAR_NO_WARN "noWarn" #define VAR_NO_USR "noUsr" +#define VAR_NO_VARTMP "noVarTmp" +#define VAR_NO_HOME "noHome" #define VAR_NONINTERACTIVE "nonInteractive" #define VAR_NOVELL "novell" #define VAR_NTPDATE_FLAGS "ntpdate_flags" @@ -174,6 +176,8 @@ #define VAR_UFS_PATH "ufs" #define VAR_USR_SIZE "usrSize" #define VAR_VAR_SIZE "varSize" +#define VAR_VARTMP_SIZE "varTmpSize" +#define VAR_HOME_SIZE "homeSize" #define VAR_XF86_CONFIG "_xf86config" #define VAR_TERM "TERM" @@ -572,7 +576,7 @@ PkgNodePtr index_search(PkgNodePtr top, char *str, PkgNodePtr *tp); /* install.c */ -extern Boolean checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vdev); +extern Boolean checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vdev, Chunk **vtdev, Chunk **hdev); extern int installCommit(dialogMenuItem *self); extern int installCustomCommit(dialogMenuItem *self); extern int installExpress(dialogMenuItem *self); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message