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$ 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."; 98218799Snwhitehorn part_wizard(); 99245700Snwhitehorn } else if (strcmp(basename(argv[0]), "scriptedpart") == 0) { 100245796Snwhitehorn error = scripted_editor(argc, argv); 101245700Snwhitehorn prompt = NULL; 102245796Snwhitehorn if (error != 0) { 103245796Snwhitehorn end_dialog(); 104245796Snwhitehorn return (error); 105245796Snwhitehorn } 106218799Snwhitehorn } else { 107218799Snwhitehorn prompt = "Create partitions for FreeBSD. No changes will be " 108225066Snwhitehorn "made until you select Finish."; 109218799Snwhitehorn } 110218799Snwhitehorn 111218799Snwhitehorn /* Show the part editor either immediately, or to confirm wizard */ 112245700Snwhitehorn while (prompt != NULL) { 113218799Snwhitehorn dlg_clear(); 114218799Snwhitehorn dlg_put_backtitle(); 115218799Snwhitehorn 116226739Snwhitehorn error = geom_gettree(&mesh); 117226739Snwhitehorn if (error == 0) 118226739Snwhitehorn items = read_geom_mesh(&mesh, &nitems); 119226739Snwhitehorn if (error || items == NULL) { 120226739Snwhitehorn dialog_msgbox("Error", "No disks found. If you need to " 121226739Snwhitehorn "install a kernel driver, choose Shell at the " 122226739Snwhitehorn "installation menu.", 0, 0, TRUE); 123226739Snwhitehorn break; 124226739Snwhitehorn } 125226739Snwhitehorn 126226739Snwhitehorn get_mount_points(items, nitems); 127226739Snwhitehorn 128218799Snwhitehorn if (i >= nitems) 129218799Snwhitehorn i = nitems - 1; 130218799Snwhitehorn op = diskeditor_show("Partition Editor", prompt, 131218799Snwhitehorn items, nitems, &i, &nscroll); 132218799Snwhitehorn 133218799Snwhitehorn switch (op) { 134218799Snwhitehorn case 0: /* Create */ 135218799Snwhitehorn gpart_create((struct gprovider *)(items[i].cookie), 136218799Snwhitehorn NULL, NULL, NULL, NULL, 1); 137218799Snwhitehorn break; 138218799Snwhitehorn case 1: /* Delete */ 139218799Snwhitehorn gpart_delete((struct gprovider *)(items[i].cookie)); 140218799Snwhitehorn break; 141218799Snwhitehorn case 2: /* Modify */ 142218799Snwhitehorn gpart_edit((struct gprovider *)(items[i].cookie)); 143218799Snwhitehorn break; 144218799Snwhitehorn case 3: /* Revert */ 145218799Snwhitehorn gpart_revert_all(&mesh); 146218799Snwhitehorn while ((md = TAILQ_FIRST(&part_metadata)) != NULL) { 147218799Snwhitehorn if (md->fstab != NULL) { 148218799Snwhitehorn free(md->fstab->fs_spec); 149218799Snwhitehorn free(md->fstab->fs_file); 150218799Snwhitehorn free(md->fstab->fs_vfstype); 151218799Snwhitehorn free(md->fstab->fs_mntops); 152218799Snwhitehorn free(md->fstab->fs_type); 153218799Snwhitehorn free(md->fstab); 154218799Snwhitehorn } 155218799Snwhitehorn if (md->newfs != NULL) 156218799Snwhitehorn free(md->newfs); 157218799Snwhitehorn free(md->name); 158218799Snwhitehorn 159218799Snwhitehorn TAILQ_REMOVE(&part_metadata, md, metadata); 160218799Snwhitehorn free(md); 161218799Snwhitehorn } 162218799Snwhitehorn init_fstab_metadata(); 163218799Snwhitehorn break; 164218799Snwhitehorn case 4: /* Auto */ 165218799Snwhitehorn part_wizard(); 166218799Snwhitehorn break; 167218799Snwhitehorn } 168218799Snwhitehorn 169218799Snwhitehorn error = 0; 170219391Snwhitehorn if (op == 5) { /* Finished */ 171225066Snwhitehorn dialog_vars.ok_label = __DECONST(char *, "Commit"); 172225066Snwhitehorn dialog_vars.extra_label = 173225066Snwhitehorn __DECONST(char *, "Revert & Exit"); 174218799Snwhitehorn dialog_vars.extra_button = TRUE; 175225066Snwhitehorn dialog_vars.cancel_label = __DECONST(char *, "Back"); 176218799Snwhitehorn op = dialog_yesno("Confirmation", "Your changes will " 177218799Snwhitehorn "now be written to disk. If you have chosen to " 178218799Snwhitehorn "overwrite existing data, it will be PERMANENTLY " 179225066Snwhitehorn "ERASED. Are you sure you want to commit your " 180225066Snwhitehorn "changes?", 0, 0); 181225066Snwhitehorn dialog_vars.ok_label = NULL; 182218799Snwhitehorn dialog_vars.extra_button = FALSE; 183225066Snwhitehorn dialog_vars.cancel_label = NULL; 184218799Snwhitehorn 185219391Snwhitehorn if (op == 0 && validate_setup()) { /* Save */ 186218799Snwhitehorn error = apply_changes(&mesh); 187218799Snwhitehorn break; 188225066Snwhitehorn } else if (op == 3) { /* Quit */ 189218799Snwhitehorn gpart_revert_all(&mesh); 190218799Snwhitehorn error = -1; 191218799Snwhitehorn break; 192218799Snwhitehorn } 193218799Snwhitehorn } 194218799Snwhitehorn 195218799Snwhitehorn geom_deletetree(&mesh); 196218799Snwhitehorn free(items); 197218799Snwhitehorn } 198218799Snwhitehorn 199245700Snwhitehorn if (prompt == NULL) { 200245700Snwhitehorn error = geom_gettree(&mesh); 201245700Snwhitehorn if (validate_setup()) { 202245700Snwhitehorn error = apply_changes(&mesh); 203245700Snwhitehorn } else { 204245700Snwhitehorn gpart_revert_all(&mesh); 205245700Snwhitehorn error = -1; 206245700Snwhitehorn } 207245700Snwhitehorn } 208218799Snwhitehorn 209218799Snwhitehorn geom_deletetree(&mesh); 210218799Snwhitehorn free(items); 211218799Snwhitehorn end_dialog(); 212218799Snwhitehorn 213218799Snwhitehorn return (error); 214218799Snwhitehorn} 215218799Snwhitehorn 216218799Snwhitehornstruct partition_metadata * 217218799Snwhitehornget_part_metadata(const char *name, int create) 218218799Snwhitehorn{ 219218799Snwhitehorn struct partition_metadata *md; 220218799Snwhitehorn 221218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) 222218799Snwhitehorn if (md->name != NULL && strcmp(md->name, name) == 0) 223218799Snwhitehorn break; 224218799Snwhitehorn 225218799Snwhitehorn if (md == NULL && create) { 226218799Snwhitehorn md = calloc(1, sizeof(*md)); 227218799Snwhitehorn md->name = strdup(name); 228218799Snwhitehorn TAILQ_INSERT_TAIL(&part_metadata, md, metadata); 229218799Snwhitehorn } 230218799Snwhitehorn 231218799Snwhitehorn return (md); 232218799Snwhitehorn} 233218799Snwhitehorn 234218799Snwhitehornvoid 235225066Snwhitehorndelete_part_metadata(const char *name) 236225066Snwhitehorn{ 237218799Snwhitehorn struct partition_metadata *md; 238218799Snwhitehorn 239218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 240218799Snwhitehorn if (md->name != NULL && strcmp(md->name, name) == 0) { 241218799Snwhitehorn if (md->fstab != NULL) { 242218799Snwhitehorn free(md->fstab->fs_spec); 243218799Snwhitehorn free(md->fstab->fs_file); 244218799Snwhitehorn free(md->fstab->fs_vfstype); 245218799Snwhitehorn free(md->fstab->fs_mntops); 246218799Snwhitehorn free(md->fstab->fs_type); 247218799Snwhitehorn free(md->fstab); 248218799Snwhitehorn } 249218799Snwhitehorn if (md->newfs != NULL) 250218799Snwhitehorn free(md->newfs); 251218799Snwhitehorn free(md->name); 252218799Snwhitehorn 253218799Snwhitehorn TAILQ_REMOVE(&part_metadata, md, metadata); 254218799Snwhitehorn free(md); 255218799Snwhitehorn break; 256218799Snwhitehorn } 257218799Snwhitehorn } 258218799Snwhitehorn} 259218799Snwhitehorn 260218799Snwhitehornstatic int 261218799Snwhitehornvalidate_setup(void) 262218799Snwhitehorn{ 263230309Snwhitehorn struct partition_metadata *md, *root = NULL; 264230309Snwhitehorn int cancel; 265218799Snwhitehorn 266218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 267218799Snwhitehorn if (md->fstab != NULL && strcmp(md->fstab->fs_file, "/") == 0) 268230309Snwhitehorn root = md; 269218799Snwhitehorn 270218799Snwhitehorn /* XXX: Check for duplicate mountpoints */ 271218799Snwhitehorn } 272218799Snwhitehorn 273230309Snwhitehorn if (root == NULL) { 274218799Snwhitehorn dialog_msgbox("Error", "No root partition was found. " 275218799Snwhitehorn "The root FreeBSD partition must have a mountpoint of '/'.", 276218799Snwhitehorn 0, 0, TRUE); 277218799Snwhitehorn return (FALSE); 278218799Snwhitehorn } 279218799Snwhitehorn 280230309Snwhitehorn /* 281230309Snwhitehorn * Check for root partitions that we aren't formatting, which is 282230309Snwhitehorn * usually a mistake 283230309Snwhitehorn */ 284244858Snwhitehorn if (root->newfs == NULL && !sade_mode) { 285230309Snwhitehorn dialog_vars.defaultno = TRUE; 286230309Snwhitehorn cancel = dialog_yesno("Warning", "The chosen root partition " 287230309Snwhitehorn "has a preexisting filesystem. If it contains an existing " 288230309Snwhitehorn "FreeBSD system, please update it with freebsd-update " 289230309Snwhitehorn "instead of installing a new system on it. The partition " 290230309Snwhitehorn "can also be erased by pressing \"No\" and then deleting " 291230309Snwhitehorn "and recreating it. Are you sure you want to proceed?", 292230309Snwhitehorn 0, 0); 293230309Snwhitehorn dialog_vars.defaultno = FALSE; 294230309Snwhitehorn if (cancel) 295230309Snwhitehorn return (FALSE); 296230309Snwhitehorn } 297230309Snwhitehorn 298218799Snwhitehorn return (TRUE); 299218799Snwhitehorn} 300218799Snwhitehorn 301218799Snwhitehornstatic int 302218799Snwhitehornapply_changes(struct gmesh *mesh) 303218799Snwhitehorn{ 304218799Snwhitehorn struct partition_metadata *md; 305218799Snwhitehorn char message[512]; 306218799Snwhitehorn int i, nitems, error; 307218799Snwhitehorn const char **items; 308218799Snwhitehorn const char *fstab_path; 309218799Snwhitehorn FILE *fstab; 310218799Snwhitehorn 311218799Snwhitehorn nitems = 1; /* Partition table changes */ 312218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 313218799Snwhitehorn if (md->newfs != NULL) 314218799Snwhitehorn nitems++; 315218799Snwhitehorn } 316218799Snwhitehorn items = calloc(nitems * 2, sizeof(const char *)); 317218799Snwhitehorn items[0] = "Writing partition tables"; 318218799Snwhitehorn items[1] = "7"; /* In progress */ 319218799Snwhitehorn i = 1; 320218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 321218799Snwhitehorn if (md->newfs != NULL) { 322218799Snwhitehorn char *item; 323218799Snwhitehorn item = malloc(255); 324218799Snwhitehorn sprintf(item, "Initializing %s", md->name); 325218799Snwhitehorn items[i*2] = item; 326218799Snwhitehorn items[i*2 + 1] = "Pending"; 327218799Snwhitehorn i++; 328218799Snwhitehorn } 329218799Snwhitehorn } 330218799Snwhitehorn 331218799Snwhitehorn i = 0; 332218799Snwhitehorn dialog_mixedgauge("Initializing", 333218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, i*100/nitems, 334218799Snwhitehorn nitems, __DECONST(char **, items)); 335218799Snwhitehorn gpart_commit(mesh); 336218799Snwhitehorn items[i*2 + 1] = "3"; 337218799Snwhitehorn i++; 338218799Snwhitehorn 339218799Snwhitehorn if (getenv("BSDINSTALL_LOG") == NULL) 340218799Snwhitehorn setenv("BSDINSTALL_LOG", "/dev/null", 1); 341218799Snwhitehorn 342218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 343218799Snwhitehorn if (md->newfs != NULL) { 344218799Snwhitehorn items[i*2 + 1] = "7"; /* In progress */ 345218799Snwhitehorn dialog_mixedgauge("Initializing", 346218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, 347218799Snwhitehorn i*100/nitems, nitems, __DECONST(char **, items)); 348218799Snwhitehorn sprintf(message, "(echo %s; %s) >>%s 2>>%s", 349218799Snwhitehorn md->newfs, md->newfs, getenv("BSDINSTALL_LOG"), 350218799Snwhitehorn getenv("BSDINSTALL_LOG")); 351218799Snwhitehorn error = system(message); 352218799Snwhitehorn items[i*2 + 1] = (error == 0) ? "3" : "1"; 353218799Snwhitehorn i++; 354218799Snwhitehorn } 355218799Snwhitehorn } 356218799Snwhitehorn dialog_mixedgauge("Initializing", 357218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, 358218799Snwhitehorn i*100/nitems, nitems, __DECONST(char **, items)); 359218799Snwhitehorn 360218799Snwhitehorn for (i = 1; i < nitems; i++) 361218799Snwhitehorn free(__DECONST(char *, items[i*2])); 362218799Snwhitehorn free(items); 363218799Snwhitehorn 364218799Snwhitehorn if (getenv("PATH_FSTAB") != NULL) 365218799Snwhitehorn fstab_path = getenv("PATH_FSTAB"); 366218799Snwhitehorn else 367218799Snwhitehorn fstab_path = "/etc/fstab"; 368218799Snwhitehorn fstab = fopen(fstab_path, "w+"); 369218799Snwhitehorn if (fstab == NULL) { 370218799Snwhitehorn sprintf(message, "Cannot open fstab file %s for writing (%s)\n", 371218799Snwhitehorn getenv("PATH_FSTAB"), strerror(errno)); 372218799Snwhitehorn dialog_msgbox("Error", message, 0, 0, TRUE); 373218799Snwhitehorn return (-1); 374218799Snwhitehorn } 375218799Snwhitehorn fprintf(fstab, "# Device\tMountpoint\tFStype\tOptions\tDump\tPass#\n"); 376218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 377218799Snwhitehorn if (md->fstab != NULL) 378223832Skevlo fprintf(fstab, "%s\t%s\t\t%s\t%s\t%d\t%d\n", 379218799Snwhitehorn md->fstab->fs_spec, md->fstab->fs_file, 380218799Snwhitehorn md->fstab->fs_vfstype, md->fstab->fs_mntops, 381218799Snwhitehorn md->fstab->fs_freq, md->fstab->fs_passno); 382218799Snwhitehorn } 383218799Snwhitehorn fclose(fstab); 384218799Snwhitehorn 385218799Snwhitehorn return (0); 386218799Snwhitehorn} 387218799Snwhitehorn 388218799Snwhitehornstatic struct partedit_item * 389225066Snwhitehornread_geom_mesh(struct gmesh *mesh, int *nitems) 390225066Snwhitehorn{ 391218799Snwhitehorn struct gclass *classp; 392218799Snwhitehorn struct ggeom *gp; 393218799Snwhitehorn struct partedit_item *items; 394218799Snwhitehorn 395218799Snwhitehorn *nitems = 0; 396218799Snwhitehorn items = NULL; 397218799Snwhitehorn 398218799Snwhitehorn /* 399218799Snwhitehorn * Build the device table. First add all disks (and CDs). 400218799Snwhitehorn */ 401218799Snwhitehorn 402218799Snwhitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) { 403218799Snwhitehorn if (strcmp(classp->lg_name, "DISK") != 0 && 404225066Snwhitehorn strcmp(classp->lg_name, "MD") != 0) 405218799Snwhitehorn continue; 406218799Snwhitehorn 407218799Snwhitehorn /* Now recurse into all children */ 408218799Snwhitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) 409218799Snwhitehorn add_geom_children(gp, 0, &items, nitems); 410218799Snwhitehorn } 411218799Snwhitehorn 412218799Snwhitehorn return (items); 413218799Snwhitehorn} 414218799Snwhitehorn 415218799Snwhitehornstatic void 416218799Snwhitehornadd_geom_children(struct ggeom *gp, int recurse, struct partedit_item **items, 417225066Snwhitehorn int *nitems) 418225066Snwhitehorn{ 419218799Snwhitehorn struct gconsumer *cp; 420218799Snwhitehorn struct gprovider *pp; 421218799Snwhitehorn struct gconfig *gc; 422218799Snwhitehorn 423218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "PART") == 0 && 424218799Snwhitehorn !LIST_EMPTY(&gp->lg_config)) { 425218799Snwhitehorn LIST_FOREACH(gc, &gp->lg_config, lg_config) { 426218799Snwhitehorn if (strcmp(gc->lg_name, "scheme") == 0) 427218799Snwhitehorn (*items)[*nitems-1].type = gc->lg_val; 428218799Snwhitehorn } 429218799Snwhitehorn } 430218799Snwhitehorn 431218799Snwhitehorn if (LIST_EMPTY(&gp->lg_provider)) 432218799Snwhitehorn return; 433218799Snwhitehorn 434218799Snwhitehorn LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 435218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "LABEL") == 0) 436218799Snwhitehorn continue; 437218799Snwhitehorn 438218799Snwhitehorn /* Skip WORM media */ 439218799Snwhitehorn if (strncmp(pp->lg_name, "cd", 2) == 0) 440218799Snwhitehorn continue; 441218799Snwhitehorn 442218799Snwhitehorn *items = realloc(*items, 443218799Snwhitehorn (*nitems+1)*sizeof(struct partedit_item)); 444218799Snwhitehorn (*items)[*nitems].indentation = recurse; 445218799Snwhitehorn (*items)[*nitems].name = pp->lg_name; 446218799Snwhitehorn (*items)[*nitems].size = pp->lg_mediasize; 447218799Snwhitehorn (*items)[*nitems].mountpoint = NULL; 448218799Snwhitehorn (*items)[*nitems].type = ""; 449218799Snwhitehorn (*items)[*nitems].cookie = pp; 450218799Snwhitehorn 451218799Snwhitehorn LIST_FOREACH(gc, &pp->lg_config, lg_config) { 452218799Snwhitehorn if (strcmp(gc->lg_name, "type") == 0) 453218799Snwhitehorn (*items)[*nitems].type = gc->lg_val; 454218799Snwhitehorn } 455218799Snwhitehorn 456218799Snwhitehorn /* Skip swap-backed MD devices */ 457218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "MD") == 0 && 458218799Snwhitehorn strcmp((*items)[*nitems].type, "swap") == 0) 459218799Snwhitehorn continue; 460218799Snwhitehorn 461218799Snwhitehorn (*nitems)++; 462218799Snwhitehorn 463218799Snwhitehorn LIST_FOREACH(cp, &pp->lg_consumers, lg_consumers) 464218799Snwhitehorn add_geom_children(cp->lg_geom, recurse+1, items, 465218799Snwhitehorn nitems); 466218799Snwhitehorn 467218799Snwhitehorn /* Only use first provider for acd */ 468218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "ACD") == 0) 469218799Snwhitehorn break; 470218799Snwhitehorn } 471218799Snwhitehorn} 472218799Snwhitehorn 473218799Snwhitehornstatic void 474218799Snwhitehorninit_fstab_metadata(void) 475218799Snwhitehorn{ 476218799Snwhitehorn struct fstab *fstab; 477218799Snwhitehorn struct partition_metadata *md; 478218799Snwhitehorn 479218799Snwhitehorn setfsent(); 480218799Snwhitehorn while ((fstab = getfsent()) != NULL) { 481218799Snwhitehorn md = calloc(1, sizeof(struct partition_metadata)); 482218799Snwhitehorn 483218799Snwhitehorn md->name = NULL; 484218799Snwhitehorn if (strncmp(fstab->fs_spec, "/dev/", 5) == 0) 485218799Snwhitehorn md->name = strdup(&fstab->fs_spec[5]); 486218799Snwhitehorn 487218799Snwhitehorn md->fstab = malloc(sizeof(struct fstab)); 488218799Snwhitehorn md->fstab->fs_spec = strdup(fstab->fs_spec); 489218799Snwhitehorn md->fstab->fs_file = strdup(fstab->fs_file); 490218799Snwhitehorn md->fstab->fs_vfstype = strdup(fstab->fs_vfstype); 491218799Snwhitehorn md->fstab->fs_mntops = strdup(fstab->fs_mntops); 492218799Snwhitehorn md->fstab->fs_type = strdup(fstab->fs_type); 493218799Snwhitehorn md->fstab->fs_freq = fstab->fs_freq; 494218799Snwhitehorn md->fstab->fs_passno = fstab->fs_passno; 495218799Snwhitehorn 496218799Snwhitehorn md->newfs = NULL; 497218799Snwhitehorn 498218799Snwhitehorn TAILQ_INSERT_TAIL(&part_metadata, md, metadata); 499218799Snwhitehorn } 500218799Snwhitehorn} 501218799Snwhitehorn 502218799Snwhitehornstatic void 503218799Snwhitehornget_mount_points(struct partedit_item *items, int nitems) 504218799Snwhitehorn{ 505218799Snwhitehorn struct partition_metadata *md; 506218799Snwhitehorn int i; 507218799Snwhitehorn 508218799Snwhitehorn for (i = 0; i < nitems; i++) { 509218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 510218799Snwhitehorn if (md->name != NULL && md->fstab != NULL && 511218799Snwhitehorn strcmp(md->name, items[i].name) == 0) { 512218799Snwhitehorn items[i].mountpoint = md->fstab->fs_file; 513218799Snwhitehorn break; 514218799Snwhitehorn } 515218799Snwhitehorn } 516218799Snwhitehorn } 517218799Snwhitehorn} 518