From 23f188e63acfdb4be7d49c99f3ad5477b09f320e Mon Sep 17 00:00:00 2001 From: nwhitehorn Date: Sun, 20 Jan 2013 22:25:58 +0000 Subject: 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 --- usr.sbin/bsdinstall/partedit/Makefile | 5 +- usr.sbin/bsdinstall/partedit/partedit.c | 14 ++- usr.sbin/bsdinstall/partedit/partedit.h | 1 + usr.sbin/bsdinstall/partedit/scripted.c | 205 ++++++++++++++++++++++++++++++++ 4 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 usr.sbin/bsdinstall/partedit/scripted.c (limited to 'usr.sbin/bsdinstall/partedit') 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 +#include +#include +#include + +#include +#include +#include + +#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); +} + -- cgit v1.1