summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2001-12-09 09:47:09 +0000
committerdillon <dillon@FreeBSD.org>2001-12-09 09:47:09 +0000
commit3824d202d7975b7fa60b86b36924f7a0d3617da8 (patch)
treefdc035e8ee538d31ed15cd57e1153a54edd35b31 /usr.sbin
parentbe4cbfd0296b742e019aae13b2d1be2267760cef (diff)
downloadFreeBSD-src-3824d202d7975b7fa60b86b36924f7a0d3617da8.zip
FreeBSD-src-3824d202d7975b7fa60b86b36924f7a0d3617da8.tar.gz
Cleanup sysinstall's 'A'uto partitioning mode to provide more reasonable
defaults both in regards to the size of the partitions that are created and in regards to safety and functional separation. Still TODO: extend the previous partition to cover a deleted partition if the previous partiton was auto-created, and supply some sort of solution for /tmp. Reviewed by: Just about everyone Approved by: Nobody except maybe my pet mouse fred Obtained from: God, so complain to HIM MFC after: 1 week
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/sade/install.c62
-rw-r--r--usr.sbin/sade/label.c355
-rw-r--r--usr.sbin/sade/sade.h6
-rw-r--r--usr.sbin/sysinstall/install.c62
-rw-r--r--usr.sbin/sysinstall/label.c355
-rw-r--r--usr.sbin/sysinstall/sysinstall.h6
6 files changed, 602 insertions, 244 deletions
diff --git a/usr.sbin/sade/install.c b/usr.sbin/sade/install.c
index 6b5a6b1..468b202 100644
--- a/usr.sbin/sade/install.c
+++ b/usr.sbin/sade/install.c
@@ -66,12 +66,12 @@ static void fixit_common(void);
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 @@ checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vd
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 @@ checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vd
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 @@ checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vd
}
/* 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"
@@ -851,7 +895,7 @@ installFilesystems(dialogMenuItem *self)
{
int i, mountfailed;
Disk *disk;
- Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev;
+ Chunk *c1, *c2, *rootdev, *swapdev;
Device **devs;
PartInfo *root;
char dname[80];
@@ -863,7 +907,7 @@ installFilesystems(dialogMenuItem *self)
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)
diff --git a/usr.sbin/sade/label.c b/usr.sbin/sade/label.c
index 5404541..39ed48c 100644
--- a/usr.sbin/sade/label.c
+++ b/usr.sbin/sade/label.c
@@ -54,28 +54,46 @@
/* 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 120
-#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 (4G).
+ */
+#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 256
+#define VARTMP_DEFAULT_SIZE 256
+#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 label_focus = 0, pslice_focus = 0;
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,27 @@ diskLabel(Device *dev)
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);
- }
+ /*
+ * Generate standard partitions automatically. If we do not
+ * have sufficient space we attempt to scale-down the size
+ * of the partitions within certain bounds.
+ */
+ {
+ int perc;
+ int req = 0;
- 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();
+ for (perc = 100; perc > 0; perc -= 5) {
+ 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;
+ msg = NULL;
}
- 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);
- }
- }
-
- /* At this point, we're reasonably "labelled" */
- if (variable_cmp(DISK_LABELLED, "written"))
- variable_set2(DISK_LABELLED, "yes", 0);
}
break;
@@ -1196,6 +1132,201 @@ diskLabel(Device *dev)
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);
+}
+
+/*
+ * Attempt to auto-label the disk. 'perc' (0-100) scales
+ * the size of the various partitions within appropriate
+ * bounds (NOMINAL through DEFAULT sizes). The procedure
+ * succeeds of NULL is returned. A non-null return message
+ * is either a failure-status message (*req == 0), or
+ * a confirmation requestor (*req == 1). *req is 0 on
+ * entry to this call.
+ *
+ * We autolabel the following partitions: /, swap, /var, /var/tmp, /usr,
+ * and /home. /home receives any extra left over disk space.
+ */
+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
diskLabelNonInteractive(Device *dev)
{
diff --git a/usr.sbin/sade/sade.h b/usr.sbin/sade/sade.h
index cc40882..7b91191 100644
--- a/usr.sbin/sade/sade.h
+++ b/usr.sbin/sade/sade.h
@@ -149,6 +149,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"
@@ -173,6 +175,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"
#define VAR_CONSTERM "_consterm"
@@ -573,7 +577,7 @@ int index_initialize(char *path);
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);
diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c
index 6b5a6b1..468b202 100644
--- a/usr.sbin/sysinstall/install.c
+++ b/usr.sbin/sysinstall/install.c
@@ -66,12 +66,12 @@ static void fixit_common(void);
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 @@ checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vd
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 @@ checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vd
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 @@ checkLabels(Boolean whinge, Chunk **rdev, Chunk **sdev, Chunk **udev, Chunk **vd
}
/* 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"
@@ -851,7 +895,7 @@ installFilesystems(dialogMenuItem *self)
{
int i, mountfailed;
Disk *disk;
- Chunk *c1, *c2, *rootdev, *swapdev, *usrdev, *vardev;
+ Chunk *c1, *c2, *rootdev, *swapdev;
Device **devs;
PartInfo *root;
char dname[80];
@@ -863,7 +907,7 @@ installFilesystems(dialogMenuItem *self)
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)
diff --git a/usr.sbin/sysinstall/label.c b/usr.sbin/sysinstall/label.c
index 5404541..39ed48c 100644
--- a/usr.sbin/sysinstall/label.c
+++ b/usr.sbin/sysinstall/label.c
@@ -54,28 +54,46 @@
/* 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 120
-#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 (4G).
+ */
+#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 256
+#define VARTMP_DEFAULT_SIZE 256
+#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 label_focus = 0, pslice_focus = 0;
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,27 @@ diskLabel(Device *dev)
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);
- }
+ /*
+ * Generate standard partitions automatically. If we do not
+ * have sufficient space we attempt to scale-down the size
+ * of the partitions within certain bounds.
+ */
+ {
+ int perc;
+ int req = 0;
- 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();
+ for (perc = 100; perc > 0; perc -= 5) {
+ 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;
+ msg = NULL;
}
- 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);
- }
- }
-
- /* At this point, we're reasonably "labelled" */
- if (variable_cmp(DISK_LABELLED, "written"))
- variable_set2(DISK_LABELLED, "yes", 0);
}
break;
@@ -1196,6 +1132,201 @@ diskLabel(Device *dev)
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);
+}
+
+/*
+ * Attempt to auto-label the disk. 'perc' (0-100) scales
+ * the size of the various partitions within appropriate
+ * bounds (NOMINAL through DEFAULT sizes). The procedure
+ * succeeds of NULL is returned. A non-null return message
+ * is either a failure-status message (*req == 0), or
+ * a confirmation requestor (*req == 1). *req is 0 on
+ * entry to this call.
+ *
+ * We autolabel the following partitions: /, swap, /var, /var/tmp, /usr,
+ * and /home. /home receives any extra left over disk space.
+ */
+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
diskLabelNonInteractive(Device *dev)
{
diff --git a/usr.sbin/sysinstall/sysinstall.h b/usr.sbin/sysinstall/sysinstall.h
index cc40882..7b91191 100644
--- a/usr.sbin/sysinstall/sysinstall.h
+++ b/usr.sbin/sysinstall/sysinstall.h
@@ -149,6 +149,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"
@@ -173,6 +175,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"
#define VAR_CONSTERM "_consterm"
@@ -573,7 +577,7 @@ int index_initialize(char *path);
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);
OpenPOWER on IntegriCloud