partedit.c revision 273831
1218799Snwhitehorn/*- 2218799Snwhitehorn * Copyright (c) 2011 Nathan Whitehorn 3218799Snwhitehorn * All rights reserved. 4218799Snwhitehorn * 5218799Snwhitehorn * Redistribution and use in source and binary forms, with or without 6218799Snwhitehorn * modification, are permitted provided that the following conditions 7218799Snwhitehorn * are met: 8218799Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9218799Snwhitehorn * notice, this list of conditions and the following disclaimer. 10218799Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11218799Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12218799Snwhitehorn * documentation and/or other materials provided with the distribution. 13218799Snwhitehorn * 14218799Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15218799Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16218799Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17218799Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18218799Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19218799Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20218799Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21218799Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22218799Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23218799Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24218799Snwhitehorn * SUCH DAMAGE. 25218799Snwhitehorn * 26218799Snwhitehorn * $FreeBSD: stable/10/usr.sbin/bsdinstall/partedit/partedit.c 273831 2014-10-29 16:48:18Z nwhitehorn $ 27218799Snwhitehorn */ 28218799Snwhitehorn 29218799Snwhitehorn#include <sys/param.h> 30218799Snwhitehorn#include <libgen.h> 31218799Snwhitehorn#include <libutil.h> 32218799Snwhitehorn#include <inttypes.h> 33218799Snwhitehorn#include <errno.h> 34218799Snwhitehorn 35218799Snwhitehorn#include <fstab.h> 36218799Snwhitehorn#include <libgeom.h> 37218799Snwhitehorn#include <dialog.h> 38218799Snwhitehorn#include <dlg_keys.h> 39218799Snwhitehorn 40218799Snwhitehorn#include "diskeditor.h" 41218799Snwhitehorn#include "partedit.h" 42218799Snwhitehorn 43218799Snwhitehornstruct pmetadata_head part_metadata; 44244858Snwhitehornstatic int sade_mode = 0; 45218799Snwhitehorn 46218799Snwhitehornstatic int apply_changes(struct gmesh *mesh); 47218799Snwhitehornstatic struct partedit_item *read_geom_mesh(struct gmesh *mesh, int *nitems); 48218799Snwhitehornstatic void add_geom_children(struct ggeom *gp, int recurse, 49218799Snwhitehorn struct partedit_item **items, int *nitems); 50218799Snwhitehornstatic void init_fstab_metadata(void); 51218799Snwhitehornstatic void get_mount_points(struct partedit_item *items, int nitems); 52218799Snwhitehornstatic int validate_setup(void); 53218799Snwhitehorn 54225066Snwhitehornstatic void 55225066Snwhitehornsigint_handler(int sig) 56225066Snwhitehorn{ 57225066Snwhitehorn struct gmesh mesh; 58225066Snwhitehorn 59225066Snwhitehorn /* Revert all changes and exit dialog-mode cleanly on SIGINT */ 60225066Snwhitehorn geom_gettree(&mesh); 61225066Snwhitehorn gpart_revert_all(&mesh); 62225066Snwhitehorn geom_deletetree(&mesh); 63225066Snwhitehorn 64225066Snwhitehorn end_dialog(); 65225066Snwhitehorn 66225066Snwhitehorn exit(1); 67225066Snwhitehorn} 68225066Snwhitehorn 69218799Snwhitehornint 70225066Snwhitehornmain(int argc, const char **argv) 71225066Snwhitehorn{ 72218799Snwhitehorn struct partition_metadata *md; 73218799Snwhitehorn const char *prompt; 74226739Snwhitehorn struct partedit_item *items = NULL; 75218799Snwhitehorn struct gmesh mesh; 76218799Snwhitehorn int i, op, nitems, nscroll; 77218799Snwhitehorn int error; 78218799Snwhitehorn 79244858Snwhitehorn if (strcmp(basename(argv[0]), "sade") == 0) 80244858Snwhitehorn sade_mode = 1; 81244858Snwhitehorn 82218799Snwhitehorn TAILQ_INIT(&part_metadata); 83218799Snwhitehorn 84218799Snwhitehorn init_fstab_metadata(); 85218799Snwhitehorn 86218799Snwhitehorn init_dialog(stdin, stdout); 87244858Snwhitehorn if (!sade_mode) 88218799Snwhitehorn dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); 89218799Snwhitehorn dialog_vars.item_help = TRUE; 90218799Snwhitehorn nscroll = i = 0; 91218799Snwhitehorn 92225066Snwhitehorn /* Revert changes on SIGINT */ 93225066Snwhitehorn signal(SIGINT, sigint_handler); 94225066Snwhitehorn 95218799Snwhitehorn if (strcmp(basename(argv[0]), "autopart") == 0) { /* Guided */ 96218799Snwhitehorn prompt = "Please review the disk setup. When complete, press " 97225066Snwhitehorn "the Finish button."; 98273831Snwhitehorn /* Experimental ZFS autopartition support */ 99273831Snwhitehorn if (argc > 1 && strcmp(argv[1], "zfs") == 0) { 100273831Snwhitehorn part_wizard("zfs"); 101273831Snwhitehorn } else { 102273831Snwhitehorn part_wizard("ufs"); 103273831Snwhitehorn } 104245700Snwhitehorn } else if (strcmp(basename(argv[0]), "scriptedpart") == 0) { 105245796Snwhitehorn error = scripted_editor(argc, argv); 106245700Snwhitehorn prompt = NULL; 107245796Snwhitehorn if (error != 0) { 108245796Snwhitehorn end_dialog(); 109245796Snwhitehorn return (error); 110245796Snwhitehorn } 111218799Snwhitehorn } else { 112218799Snwhitehorn prompt = "Create partitions for FreeBSD. No changes will be " 113225066Snwhitehorn "made until you select Finish."; 114218799Snwhitehorn } 115218799Snwhitehorn 116218799Snwhitehorn /* Show the part editor either immediately, or to confirm wizard */ 117245700Snwhitehorn while (prompt != NULL) { 118218799Snwhitehorn dlg_clear(); 119218799Snwhitehorn dlg_put_backtitle(); 120218799Snwhitehorn 121226739Snwhitehorn error = geom_gettree(&mesh); 122226739Snwhitehorn if (error == 0) 123226739Snwhitehorn items = read_geom_mesh(&mesh, &nitems); 124226739Snwhitehorn if (error || items == NULL) { 125226739Snwhitehorn dialog_msgbox("Error", "No disks found. If you need to " 126226739Snwhitehorn "install a kernel driver, choose Shell at the " 127226739Snwhitehorn "installation menu.", 0, 0, TRUE); 128226739Snwhitehorn break; 129226739Snwhitehorn } 130226739Snwhitehorn 131226739Snwhitehorn get_mount_points(items, nitems); 132226739Snwhitehorn 133218799Snwhitehorn if (i >= nitems) 134218799Snwhitehorn i = nitems - 1; 135218799Snwhitehorn op = diskeditor_show("Partition Editor", prompt, 136218799Snwhitehorn items, nitems, &i, &nscroll); 137218799Snwhitehorn 138218799Snwhitehorn switch (op) { 139218799Snwhitehorn case 0: /* Create */ 140218799Snwhitehorn gpart_create((struct gprovider *)(items[i].cookie), 141218799Snwhitehorn NULL, NULL, NULL, NULL, 1); 142218799Snwhitehorn break; 143218799Snwhitehorn case 1: /* Delete */ 144218799Snwhitehorn gpart_delete((struct gprovider *)(items[i].cookie)); 145218799Snwhitehorn break; 146218799Snwhitehorn case 2: /* Modify */ 147218799Snwhitehorn gpart_edit((struct gprovider *)(items[i].cookie)); 148218799Snwhitehorn break; 149218799Snwhitehorn case 3: /* Revert */ 150218799Snwhitehorn gpart_revert_all(&mesh); 151218799Snwhitehorn while ((md = TAILQ_FIRST(&part_metadata)) != NULL) { 152218799Snwhitehorn if (md->fstab != NULL) { 153218799Snwhitehorn free(md->fstab->fs_spec); 154218799Snwhitehorn free(md->fstab->fs_file); 155218799Snwhitehorn free(md->fstab->fs_vfstype); 156218799Snwhitehorn free(md->fstab->fs_mntops); 157218799Snwhitehorn free(md->fstab->fs_type); 158218799Snwhitehorn free(md->fstab); 159218799Snwhitehorn } 160218799Snwhitehorn if (md->newfs != NULL) 161218799Snwhitehorn free(md->newfs); 162218799Snwhitehorn free(md->name); 163218799Snwhitehorn 164218799Snwhitehorn TAILQ_REMOVE(&part_metadata, md, metadata); 165218799Snwhitehorn free(md); 166218799Snwhitehorn } 167218799Snwhitehorn init_fstab_metadata(); 168218799Snwhitehorn break; 169218799Snwhitehorn case 4: /* Auto */ 170273831Snwhitehorn part_wizard("ufs"); 171218799Snwhitehorn break; 172218799Snwhitehorn } 173218799Snwhitehorn 174218799Snwhitehorn error = 0; 175219391Snwhitehorn if (op == 5) { /* Finished */ 176225066Snwhitehorn dialog_vars.ok_label = __DECONST(char *, "Commit"); 177225066Snwhitehorn dialog_vars.extra_label = 178225066Snwhitehorn __DECONST(char *, "Revert & Exit"); 179218799Snwhitehorn dialog_vars.extra_button = TRUE; 180225066Snwhitehorn dialog_vars.cancel_label = __DECONST(char *, "Back"); 181218799Snwhitehorn op = dialog_yesno("Confirmation", "Your changes will " 182218799Snwhitehorn "now be written to disk. If you have chosen to " 183218799Snwhitehorn "overwrite existing data, it will be PERMANENTLY " 184225066Snwhitehorn "ERASED. Are you sure you want to commit your " 185225066Snwhitehorn "changes?", 0, 0); 186225066Snwhitehorn dialog_vars.ok_label = NULL; 187218799Snwhitehorn dialog_vars.extra_button = FALSE; 188225066Snwhitehorn dialog_vars.cancel_label = NULL; 189218799Snwhitehorn 190219391Snwhitehorn if (op == 0 && validate_setup()) { /* Save */ 191218799Snwhitehorn error = apply_changes(&mesh); 192218799Snwhitehorn break; 193225066Snwhitehorn } else if (op == 3) { /* Quit */ 194218799Snwhitehorn gpart_revert_all(&mesh); 195218799Snwhitehorn error = -1; 196218799Snwhitehorn break; 197218799Snwhitehorn } 198218799Snwhitehorn } 199218799Snwhitehorn 200218799Snwhitehorn geom_deletetree(&mesh); 201218799Snwhitehorn free(items); 202218799Snwhitehorn } 203218799Snwhitehorn 204245700Snwhitehorn if (prompt == NULL) { 205245700Snwhitehorn error = geom_gettree(&mesh); 206245700Snwhitehorn if (validate_setup()) { 207245700Snwhitehorn error = apply_changes(&mesh); 208245700Snwhitehorn } else { 209245700Snwhitehorn gpart_revert_all(&mesh); 210245700Snwhitehorn error = -1; 211245700Snwhitehorn } 212245700Snwhitehorn } 213218799Snwhitehorn 214218799Snwhitehorn geom_deletetree(&mesh); 215218799Snwhitehorn free(items); 216218799Snwhitehorn end_dialog(); 217218799Snwhitehorn 218218799Snwhitehorn return (error); 219218799Snwhitehorn} 220218799Snwhitehorn 221218799Snwhitehornstruct partition_metadata * 222218799Snwhitehornget_part_metadata(const char *name, int create) 223218799Snwhitehorn{ 224218799Snwhitehorn struct partition_metadata *md; 225218799Snwhitehorn 226218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) 227218799Snwhitehorn if (md->name != NULL && strcmp(md->name, name) == 0) 228218799Snwhitehorn break; 229218799Snwhitehorn 230218799Snwhitehorn if (md == NULL && create) { 231218799Snwhitehorn md = calloc(1, sizeof(*md)); 232218799Snwhitehorn md->name = strdup(name); 233218799Snwhitehorn TAILQ_INSERT_TAIL(&part_metadata, md, metadata); 234218799Snwhitehorn } 235218799Snwhitehorn 236218799Snwhitehorn return (md); 237218799Snwhitehorn} 238218799Snwhitehorn 239218799Snwhitehornvoid 240225066Snwhitehorndelete_part_metadata(const char *name) 241225066Snwhitehorn{ 242218799Snwhitehorn struct partition_metadata *md; 243218799Snwhitehorn 244218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 245218799Snwhitehorn if (md->name != NULL && strcmp(md->name, name) == 0) { 246218799Snwhitehorn if (md->fstab != NULL) { 247218799Snwhitehorn free(md->fstab->fs_spec); 248218799Snwhitehorn free(md->fstab->fs_file); 249218799Snwhitehorn free(md->fstab->fs_vfstype); 250218799Snwhitehorn free(md->fstab->fs_mntops); 251218799Snwhitehorn free(md->fstab->fs_type); 252218799Snwhitehorn free(md->fstab); 253218799Snwhitehorn } 254218799Snwhitehorn if (md->newfs != NULL) 255218799Snwhitehorn free(md->newfs); 256218799Snwhitehorn free(md->name); 257218799Snwhitehorn 258218799Snwhitehorn TAILQ_REMOVE(&part_metadata, md, metadata); 259218799Snwhitehorn free(md); 260218799Snwhitehorn break; 261218799Snwhitehorn } 262218799Snwhitehorn } 263218799Snwhitehorn} 264218799Snwhitehorn 265218799Snwhitehornstatic int 266218799Snwhitehornvalidate_setup(void) 267218799Snwhitehorn{ 268230309Snwhitehorn struct partition_metadata *md, *root = NULL; 269230309Snwhitehorn int cancel; 270218799Snwhitehorn 271218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 272218799Snwhitehorn if (md->fstab != NULL && strcmp(md->fstab->fs_file, "/") == 0) 273230309Snwhitehorn root = md; 274218799Snwhitehorn 275218799Snwhitehorn /* XXX: Check for duplicate mountpoints */ 276218799Snwhitehorn } 277218799Snwhitehorn 278230309Snwhitehorn if (root == NULL) { 279218799Snwhitehorn dialog_msgbox("Error", "No root partition was found. " 280218799Snwhitehorn "The root FreeBSD partition must have a mountpoint of '/'.", 281218799Snwhitehorn 0, 0, TRUE); 282218799Snwhitehorn return (FALSE); 283218799Snwhitehorn } 284218799Snwhitehorn 285230309Snwhitehorn /* 286230309Snwhitehorn * Check for root partitions that we aren't formatting, which is 287230309Snwhitehorn * usually a mistake 288230309Snwhitehorn */ 289244858Snwhitehorn if (root->newfs == NULL && !sade_mode) { 290230309Snwhitehorn dialog_vars.defaultno = TRUE; 291230309Snwhitehorn cancel = dialog_yesno("Warning", "The chosen root partition " 292230309Snwhitehorn "has a preexisting filesystem. If it contains an existing " 293230309Snwhitehorn "FreeBSD system, please update it with freebsd-update " 294230309Snwhitehorn "instead of installing a new system on it. The partition " 295230309Snwhitehorn "can also be erased by pressing \"No\" and then deleting " 296230309Snwhitehorn "and recreating it. Are you sure you want to proceed?", 297230309Snwhitehorn 0, 0); 298230309Snwhitehorn dialog_vars.defaultno = FALSE; 299230309Snwhitehorn if (cancel) 300230309Snwhitehorn return (FALSE); 301230309Snwhitehorn } 302230309Snwhitehorn 303218799Snwhitehorn return (TRUE); 304218799Snwhitehorn} 305218799Snwhitehorn 306218799Snwhitehornstatic int 307218799Snwhitehornapply_changes(struct gmesh *mesh) 308218799Snwhitehorn{ 309218799Snwhitehorn struct partition_metadata *md; 310218799Snwhitehorn char message[512]; 311218799Snwhitehorn int i, nitems, error; 312218799Snwhitehorn const char **items; 313218799Snwhitehorn const char *fstab_path; 314218799Snwhitehorn FILE *fstab; 315218799Snwhitehorn 316218799Snwhitehorn nitems = 1; /* Partition table changes */ 317218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 318218799Snwhitehorn if (md->newfs != NULL) 319218799Snwhitehorn nitems++; 320218799Snwhitehorn } 321218799Snwhitehorn items = calloc(nitems * 2, sizeof(const char *)); 322218799Snwhitehorn items[0] = "Writing partition tables"; 323218799Snwhitehorn items[1] = "7"; /* In progress */ 324218799Snwhitehorn i = 1; 325218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 326218799Snwhitehorn if (md->newfs != NULL) { 327218799Snwhitehorn char *item; 328218799Snwhitehorn item = malloc(255); 329218799Snwhitehorn sprintf(item, "Initializing %s", md->name); 330218799Snwhitehorn items[i*2] = item; 331218799Snwhitehorn items[i*2 + 1] = "Pending"; 332218799Snwhitehorn i++; 333218799Snwhitehorn } 334218799Snwhitehorn } 335218799Snwhitehorn 336218799Snwhitehorn i = 0; 337218799Snwhitehorn dialog_mixedgauge("Initializing", 338218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, i*100/nitems, 339218799Snwhitehorn nitems, __DECONST(char **, items)); 340218799Snwhitehorn gpart_commit(mesh); 341218799Snwhitehorn items[i*2 + 1] = "3"; 342218799Snwhitehorn i++; 343218799Snwhitehorn 344218799Snwhitehorn if (getenv("BSDINSTALL_LOG") == NULL) 345218799Snwhitehorn setenv("BSDINSTALL_LOG", "/dev/null", 1); 346218799Snwhitehorn 347218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 348218799Snwhitehorn if (md->newfs != NULL) { 349218799Snwhitehorn items[i*2 + 1] = "7"; /* In progress */ 350218799Snwhitehorn dialog_mixedgauge("Initializing", 351218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, 352218799Snwhitehorn i*100/nitems, nitems, __DECONST(char **, items)); 353218799Snwhitehorn sprintf(message, "(echo %s; %s) >>%s 2>>%s", 354218799Snwhitehorn md->newfs, md->newfs, getenv("BSDINSTALL_LOG"), 355218799Snwhitehorn getenv("BSDINSTALL_LOG")); 356218799Snwhitehorn error = system(message); 357218799Snwhitehorn items[i*2 + 1] = (error == 0) ? "3" : "1"; 358218799Snwhitehorn i++; 359218799Snwhitehorn } 360218799Snwhitehorn } 361218799Snwhitehorn dialog_mixedgauge("Initializing", 362218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, 363218799Snwhitehorn i*100/nitems, nitems, __DECONST(char **, items)); 364218799Snwhitehorn 365218799Snwhitehorn for (i = 1; i < nitems; i++) 366218799Snwhitehorn free(__DECONST(char *, items[i*2])); 367218799Snwhitehorn free(items); 368218799Snwhitehorn 369218799Snwhitehorn if (getenv("PATH_FSTAB") != NULL) 370218799Snwhitehorn fstab_path = getenv("PATH_FSTAB"); 371218799Snwhitehorn else 372218799Snwhitehorn fstab_path = "/etc/fstab"; 373218799Snwhitehorn fstab = fopen(fstab_path, "w+"); 374218799Snwhitehorn if (fstab == NULL) { 375218799Snwhitehorn sprintf(message, "Cannot open fstab file %s for writing (%s)\n", 376218799Snwhitehorn getenv("PATH_FSTAB"), strerror(errno)); 377218799Snwhitehorn dialog_msgbox("Error", message, 0, 0, TRUE); 378218799Snwhitehorn return (-1); 379218799Snwhitehorn } 380218799Snwhitehorn fprintf(fstab, "# Device\tMountpoint\tFStype\tOptions\tDump\tPass#\n"); 381218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 382218799Snwhitehorn if (md->fstab != NULL) 383223832Skevlo fprintf(fstab, "%s\t%s\t\t%s\t%s\t%d\t%d\n", 384218799Snwhitehorn md->fstab->fs_spec, md->fstab->fs_file, 385218799Snwhitehorn md->fstab->fs_vfstype, md->fstab->fs_mntops, 386218799Snwhitehorn md->fstab->fs_freq, md->fstab->fs_passno); 387218799Snwhitehorn } 388218799Snwhitehorn fclose(fstab); 389218799Snwhitehorn 390218799Snwhitehorn return (0); 391218799Snwhitehorn} 392218799Snwhitehorn 393218799Snwhitehornstatic struct partedit_item * 394225066Snwhitehornread_geom_mesh(struct gmesh *mesh, int *nitems) 395225066Snwhitehorn{ 396218799Snwhitehorn struct gclass *classp; 397218799Snwhitehorn struct ggeom *gp; 398218799Snwhitehorn struct partedit_item *items; 399218799Snwhitehorn 400218799Snwhitehorn *nitems = 0; 401218799Snwhitehorn items = NULL; 402218799Snwhitehorn 403218799Snwhitehorn /* 404218799Snwhitehorn * Build the device table. First add all disks (and CDs). 405218799Snwhitehorn */ 406218799Snwhitehorn 407218799Snwhitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) { 408218799Snwhitehorn if (strcmp(classp->lg_name, "DISK") != 0 && 409225066Snwhitehorn strcmp(classp->lg_name, "MD") != 0) 410218799Snwhitehorn continue; 411218799Snwhitehorn 412218799Snwhitehorn /* Now recurse into all children */ 413218799Snwhitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) 414218799Snwhitehorn add_geom_children(gp, 0, &items, nitems); 415218799Snwhitehorn } 416218799Snwhitehorn 417218799Snwhitehorn return (items); 418218799Snwhitehorn} 419218799Snwhitehorn 420218799Snwhitehornstatic void 421218799Snwhitehornadd_geom_children(struct ggeom *gp, int recurse, struct partedit_item **items, 422225066Snwhitehorn int *nitems) 423225066Snwhitehorn{ 424218799Snwhitehorn struct gconsumer *cp; 425218799Snwhitehorn struct gprovider *pp; 426218799Snwhitehorn struct gconfig *gc; 427218799Snwhitehorn 428218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "PART") == 0 && 429218799Snwhitehorn !LIST_EMPTY(&gp->lg_config)) { 430218799Snwhitehorn LIST_FOREACH(gc, &gp->lg_config, lg_config) { 431218799Snwhitehorn if (strcmp(gc->lg_name, "scheme") == 0) 432218799Snwhitehorn (*items)[*nitems-1].type = gc->lg_val; 433218799Snwhitehorn } 434218799Snwhitehorn } 435218799Snwhitehorn 436218799Snwhitehorn if (LIST_EMPTY(&gp->lg_provider)) 437218799Snwhitehorn return; 438218799Snwhitehorn 439218799Snwhitehorn LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 440218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "LABEL") == 0) 441218799Snwhitehorn continue; 442218799Snwhitehorn 443218799Snwhitehorn /* Skip WORM media */ 444218799Snwhitehorn if (strncmp(pp->lg_name, "cd", 2) == 0) 445218799Snwhitehorn continue; 446218799Snwhitehorn 447218799Snwhitehorn *items = realloc(*items, 448218799Snwhitehorn (*nitems+1)*sizeof(struct partedit_item)); 449218799Snwhitehorn (*items)[*nitems].indentation = recurse; 450218799Snwhitehorn (*items)[*nitems].name = pp->lg_name; 451218799Snwhitehorn (*items)[*nitems].size = pp->lg_mediasize; 452218799Snwhitehorn (*items)[*nitems].mountpoint = NULL; 453218799Snwhitehorn (*items)[*nitems].type = ""; 454218799Snwhitehorn (*items)[*nitems].cookie = pp; 455218799Snwhitehorn 456218799Snwhitehorn LIST_FOREACH(gc, &pp->lg_config, lg_config) { 457218799Snwhitehorn if (strcmp(gc->lg_name, "type") == 0) 458218799Snwhitehorn (*items)[*nitems].type = gc->lg_val; 459218799Snwhitehorn } 460218799Snwhitehorn 461218799Snwhitehorn /* Skip swap-backed MD devices */ 462218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "MD") == 0 && 463218799Snwhitehorn strcmp((*items)[*nitems].type, "swap") == 0) 464218799Snwhitehorn continue; 465218799Snwhitehorn 466218799Snwhitehorn (*nitems)++; 467218799Snwhitehorn 468218799Snwhitehorn LIST_FOREACH(cp, &pp->lg_consumers, lg_consumers) 469218799Snwhitehorn add_geom_children(cp->lg_geom, recurse+1, items, 470218799Snwhitehorn nitems); 471218799Snwhitehorn 472218799Snwhitehorn /* Only use first provider for acd */ 473218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "ACD") == 0) 474218799Snwhitehorn break; 475218799Snwhitehorn } 476218799Snwhitehorn} 477218799Snwhitehorn 478218799Snwhitehornstatic void 479218799Snwhitehorninit_fstab_metadata(void) 480218799Snwhitehorn{ 481218799Snwhitehorn struct fstab *fstab; 482218799Snwhitehorn struct partition_metadata *md; 483218799Snwhitehorn 484218799Snwhitehorn setfsent(); 485218799Snwhitehorn while ((fstab = getfsent()) != NULL) { 486218799Snwhitehorn md = calloc(1, sizeof(struct partition_metadata)); 487218799Snwhitehorn 488218799Snwhitehorn md->name = NULL; 489218799Snwhitehorn if (strncmp(fstab->fs_spec, "/dev/", 5) == 0) 490218799Snwhitehorn md->name = strdup(&fstab->fs_spec[5]); 491218799Snwhitehorn 492218799Snwhitehorn md->fstab = malloc(sizeof(struct fstab)); 493218799Snwhitehorn md->fstab->fs_spec = strdup(fstab->fs_spec); 494218799Snwhitehorn md->fstab->fs_file = strdup(fstab->fs_file); 495218799Snwhitehorn md->fstab->fs_vfstype = strdup(fstab->fs_vfstype); 496218799Snwhitehorn md->fstab->fs_mntops = strdup(fstab->fs_mntops); 497218799Snwhitehorn md->fstab->fs_type = strdup(fstab->fs_type); 498218799Snwhitehorn md->fstab->fs_freq = fstab->fs_freq; 499218799Snwhitehorn md->fstab->fs_passno = fstab->fs_passno; 500218799Snwhitehorn 501218799Snwhitehorn md->newfs = NULL; 502218799Snwhitehorn 503218799Snwhitehorn TAILQ_INSERT_TAIL(&part_metadata, md, metadata); 504218799Snwhitehorn } 505218799Snwhitehorn} 506218799Snwhitehorn 507218799Snwhitehornstatic void 508218799Snwhitehornget_mount_points(struct partedit_item *items, int nitems) 509218799Snwhitehorn{ 510218799Snwhitehorn struct partition_metadata *md; 511218799Snwhitehorn int i; 512218799Snwhitehorn 513218799Snwhitehorn for (i = 0; i < nitems; i++) { 514218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 515218799Snwhitehorn if (md->name != NULL && md->fstab != NULL && 516218799Snwhitehorn strcmp(md->name, items[i].name) == 0) { 517218799Snwhitehorn items[i].mountpoint = md->fstab->fs_file; 518218799Snwhitehorn break; 519218799Snwhitehorn } 520218799Snwhitehorn } 521218799Snwhitehorn } 522218799Snwhitehorn} 523