summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2013-01-20 22:25:58 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2013-01-20 22:25:58 +0000
commit23f188e63acfdb4be7d49c99f3ad5477b09f320e (patch)
tree824b79fc3544ba9f92e5e9ed0339b11570b8174e
parent16ff7601a62477a9a6e67e96a511a1c6184119d2 (diff)
downloadFreeBSD-src-23f188e63acfdb4be7d49c99f3ad5477b09f320e.zip
FreeBSD-src-23f188e63acfdb4be7d49c99f3ad5477b09f320e.tar.gz
Add a simple scripted partitioner. Documentation and more scripting support
will come soon. This lets the install process have a line like: bsdinstall scriptedpart 'ada0 GPT {1.5G freebsd-ufs /, 10G freebsd-swap, auto freebsd-ufs /usr}' to set up a system with a 1.5GB /, some swap space, and a /usr using the rest of ada0. MFC after: 1 month
-rw-r--r--usr.sbin/bsdinstall/partedit/Makefile5
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit.c14
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit.h1
-rw-r--r--usr.sbin/bsdinstall/partedit/scripted.c205
4 files changed, 222 insertions, 3 deletions
diff --git a/usr.sbin/bsdinstall/partedit/Makefile b/usr.sbin/bsdinstall/partedit/Makefile
index 21eaf91..b7f5097 100644
--- a/usr.sbin/bsdinstall/partedit/Makefile
+++ b/usr.sbin/bsdinstall/partedit/Makefile
@@ -2,7 +2,8 @@
BINDIR= /usr/libexec/bsdinstall
PROG= partedit
-LINKS= ${BINDIR}/partedit ${BINDIR}/autopart
+LINKS= ${BINDIR}/partedit ${BINDIR}/autopart \
+ ${BINDIR}/partedit ${BINDIR}/scriptedpart
SYMLINKS= ${BINDIR}/partedit /usr/sbin/sade
LDADD= -lgeom -lncursesw -lutil -ldialog -lm
@@ -15,7 +16,7 @@ PARTEDIT_ARCH= generic
.endif
SRCS= diskeditor.c partedit.c gpart_ops.c partedit_${PARTEDIT_ARCH}.c \
- part_wizard.c
+ part_wizard.c scripted.c
WARNS?= 3
MAN= sade.8
diff --git a/usr.sbin/bsdinstall/partedit/partedit.c b/usr.sbin/bsdinstall/partedit/partedit.c
index d470c80..296d45c 100644
--- a/usr.sbin/bsdinstall/partedit/partedit.c
+++ b/usr.sbin/bsdinstall/partedit/partedit.c
@@ -96,13 +96,16 @@ main(int argc, const char **argv)
prompt = "Please review the disk setup. When complete, press "
"the Finish button.";
part_wizard();
+ } else if (strcmp(basename(argv[0]), "scriptedpart") == 0) {
+ scripted_editor(argc, argv);
+ prompt = NULL;
} else {
prompt = "Create partitions for FreeBSD. No changes will be "
"made until you select Finish.";
}
/* Show the part editor either immediately, or to confirm wizard */
- while (1) {
+ while (prompt != NULL) {
dlg_clear();
dlg_put_backtitle();
@@ -189,6 +192,15 @@ main(int argc, const char **argv)
free(items);
}
+ if (prompt == NULL) {
+ error = geom_gettree(&mesh);
+ if (validate_setup()) {
+ error = apply_changes(&mesh);
+ } else {
+ gpart_revert_all(&mesh);
+ error = -1;
+ }
+ }
geom_deletetree(&mesh);
free(items);
diff --git a/usr.sbin/bsdinstall/partedit/partedit.h b/usr.sbin/bsdinstall/partedit/partedit.h
index bffb076..136d187 100644
--- a/usr.sbin/bsdinstall/partedit/partedit.h
+++ b/usr.sbin/bsdinstall/partedit/partedit.h
@@ -55,6 +55,7 @@ struct partition_metadata *get_part_metadata(const char *name, int create);
void delete_part_metadata(const char *name);
int part_wizard(void);
+int scripted_editor(int argc, const char **argv);
/* gpart operations */
void gpart_delete(struct gprovider *pp);
diff --git a/usr.sbin/bsdinstall/partedit/scripted.c b/usr.sbin/bsdinstall/partedit/scripted.c
new file mode 100644
index 0000000..b498641
--- /dev/null
+++ b/usr.sbin/bsdinstall/partedit/scripted.c
@@ -0,0 +1,205 @@
+/*-
+ * Copyright (c) 2013 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <errno.h>
+#include <libutil.h>
+#include <inttypes.h>
+
+#include <libgeom.h>
+#include <dialog.h>
+#include <dlg_keys.h>
+
+#include "partedit.h"
+
+static struct gprovider *
+provider_for_name(struct gmesh *mesh, const char *name)
+{
+ struct gclass *classp;
+ struct gprovider *pp = NULL;
+ struct ggeom *gp;
+
+ LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
+ if (strcmp(classp->lg_name, "DISK") != 0 &&
+ strcmp(classp->lg_name, "PART") != 0 &&
+ strcmp(classp->lg_name, "RAID") != 0 &&
+ strcmp(classp->lg_name, "MD") != 0)
+ continue;
+
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ if (LIST_EMPTY(&gp->lg_provider))
+ continue;
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider)
+ if (strcmp(pp->lg_name, name) == 0)
+ break;
+
+ if (pp != NULL) break;
+ }
+
+ if (pp != NULL) break;
+ }
+
+ return (pp);
+}
+
+static int
+part_config(char *disk, const char *scheme, char *config)
+{
+ char *partition, *ap, *size = NULL, *type = NULL, *mount = NULL;
+ struct gclass *classp;
+ struct gmesh mesh;
+ struct ggeom *gpart = NULL;
+ int error;
+
+ if (scheme == NULL)
+ scheme = default_scheme();
+
+ error = geom_gettree(&mesh);
+
+ /* Remove any existing partitioning and create new scheme */
+ LIST_FOREACH(classp, &mesh.lg_class, lg_class)
+ if (strcmp(classp->lg_name, "PART") == 0)
+ break;
+ if (classp != NULL) {
+ LIST_FOREACH(gpart, &classp->lg_geom, lg_geom)
+ if (strcmp(gpart->lg_name, disk) == 0)
+ break;
+ }
+ if (gpart != NULL)
+ gpart_destroy(gpart);
+ gpart_partition(disk, scheme);
+
+ if (strcmp(scheme, "PC98") == 0 || strcmp(scheme, "MBR") == 0) {
+ struct gmesh submesh;
+ geom_gettree(&submesh);
+ gpart_create(provider_for_name(&submesh, disk),
+ "freebsd", NULL, NULL, &disk, 0);
+ geom_deletetree(&submesh);
+ } else {
+ disk= strdup(disk);
+ }
+
+ geom_deletetree(&mesh);
+ error = geom_gettree(&mesh);
+
+ /* Create partitions */
+ while ((partition = strsep(&config, ",")) != NULL) {
+ while ((ap = strsep(&partition, " \t\n")) != NULL) {
+ if (*ap == '\0')
+ continue;
+ if (size == NULL)
+ size = ap;
+ else if (type == NULL)
+ type = ap;
+ else if (mount == NULL)
+ mount = ap;
+ }
+ if (size == NULL)
+ continue;
+ if (strcmp(size, "auto") == 0)
+ size = NULL;
+ gpart_create(provider_for_name(&mesh, disk), type, size, mount,
+ NULL, 0);
+ geom_deletetree(&mesh);
+ error = geom_gettree(&mesh);
+ size = type = mount = NULL;
+ }
+
+ geom_deletetree(&mesh);
+ free(disk);
+
+ return (0);
+}
+
+static
+int parse_disk_config(char *input)
+{
+ char *ap;
+ char *disk = NULL, *scheme = NULL, *partconfig = NULL;
+
+ while (input != NULL && *input != 0) {
+ if (isspace(*input)) {
+ input++;
+ continue;
+ }
+
+ switch(*input) {
+ case '{':
+ input++;
+ partconfig = strchr(input, '}');
+ if (partconfig == NULL) {
+ fprintf(stderr, "Malformed partition setup "
+ "string: %s\n", input);
+ return (1);
+ }
+ *partconfig = '\0';
+ ap = partconfig+1;
+ partconfig = input;
+ input = ap;
+ break;
+ default:
+ if (disk == NULL)
+ disk = strsep(&input, " \t\n");
+ else if (scheme == NULL)
+ scheme = strsep(&input, " \t\n");
+ else {
+ fprintf(stderr, "Unknown directive: %s\n",
+ strsep(&input, " \t\n"));
+ return (1);
+ }
+ }
+ } while (input != NULL && *input != 0);
+
+ if (disk != NULL)
+ part_config(disk, scheme, partconfig);
+
+ return (0);
+}
+
+int
+scripted_editor(int argc, const char **argv)
+{
+ char *token;
+ int i, len = 0;
+
+ for (i = 1; i < argc; i++)
+ len += strlen(argv[i]) + 1;
+ char inputbuf[len], *input = inputbuf;
+ strcpy(input, argv[1]);
+ for (i = 2; i < argc; i++) {
+ strcat(input, " ");
+ strcat(input, argv[i]);
+ }
+
+ while ((token = strsep(&input, ";")) != NULL)
+ parse_disk_config(token);
+
+ return (0);
+}
+
OpenPOWER on IntegriCloud