summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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