diff --git a/distrib/utils/sysinst/Makefile.inc b/distrib/utils/sysinst/Makefile.inc
index 434d924..ff14908 100644
--- a/distrib/utils/sysinst/Makefile.inc
+++ b/distrib/utils/sysinst/Makefile.inc
@@ -13,7 +13,7 @@ WARNS=		4
 
 SRCS+=	menu_defs.c msg_defs.c main.c install.c upgrade.c \
 	txtwalk.c run.c factor.c net.c disks.c disks_lfs.c util.c geom.c \
-	label.c target.c md.c sizemultname.c configmenu.c checkrc.c
+	label.c target.c md.c sizemultname.c configmenu.c checkrc.c partman.c
 
 SRCS+=	${MD_OPTIONS:MAOUT2ELF:S/AOUT2ELF/aout2elf.c/}
 SRCS+=	${MENUS_MD:Mmenus.mbr:S/menus.mbr/mbr.c/}
@@ -44,6 +44,10 @@ CPPFLAGS+=	-I. -I${.CURDIR}/../.. -I${.CURDIR} \
 		-DREL=\"${DISTRIBVER}\" -DMACH=\"${MACHINE}\" \
 		-DMACH_${MACHINE} -DARCH_${MACHINE_ARCH}
 
+.if (defined(DEBUG))
+CPPFLAGS+=-DDEBUG -g -O0
+.endif
+
 .if (!defined(SMALLPROG) || defined(SMALLPROG_INET6)) && (${USE_INET6} != "no")
 CPPFLAGS+=-DINET6
 .endif
@@ -60,6 +64,7 @@ COPTS.mbr.c += -Wno-format-nonliteral
 COPTS.msg_defs.c += -Wno-format-nonliteral
 COPTS.bsddisklabel.c += -Wno-format-nonliteral
 COPTS.md.c += -Wno-format-nonliteral
+COPTS.partman.c += -Wno-format-nonliteral
 
 # Host to ftp from.  Default:
 #	"ftp.NetBSD.org"
diff --git a/distrib/utils/sysinst/arch/acorn32/md.c b/distrib/utils/sysinst/arch/acorn32/md.c
index 2e51b1c..96708ff 100644
--- a/distrib/utils/sysinst/arch/acorn32/md.c
+++ b/distrib/utils/sysinst/arch/acorn32/md.c
@@ -73,12 +73,12 @@ md_get_info(void)
 	struct filecore_bootblock *fcbb = (struct filecore_bootblock *)bb;
 	int offset = 0;
 
-	if (strncmp(diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+	if (strncmp(pm->diskdev, "wd", 2) == 0)
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
-	snprintf(dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
+	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -173,31 +173,31 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
-	ptstart = offset;
+	pm->ptstart = offset;
 /*	endwin();
-	printf("dlcyl=%d\n", dlcyl);
-	printf("dlhead=%d\n", dlhead);
-	printf("dlsec=%d\n", dlsec);
-	printf("secsz=%d\n", sectorsize);
-	printf("cylsz=%d\n", dlcylsize);
-	printf("dlsz=%d\n", dlsize);
-	printf("pstart=%d\n", ptstart);
+	printf("pm->dlcyl=%d\n", pm->dlcyl);
+	printf("pm->dlhead=%d\n", pm->dlhead);
+	printf("pm->dlsec=%d\n", pm->dlsec);
+	printf("secsz=%d\n", pm->sectorsize);
+	printf("cylsz=%d\n", pm->dlcylsize);
+	printf("dlsz=%d\n", pm->dlsize);
+	printf("pstart=%d\n", pm->ptstart);
 	printf("pstart=%d\n", partsize);
 	printf("secpun=%d\n", disklabel.d_secperunit);
 	backtowin();*/
diff --git a/distrib/utils/sysinst/arch/alpha/md.c b/distrib/utils/sysinst/arch/alpha/md.c
index 1114462..cd8fb82 100644
--- a/distrib/utils/sysinst/arch/alpha/md.c
+++ b/distrib/utils/sysinst/arch/alpha/md.c
@@ -67,7 +67,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf (dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
+	snprintf (dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
 	fd = open (dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -83,21 +83,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -151,12 +151,12 @@ md_post_newfs(void)
 	char *bootxx;
 	int error;
 
-	printf(msg_string(MSG_dobootblks), diskdev);
+	printf(msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot", "/boot");
 	bootxx = bootxx_name();
 	if (bootxx != NULL) {
 		error = run_program(RUN_DISPLAY | RUN_NO_CLEAR,
-		    "/usr/sbin/installboot /dev/r%sc %s", diskdev, bootxx);
+		    "/usr/sbin/installboot /dev/r%sc %s", pm->diskdev, bootxx);
 		free(bootxx);
 	} else
 		error = -1;
diff --git a/distrib/utils/sysinst/arch/amiga/md.c b/distrib/utils/sysinst/arch/amiga/md.c
index c74334a..1b6a976 100644
--- a/distrib/utils/sysinst/arch/amiga/md.c
+++ b/distrib/utils/sysinst/arch/amiga/md.c
@@ -107,9 +107,9 @@ int
 md_post_newfs(void)
 {
 	/* boot blocks ... */
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	return run_program(RUN_DISPLAY,
-	    "/usr/mdec/installboot -v /usr/mdec/xxboot /dev/r%sa", diskdev);
+	    "/usr/mdec/installboot -v /usr/mdec/xxboot /dev/r%sa", pm->diskdev);
 }
 
 int
diff --git a/distrib/utils/sysinst/arch/arc/md.c b/distrib/utils/sysinst/arch/arc/md.c
index 5e4ccf9..0363ef9 100644
--- a/distrib/utils/sysinst/arch/arc/md.c
+++ b/distrib/utils/sysinst/arch/arc/md.c
@@ -88,62 +88,62 @@ md_make_bsd_partitions(void)
 	 * Initialize global variables that track space used on this disk.
 	 * Standard 4.4BSD 8-partition labels always cover whole disk.
 	 */
-	if (ptsize == 0)
-		ptsize = dlsize - ptstart;
-	if (dlsize == 0)
-		dlsize = ptstart + ptsize;
+	if (pm->ptsize == 0)
+		pm->ptsize = pm->dlsize - pm->ptstart;
+	if (pm->dlsize == 0)
+		pm->dlsize = pm->ptstart + pm->ptsize;
 
-	partstart = ptstart;
-	ptend = ptstart + ptsize;
+	partstart = pm->ptstart;
+	ptend = pm->ptstart + pm->ptsize;
 
 	/* Ask for layout type -- standard or special */
 	msg_display(MSG_layout,
-		    ptsize / (MEG / sectorsize),
+		    pm->ptsize / (MEG / pm->sectorsize),
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);
 
 	process_menu(MENU_layout, NULL);
 
 	/* Set so we use the 'real' geometry for rounding, input in MB */
-	current_cylsize = dlcylsize;
+	pm->current_cylsize = pm->dlcylsize;
 	set_sizemultname_meg();
 
 	/* Build standard partitions */
-	memset(&bsdlabel, 0, sizeof bsdlabel);
+	memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
 
 	/* Set initial partition types to unused */
 	for (part = 0 ; part < maxpart ; ++part)
-		bsdlabel[part].pi_fstype = FS_UNUSED;
+		pm->bsdlabel[part].pi_fstype = FS_UNUSED;
 
 	/* Whole disk partition */
 	part_raw = getrawpartition();
 	if (part_raw == -1)
 		part_raw = PART_C;	/* for sanity... */
-	bsdlabel[part_raw].pi_offset = 0;
-	bsdlabel[part_raw].pi_size = dlsize;
+	pm->bsdlabel[part_raw].pi_offset = 0;
+	pm->bsdlabel[part_raw].pi_size = pm->dlsize;
 
 	if (part_raw == PART_D) {
 		/* Probably a system that expects an i386 style mbr */
 		part_bsd = PART_C;
-		bsdlabel[PART_C].pi_offset = ptstart;
-		bsdlabel[PART_C].pi_size = ptsize;
+		pm->bsdlabel[PART_C].pi_offset = pm->ptstart;
+		pm->bsdlabel[PART_C].pi_size = pm->ptsize;
 	} else {
 		part_bsd = part_raw;
 	}
 
-	if (bootsize != 0) {
-		bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
-		bsdlabel[PART_BOOT_FAT12].pi_size = bootsize;
-		bsdlabel[PART_BOOT_FAT12].pi_offset = bootstart;
-		bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
-		strlcpy(bsdlabel[PART_BOOT_FAT12].pi_mount,
+	if (pm->bootsize != 0) {
+		pm->bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
+		pm->bsdlabel[PART_BOOT_FAT12].pi_size = pm->bootsize;
+		pm->bsdlabel[PART_BOOT_FAT12].pi_offset = pm->bootstart;
+		pm->bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
+		strlcpy(pm->bsdlabel[PART_BOOT_FAT12].pi_mount,
 		    PART_BOOT_FAT12_PI_MOUNT,
-		    sizeof bsdlabel[PART_BOOT_FAT12].pi_mount);
+		    sizeof pm->bsdlabel[PART_BOOT_FAT12].pi_mount);
 	}
 
 #ifdef PART_REST
-	bsdlabel[PART_REST].pi_offset = 0;
-	bsdlabel[PART_REST].pi_size = ptstart;
+	pm->bsdlabel[PART_REST].pi_offset = 0;
+	pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
 #endif
 
 	/*
@@ -153,27 +153,27 @@ md_make_bsd_partitions(void)
 	 * partitions on a multiboot i386 system.
 	 */
 	 for (i = maxpart; i--;) {
-		if (bsdlabel[i].pi_size != 0)
+		if (pm->bsdlabel[i].pi_size != 0)
 			/* Don't overwrite special partitions */
 			continue;
-		p = &oldlabel[i];
+		p = &pm->oldlabel[i];
 		if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
 			continue;
-		if (layoutkind == 4) {
+		if (layoutkind == LY_USEEXIST) {
 			if (PI_ISBSDFS(p))
 				p->pi_flags |= PIF_MOUNT;
 		} else {
-			if (p->pi_offset < ptstart + ptsize &&
-			    p->pi_offset + p->pi_size > ptstart)
+			if (p->pi_offset < pm->ptstart + pm->ptsize &&
+			    p->pi_offset + p->pi_size > pm->ptstart)
 				/* Not outside area we are allocating */
 				continue;
 			if (p->pi_fstype == FS_SWAP)
 				no_swap = 1;
 		}
-		bsdlabel[i] = oldlabel[i];
+		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/* XXX Check we have a sensible layout */
 		;
 	} else
@@ -184,7 +184,7 @@ md_make_bsd_partitions(void)
 	 * edit it and verify it's OK, or abort altogether.
 	 */
  edit_check:
-	if (edit_and_check_label(bsdlabel, maxpart, part_raw, part_bsd) == 0) {
+	if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
 		msg_display(MSG_abort);
 		return 0;
 	}
@@ -192,10 +192,10 @@ md_make_bsd_partitions(void)
 		goto edit_check;
 
 	/* Disk name */
-	msg_prompt(MSG_packname, bsddiskname, bsddiskname, sizeof bsddiskname);
+	msg_prompt(MSG_packname, pm->bsddiskname, pm->bsddiskname, sizeof pm->bsddiskname);
 
 	/* save label to disk for MI code to update. */
-	(void)savenewlabel(bsdlabel, maxpart);
+	(void)savenewlabel(pm->bsdlabel, maxpart);
 
 	/* Everything looks OK. */
 	return 1;
@@ -214,7 +214,7 @@ md_check_partitions(void)
 	 * something stupid, like move it away from the MBR partition.
 	 */
 	for (part = PART_A; part < MAXPARTITIONS; part++)
-		if (bsdlabel[part].pi_fstype == FS_MSDOS) {
+		if (pm->bsdlabel[part].pi_fstype == FS_MSDOS) {
 			bootpart_fat12 = part;
 			return 1;
 		}
@@ -233,7 +233,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -248,7 +248,7 @@ int
 md_post_disklabel(void)
 {
 	if (get_ramsize() <= 32)
-		set_swap(diskdev, bsdlabel);
+		set_swap(pm->diskdev, pm->bsdlabel);
 	return 0;
 }
 
@@ -261,7 +261,7 @@ int
 md_post_newfs(void)
 {
 	if (!nobootfs) {
-		msg_display(msg_string(MSG_copybootloader), diskdev);
+		msg_display(msg_string(MSG_copybootloader), pm->diskdev);
 		cp_to_target("/usr/mdec/boot", PART_BOOT_FAT12_PI_MOUNT);
 	}
 
@@ -292,9 +292,9 @@ md_pre_update(void)
 	int i;
 
 	if (get_ramsize() <= 32)
-		set_swap(diskdev, NULL);
+		set_swap(pm->diskdev, NULL);
 
-	read_mbr(diskdev, &mbr);
+	read_mbr(pm->diskdev, &mbr);
 	/* do a sanity check of the partition table */
 	for (ext = &mbr; ext; ext = ext->extended) {
 		part = ext->mbr.mbr_parts;
@@ -335,13 +335,13 @@ md_check_mbr(mbr_info_t *mbri)
 		part = ext->mbr.mbr_parts;
 		for (i = 0; i < MBR_PART_COUNT; part++, i++) {
 			if (part->mbrp_type == MBR_PTYPE_FAT12) {
-				bootstart = part->mbrp_start;
-				bootsize = part->mbrp_size;
+				pm->bootstart = part->mbrp_start;
+				pm->bootsize = part->mbrp_size;
 				break;
 			}
 		}
 	}
-	if (bootsize < (MIN_FAT12_BOOT / 512)) {
+	if (pm->bootsize < (MIN_FAT12_BOOT / 512)) {
 		msg_display(MSG_boottoosmall);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -349,7 +349,7 @@ md_check_mbr(mbr_info_t *mbri)
 			return 0;
 		return 1;
 	}
-	if (bootstart == 0 || bootsize == 0) {
+	if (pm->bootstart == 0 || pm->bootsize == 0) {
 		msg_display(MSG_nobootpart);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -383,14 +383,14 @@ md_mbr_use_wholedisk(mbr_info_t *mbri)
 	part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
 
 	part[1].mbrp_type = MBR_PTYPE_NETBSD;
-	part[1].mbrp_size = dlsize - (bsec + FAT12_BOOT_SIZE / 512);
+	part[1].mbrp_size = pm->dlsize - (bsec + FAT12_BOOT_SIZE / 512);
 	part[1].mbrp_start = bsec + FAT12_BOOT_SIZE / 512;
 	part[1].mbrp_flag = 0;
 
-	ptstart = part[1].mbrp_start;
-	ptsize = part[1].mbrp_size;
-	bootstart = part[0].mbrp_start;
-	bootsize = part[0].mbrp_size;
+	pm->ptstart = part[1].mbrp_start;
+	pm->ptsize = part[1].mbrp_size;
+	pm->bootstart = part[0].mbrp_start;
+	pm->bootsize = part[0].mbrp_size;
 	return 1;
 }
 
diff --git a/distrib/utils/sysinst/arch/atari/md.c b/distrib/utils/sysinst/arch/atari/md.c
index 8faa9bf..4c2ab3d 100644
--- a/distrib/utils/sysinst/arch/atari/md.c
+++ b/distrib/utils/sysinst/arch/atari/md.c
@@ -68,10 +68,10 @@ md_get_info(void)
 int
 md_make_bsd_partitions(void)
 {
-	msg_display(MSG_infoahdilabel, diskdev);
+	msg_display(MSG_infoahdilabel, pm->diskdev);
 	process_menu(MENU_noyes, NULL);
 	if (yesno) {
-		run_program(RUN_DISPLAY, "ahdilabel /dev/r%sc", diskdev);
+		run_program(RUN_DISPLAY, "ahdilabel /dev/r%sc", pm->diskdev);
 	}
 	if (!make_bsd_partitions())
 		return 0;
@@ -79,10 +79,10 @@ md_make_bsd_partitions(void)
 	/*
 	 * Setup the disktype so /etc/disktab gets proper info
 	 */
-	if (strncmp (diskdev, "sd", 2) == 0)
-		disktype = "SCSI";
+	if (strncmp (pm->diskdev, "sd", 2) == 0)
+		pm->disktype = "SCSI";
 	else
-		disktype = "ST506";
+		pm->disktype = "ST506";
 
 	return 1;
 }
@@ -140,7 +140,7 @@ md_post_newfs(void)
 	free(cpu_model);
 
 	/* copy tertiary boot and install boot blocks */
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	snprintf(bootpath, sizeof(bootpath), "/usr/mdec/%s/boot.atari",
 	    milan ? "milan" : "std");
 	rv = cp_to_target(bootpath, "/");
@@ -148,7 +148,7 @@ md_post_newfs(void)
 		return rv;
 
 	rv = run_program(RUN_DISPLAY, "/usr/mdec/installboot -v%s /dev/r%sc",
-	    milan ? "m" : "", diskdev);
+	    milan ? "m" : "", pm->diskdev);
 
 	return rv;
 }
diff --git a/distrib/utils/sysinst/arch/bebox/md.c b/distrib/utils/sysinst/arch/bebox/md.c
index f939303..3481d78 100644
--- a/distrib/utils/sysinst/arch/bebox/md.c
+++ b/distrib/utils/sysinst/arch/bebox/md.c
@@ -88,7 +88,7 @@ md_pre_disklabel(void)
 	printf ("%s", msg_string (MSG_dofdisk));
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
diff --git a/distrib/utils/sysinst/arch/cats/md.c b/distrib/utils/sysinst/arch/cats/md.c
index 8c0f493..6ac23d6 100644
--- a/distrib/utils/sysinst/arch/cats/md.c
+++ b/distrib/utils/sysinst/arch/cats/md.c
@@ -72,12 +72,12 @@ md_get_info(void)
 #endif
 	int offset = 0;
 
-	if (strncmp(diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+	if (strncmp(pm->diskdev, "wd", 2) == 0)
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -94,31 +94,31 @@ md_get_info(void)
 
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
-	ptstart = offset;
+	pm->ptstart = offset;
 /*	endwin();
-	printf("dlcyl=%d\n", dlcyl);
-	printf("dlhead=%d\n", dlhead);
-	printf("dlsec=%d\n", dlsec);
-	printf("secsz=%d\n", sectorsize);
-	printf("cylsz=%d\n", dlcylsize);
-	printf("dlsz=%d\n", dlsize);
-	printf("pstart=%d\n", ptstart);
+	printf("pm->dlcyl=%d\n", pm->dlcyl);
+	printf("pm->dlhead=%d\n", pm->dlhead);
+	printf("pm->dlsec=%d\n", pm->dlsec);
+	printf("secsz=%d\n", pm->sectorsize);
+	printf("cylsz=%d\n", pm->dlcylsize);
+	printf("dlsz=%d\n", pm->dlsize);
+	printf("pstart=%d\n", pm->ptstart);
 	printf("pstart=%d\n", partsize);
 	printf("secpun=%d\n", disklabel.d_secperunit);
 	backtowin();*/
diff --git a/distrib/utils/sysinst/arch/cobalt/md.c b/distrib/utils/sysinst/arch/cobalt/md.c
index 47808d3..a96053f 100644
--- a/distrib/utils/sysinst/arch/cobalt/md.c
+++ b/distrib/utils/sysinst/arch/cobalt/md.c
@@ -88,63 +88,63 @@ md_make_bsd_partitions(void)
 	 * Initialize global variables that track space used on this disk.
 	 * Standard 4.4BSD 8-partition labels always cover whole disk.
 	 */
-	if (ptsize == 0)
-		ptsize = dlsize - ptstart;
-	if (dlsize == 0)
-		dlsize = ptstart + ptsize;
+	if (pm->ptsize == 0)
+		pm->ptsize = pm->dlsize - pm->ptstart;
+	if (pm->dlsize == 0)
+		pm->dlsize = pm->ptstart + pm->ptsize;
 
-	partstart = ptstart;
-	ptend = ptstart + ptsize;
+	partstart = pm->ptstart;
+	ptend = pm->ptstart + pm->ptsize;
 
 	/* Ask for layout type -- standard or special */
 	msg_display(MSG_layout,
-		    ptsize / (MEG / sectorsize),
+		    pm->ptsize / (MEG / pm->sectorsize),
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);
 
 	process_menu(MENU_layout, NULL);
 
 	/* Set so we use the 'real' geometry for rounding, input in MB */
-	current_cylsize = dlcylsize;
+	pm->current_cylsize = pm->dlcylsize;
 	set_sizemultname_meg();
 
 	/* Build standard partitions */
-	memset(&bsdlabel, 0, sizeof bsdlabel);
+	memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
 
 	/* Set initial partition types to unused */
 	for (part = 0 ; part < maxpart ; ++part)
-		bsdlabel[part].pi_fstype = FS_UNUSED;
+		pm->bsdlabel[part].pi_fstype = FS_UNUSED;
 
 	/* Whole disk partition */
 	part_raw = getrawpartition();
 	if (part_raw == -1)
 		part_raw = PART_C;	/* for sanity... */
-	bsdlabel[part_raw].pi_offset = 0;
-	bsdlabel[part_raw].pi_size = dlsize;
+	pm->bsdlabel[part_raw].pi_offset = 0;
+	pm->bsdlabel[part_raw].pi_size = pm->dlsize;
 
 	if (part_raw == PART_D) {
 		/* Probably a system that expects an i386 style mbr */
 		part_bsd = PART_C;
-		bsdlabel[PART_C].pi_offset = ptstart;
-		bsdlabel[PART_C].pi_size = ptsize;
+		pm->bsdlabel[PART_C].pi_offset = pm->ptstart;
+		pm->bsdlabel[PART_C].pi_size = pm->ptsize;
 	} else {
 		part_bsd = part_raw;
 	}
 
-	if (bootsize != 0) {
-		bsdlabel[PART_BOOT_EXT2FS].pi_fstype = FS_EX2FS;
-		bsdlabel[PART_BOOT_EXT2FS].pi_size = bootsize;
-		bsdlabel[PART_BOOT_EXT2FS].pi_offset = bootstart;
-		bsdlabel[PART_BOOT_EXT2FS].pi_flags |=
+	if (pm->bootsize != 0) {
+		pm->bsdlabel[PART_BOOT_EXT2FS].pi_fstype = FS_EX2FS;
+		pm->bsdlabel[PART_BOOT_EXT2FS].pi_size = pm->bootsize;
+		pm->bsdlabel[PART_BOOT_EXT2FS].pi_offset = pm->bootstart;
+		pm->bsdlabel[PART_BOOT_EXT2FS].pi_flags |=
 		    PART_BOOT_EXT2FS_PI_FLAGS;
-		strlcpy(bsdlabel[PART_BOOT_EXT2FS].pi_mount,
+		strlcpy(pm->bsdlabel[PART_BOOT_EXT2FS].pi_mount,
 		    PART_BOOT_EXT2FS_PI_MOUNT,
-		    sizeof bsdlabel[PART_BOOT_EXT2FS].pi_mount);
+		    sizeof pm->bsdlabel[PART_BOOT_EXT2FS].pi_mount);
 	}
 
 #ifdef PART_REST
-	bsdlabel[PART_REST].pi_offset = 0;
-	bsdlabel[PART_REST].pi_size = ptstart;
+	pm->bsdlabel[PART_REST].pi_offset = 0;
+	pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
 #endif
 
 	/*
@@ -154,27 +154,27 @@ md_make_bsd_partitions(void)
 	 * partitions on a multiboot i386 system.
 	 */
 	 for (i = maxpart; i--;) {
-		if (bsdlabel[i].pi_size != 0)
+		if (pm->bsdlabel[i].pi_size != 0)
 			/* Don't overwrite special partitions */
 			continue;
-		p = &oldlabel[i];
+		p = &pm->oldlabel[i];
 		if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
 			continue;
-		if (layoutkind == 4) {
+		if (layoutkind == LY_USEEXIST) {
 			if (PI_ISBSDFS(p))
 				p->pi_flags |= PIF_MOUNT;
 		} else {
-			if (p->pi_offset < ptstart + ptsize &&
-			    p->pi_offset + p->pi_size > ptstart)
+			if (p->pi_offset < pm->ptstart + pm->ptsize &&
+			    p->pi_offset + p->pi_size > pm->ptstart)
 				/* Not outside area we are allocating */
 				continue;
 			if (p->pi_fstype == FS_SWAP)
 				no_swap = 1;
 		}
-		bsdlabel[i] = oldlabel[i];
+		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/* XXX Check we have a sensible layout */
 		;
 	} else
@@ -185,7 +185,7 @@ md_make_bsd_partitions(void)
 	 * edit it and verify it's OK, or abort altogether.
 	 */
  edit_check:
-	if (edit_and_check_label(bsdlabel, maxpart, part_raw, part_bsd) == 0) {
+	if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
 		msg_display(MSG_abort);
 		return 0;
 	}
@@ -193,10 +193,10 @@ md_make_bsd_partitions(void)
 		goto edit_check;
 
 	/* Disk name */
-	msg_prompt(MSG_packname, bsddiskname, bsddiskname, sizeof bsddiskname);
+	msg_prompt(MSG_packname, pm->bsddiskname, pm->bsddiskname, sizeof pm->bsddiskname);
 
 	/* save label to disk for MI code to update. */
-	(void)savenewlabel(bsdlabel, maxpart);
+	(void)savenewlabel(pm->bsdlabel, maxpart);
 
 	/* Everything looks OK. */
 	return 1;
@@ -215,7 +215,7 @@ md_check_partitions(void)
 	 * something stupid, like move it away from the MBR partition.
 	 */
 	for (part = PART_A; part < MAXPARTITIONS; part++)
-		if (bsdlabel[part].pi_fstype == FS_EX2FS) {
+		if (pm->bsdlabel[part].pi_fstype == FS_EX2FS) {
 			bootpart_ext2fs = part;
 			return 1;
 		}
@@ -234,7 +234,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -249,7 +249,7 @@ int
 md_post_disklabel(void)
 {
 	if (get_ramsize() <= 32)
-		set_swap(diskdev, bsdlabel);
+		set_swap(pm->diskdev, pm->bsdlabel);
 
 	return 0;
 }
@@ -273,7 +273,7 @@ md_post_newfs(void)
 	unsigned int i;
 
 	if (!nobootfs) {
-		msg_display(msg_string(MSG_copybootloader), diskdev);
+		msg_display(msg_string(MSG_copybootloader), pm->diskdev);
 
 		snprintf(bootdir, sizeof(bootdir), "%s/boot",
 		    target_expand(PART_BOOT_EXT2FS_PI_MOUNT));
@@ -311,9 +311,9 @@ md_pre_update(void)
 	int i;
 
 	if (get_ramsize() <= 32)
-		set_swap(diskdev, NULL);
+		set_swap(pm->diskdev, NULL);
 
-	read_mbr(diskdev, &mbr);
+	read_mbr(pm->diskdev, &mbr);
 	/* do a sanity check of the partition table */
 	for (ext = &mbr; ext; ext = ext->extended) {
 		part = ext->mbr.mbr_parts;
@@ -354,13 +354,13 @@ md_check_mbr(mbr_info_t *mbri)
 		part = ext->mbr.mbr_parts;
 		for (i = 0; i < MBR_PART_COUNT; part++, i++) {
 			if (part->mbrp_type == MBR_PTYPE_LNXEXT2) {
-				bootstart = part->mbrp_start;
-				bootsize = part->mbrp_size;
+				pm->bootstart = part->mbrp_start;
+				pm->bootsize = part->mbrp_size;
 				break;
 			}
 		}
 	}
-	if (bootsize < (MIN_EXT2FS_BOOT / 512)) {
+	if (pm->bootsize < (MIN_EXT2FS_BOOT / 512)) {
 		msg_display(MSG_boottoosmall);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -368,7 +368,7 @@ md_check_mbr(mbr_info_t *mbri)
 			return 0;
 		return 1;
 	}
-	if (bootstart == 0 || bootsize == 0) {
+	if (pm->bootstart == 0 || pm->bootsize == 0) {
 		msg_display(MSG_nobootpart);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -402,14 +402,14 @@ md_mbr_use_wholedisk(mbr_info_t *mbri)
 	part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
 
 	part[1].mbrp_type = MBR_PTYPE_NETBSD;
-	part[1].mbrp_size = dlsize - (bsec + EXT2FS_BOOT_SIZE / 512);
+	part[1].mbrp_size = pm->dlsize - (bsec + EXT2FS_BOOT_SIZE / 512);
 	part[1].mbrp_start = bsec + EXT2FS_BOOT_SIZE / 512;
 	part[1].mbrp_flag = 0;
 
-	ptstart = part[1].mbrp_start;
-	ptsize = part[1].mbrp_size;
-	bootstart = part[0].mbrp_start;
-	bootsize = part[0].mbrp_size;
+	pm->ptstart = part[1].mbrp_start;
+	pm->ptsize = part[1].mbrp_size;
+	pm->bootstart = part[0].mbrp_start;
+	pm->bootsize = part[0].mbrp_size;
 	return 1;
 }
 
diff --git a/distrib/utils/sysinst/arch/emips/md.c b/distrib/utils/sysinst/arch/emips/md.c
index 4a9004b..30e46e9 100644
--- a/distrib/utils/sysinst/arch/emips/md.c
+++ b/distrib/utils/sysinst/arch/emips/md.c
@@ -66,7 +66,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -87,21 +87,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/evbarm/md.c b/distrib/utils/sysinst/arch/evbarm/md.c
index 8971717..2a7b53f 100644
--- a/distrib/utils/sysinst/arch/evbarm/md.c
+++ b/distrib/utils/sysinst/arch/evbarm/md.c
@@ -67,21 +67,21 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	if (no_mbr)
+	if (pm->no_mbr)
 		return 1;
 
-	if (read_mbr(diskdev, &mbr) < 0)
+	if (read_mbr(pm->diskdev, &mbr) < 0)
 		memset(&mbr.mbr, 0, sizeof(mbr.mbr)-2);
 
 	if (edit_mbr(&mbr) == 0)
 		return 0;
 
-	if (strncmp(diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+	if (strncmp(pm->diskdev, "wd", 2) == 0)
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -97,21 +97,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -140,13 +140,13 @@ md_check_partitions(void)
 int
 md_pre_disklabel(void)
 {
-	if (no_mbr)
+	if (pm->no_mbr)
 		return 0;
 
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
diff --git a/distrib/utils/sysinst/arch/evbmips/md.c b/distrib/utils/sysinst/arch/evbmips/md.c
index a29e89a..841b0a7 100644
--- a/distrib/utils/sysinst/arch/evbmips/md.c
+++ b/distrib/utils/sysinst/arch/evbmips/md.c
@@ -85,13 +85,13 @@ md_check_partitions(void)
 int
 md_pre_disklabel(void)
 {
-	if (no_mbr)
+	if (pm->no_mbr)
 		return 0;
 
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
diff --git a/distrib/utils/sysinst/arch/evbppc/md.c b/distrib/utils/sysinst/arch/evbppc/md.c
index 9006c2d..f311431 100644
--- a/distrib/utils/sysinst/arch/evbppc/md.c
+++ b/distrib/utils/sysinst/arch/evbppc/md.c
@@ -88,7 +88,7 @@ md_pre_disklabel(void)
 	printf ("%s", msg_string (MSG_dofdisk));
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -103,10 +103,10 @@ int
 md_post_disklabel(void)
 {
 	/* Sector forwarding / badblocks ... */
-	if (*doessf) {
+	if (*pm->doessf) {
 		printf ("%s", msg_string (MSG_dobad144));
 		return run_program(RUN_DISPLAY, "/usr/sbin/bad144 %s 0",
-		    diskdev);
+		    pm->diskdev);
 	}
 	return 0;
 }
diff --git a/distrib/utils/sysinst/arch/evbsh3/md.c b/distrib/utils/sysinst/arch/evbsh3/md.c
index 6edfcda..76df729 100644
--- a/distrib/utils/sysinst/arch/evbsh3/md.c
+++ b/distrib/utils/sysinst/arch/evbsh3/md.c
@@ -55,7 +55,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
+	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -71,21 +71,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl * dlhead * dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/ews4800mips/md.c b/distrib/utils/sysinst/arch/ews4800mips/md.c
index 170a62a..925dde8 100644
--- a/distrib/utils/sysinst/arch/ews4800mips/md.c
+++ b/distrib/utils/sysinst/arch/ews4800mips/md.c
@@ -69,7 +69,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
+	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -85,21 +85,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl * dlhead * dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -129,7 +129,7 @@ md_check_partitions(void)
 int
 md_pre_disklabel(void)
 {
-	bsdlabel[PART_BOOT].pi_offset = ews4800mips_boot_offset();
+	pm->bsdlabel[PART_BOOT].pi_offset = ews4800mips_boot_offset();
 
 	return 0;
 }
@@ -158,7 +158,7 @@ md_post_newfs(void)
 	flags = RUN_DISPLAY | RUN_FATAL;
 	cp_to_target("/usr/mdec/boot", "/stand/boot");
 	run_program(flags, "/usr/sbin/installboot /dev/r%s%c %s",
-	    diskdev, 'a' + getrawpartition(),
+	    pm->diskdev, 'a' + getrawpartition(),
 	    "/usr/mdec/bootxx_bfs");
 
 	return 0;
@@ -195,7 +195,7 @@ md_update(void)
 static int
 ews4800mips_boot_offset(void)
 {
-	return dlcylsize;
+	return pm->dlcylsize;
 }
 
 /*
@@ -207,12 +207,12 @@ ews4800mips_boot_size(void)
 	int i;
 
 	/*
-	 * dlcylsize	: PDINFO block
-	 * dlcylsize	: 100 block
+	 * pm->dlcylsize	: PDINFO block
+	 * pm->dlcylsize	: 100 block
 	 */
-	i = dlcylsize + 100;
+	i = pm->dlcylsize + 100;
 	if (i >= 1024) /* XXX bsddisklabel.c hack. convert to byte count. */
-		i = dlcylsize * sectorsize * 2;
+		i = pm->dlcylsize * pm->sectorsize * 2;
 
 	return i;
 }
diff --git a/distrib/utils/sysinst/arch/hp300/md.c b/distrib/utils/sysinst/arch/hp300/md.c
index 9878885..e58dc39 100644
--- a/distrib/utils/sysinst/arch/hp300/md.c
+++ b/distrib/utils/sysinst/arch/hp300/md.c
@@ -66,7 +66,7 @@ md_get_info(void)
 	char dev_name[100];
 	struct disklabel disklabel;
 
-	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", diskdev);
+	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -92,12 +92,12 @@ md_get_info(void)
 		exit(1);
 	}
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
-	dlsize = dlcyl*dlhead*dlsec;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
 
 	if (read(fd, buf, 1024) < 0) {
 		endwin();
@@ -107,7 +107,7 @@ md_get_info(void)
 	}
 
 	/* We will preserve the first cylinder as PART_BOOT for bootloader. */
-	ptstart = 0;
+	pm->ptstart = 0;
 
 	close(fd);
 
@@ -139,22 +139,22 @@ md_check_partitions(void)
 	for (part = PART_A; part < MAXPARTITIONS; part++) {
 		if (part == PART_RAW || part == PART_BOOT)
 			continue;
-		if (last >= PART_A && bsdlabel[part].pi_size > 0) {
+		if (last >= PART_A && pm->bsdlabel[part].pi_size > 0) {
 			msg_display(MSG_emptypart, part+'a');
 			process_menu(MENU_ok, NULL);
 			return 0;
 		}
-		if (bsdlabel[part].pi_size == 0) {
+		if (pm->bsdlabel[part].pi_size == 0) {
 			if (last < PART_A)
 				last = part;
 		} else {
-			if (start >= bsdlabel[part].pi_offset) {
+			if (start >= pm->bsdlabel[part].pi_offset) {
 				msg_display(MSG_ordering, part+'a');
 				process_menu(MENU_yesno, NULL);
 				if (yesno)
 					return 0;
 			}
-			start = bsdlabel[part].pi_offset;
+			start = pm->bsdlabel[part].pi_offset;
 		}
 	}
 
@@ -177,7 +177,7 @@ int
 md_post_disklabel(void)
 {
 	if (get_ramsize() < 6)
-		set_swap(diskdev, bsdlabel);
+		set_swap(pm->diskdev, pm->bsdlabel);
 
 	return 0;
 }
@@ -193,9 +193,9 @@ int
 md_post_newfs(void)
 {
 	/* boot blocks ... */
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	if (run_program(RUN_DISPLAY | RUN_NO_CLEAR,
-	    "/usr/sbin/installboot /dev/r%sc /usr/mdec/uboot.lif", diskdev))
+	    "/usr/sbin/installboot /dev/r%sc /usr/mdec/uboot.lif", pm->diskdev))
 		process_menu(MENU_ok,
 		    deconst("Warning: disk is probably not bootable"));
 	return 0;
@@ -219,7 +219,7 @@ int
 md_pre_update(void)
 {
 	if (get_ramsize() < 6)
-		set_swap(diskdev, NULL);
+		set_swap(pm->diskdev, NULL);
 	return 1;
 }
 
@@ -239,9 +239,9 @@ hp300_boot_size(void)
 {
 	int i;
 
-	i = dlcylsize;
+	i = pm->dlcylsize;
 	if (i >= 1024) /* XXX: bsddisklabel.c has a hack. */
-		i = dlcylsize * sectorsize * 2;
+		i = pm->dlcylsize * pm->sectorsize * 2;
 
 	return i;
 }
diff --git a/distrib/utils/sysinst/arch/hp700/md.c b/distrib/utils/sysinst/arch/hp700/md.c
index ef52b11..229729c 100644
--- a/distrib/utils/sysinst/arch/hp700/md.c
+++ b/distrib/utils/sysinst/arch/hp700/md.c
@@ -70,7 +70,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -91,26 +91,26 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	/*
 	 * hp700 PDC can only address up to 2GB.
 	 */
-	root_limit = HP700_PDC_LIMIT / (unsigned)sectorsize;
+	root_limit = HP700_PDC_LIMIT / (unsigned)pm->sectorsize;
 
 	return 1;
 }
@@ -131,13 +131,13 @@ int
 md_check_partitions(void)
 {
 	/* Check the root partition is sane. */
-	uint32_t limit = HP700_PDC_LIMIT / (unsigned)sectorsize;
+	uint32_t limit = HP700_PDC_LIMIT / (unsigned)pm->sectorsize;
 	int part;
 
 	for (part = PART_A; part < MAXPARTITIONS; part++) {
-		if (strcmp(bsdlabel[part].pi_mount, "/") == 0) {
-			uint32_t offset = bsdlabel[part].pi_offset;
-			uint32_t size = bsdlabel[part].pi_size;
+		if (strcmp(pm->bsdlabel[part].pi_mount, "/") == 0) {
+			uint32_t offset = pm->bsdlabel[part].pi_offset;
+			uint32_t size = pm->bsdlabel[part].pi_size;
 
 			if (offset > limit || offset + size > limit) {
 				msg_display(MSG_md_pdclimit);
@@ -183,10 +183,10 @@ md_post_newfs(void)
 		return error;
 
 	/* boot blocks ... */
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	if (run_program(RUN_DISPLAY | RUN_NO_CLEAR,
 	    "/usr/sbin/installboot -v /dev/r%sc /usr/mdec/xxboot",
-	    diskdev))
+	    pm->diskdev))
 		process_menu(MENU_ok,
 			 deconst("Warning: disk is probably not bootable"));
 	return 0;
diff --git a/distrib/utils/sysinst/arch/hpcarm/md.c b/distrib/utils/sysinst/arch/hpcarm/md.c
index 1e1b3c6..4820214 100644
--- a/distrib/utils/sysinst/arch/hpcarm/md.c
+++ b/distrib/utils/sysinst/arch/hpcarm/md.c
@@ -117,7 +117,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -132,10 +132,10 @@ int
 md_post_disklabel(void)
 {
 	/* Sector forwarding / badblocks ... */
-	if (*doessf) {
+	if (*pm->doessf) {
 		msg_display(MSG_dobad144);
 		return run_program(RUN_DISPLAY, "/usr/sbin/bad144 %s 0",
-		    diskdev);
+		    pm->diskdev);
 	}
 	return 0;
 }
@@ -153,7 +153,7 @@ md_post_newfs(void)
 	ssize_t sz;
 	int fd = -1;
 
-	snprintf(adevname, sizeof(adevname), "/dev/r%sa", diskdev);
+	snprintf(adevname, sizeof(adevname), "/dev/r%sa", pm->diskdev);
 	fd = open(adevname, O_RDWR);
 	if (fd < 0)
 		goto out;
diff --git a/distrib/utils/sysinst/arch/hpcmips/md.c b/distrib/utils/sysinst/arch/hpcmips/md.c
index 0d2ef06..47eee83 100644
--- a/distrib/utils/sysinst/arch/hpcmips/md.c
+++ b/distrib/utils/sysinst/arch/hpcmips/md.c
@@ -91,7 +91,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -106,10 +106,10 @@ int
 md_post_disklabel(void)
 {
 	/* Sector forwarding / badblocks ... */
-	if (*doessf) {
+	if (*pm->doessf) {
 		msg_display(MSG_dobad144);
 		return run_program(RUN_DISPLAY, "/usr/sbin/bad144 %s 0",
-		    diskdev);
+		    pm->diskdev);
 	}
 	return 0;
 }
diff --git a/distrib/utils/sysinst/arch/hpcsh/md.c b/distrib/utils/sysinst/arch/hpcsh/md.c
index 0d76194..286ce20 100644
--- a/distrib/utils/sysinst/arch/hpcsh/md.c
+++ b/distrib/utils/sysinst/arch/hpcsh/md.c
@@ -96,7 +96,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
diff --git a/distrib/utils/sysinst/arch/i386/md.c b/distrib/utils/sysinst/arch/i386/md.c
index 291594b..bed7e5e 100644
--- a/distrib/utils/sysinst/arch/i386/md.c
+++ b/distrib/utils/sysinst/arch/i386/md.c
@@ -94,12 +94,12 @@ md_get_info(void)
 #define	NETBSD_NAMED	0x0400
 #define	ACTIVE_NAMED	0x0800
 
-	if (no_mbr)
+	if (pm->no_mbr)
 		return 1;
 
-	if (read_mbr(diskdev, &mbr) < 0)
+	if (read_mbr(pm->diskdev, &mbr) < 0)
 		memset(&mbr.mbr, 0, sizeof mbr.mbr - 2);
-	get_bios_info(diskdev);
+	get_bios_info(pm->diskdev);
 
 edit:
 	if (edit_mbr(&mbr) == 0)
@@ -118,7 +118,7 @@ edit:
 	}
 
 	/*
-	 * Ensure the install partition (at sector ptstart) and the active
+	 * Ensure the install partition (at sector pm->ptstart) and the active
 	 * partition are bootable.
 	 * Determine whether the bootselect code is needed.
 	 * Note that MBR_BS_NEWMBR is always set, so we ignore it!
@@ -130,14 +130,14 @@ edit:
 		for (i = 0; i < MBR_PART_COUNT; p++, i++) {
 			if (p->mbrp_flag == MBR_PFLAG_ACTIVE) {
 				fl |= ACTIVE_FOUND;
-			    if (ext->sector + p->mbrp_start == ptstart)
+			    if (ext->sector + p->mbrp_start == pm->ptstart)
 				fl |= NETBSD_ACTIVE;
 			}
 			if (ext->mbrb.mbrbs_nametab[i][0] == 0) {
 				/* No bootmenu label... */
 				if (ext->sector == 0)
 					continue;
-				if (ext->sector + p->mbrp_start == ptstart)
+				if (ext->sector + p->mbrp_start == pm->ptstart)
 					/*
 					 * Have installed into an extended ptn
 					 * force name & bootsel...
@@ -148,7 +148,7 @@ edit:
 			/* Partition has a bootmenu label... */
 			if (ext->sector != 0)
 				fl |= MBR_BS_EXTLBA;
-			if (ext->sector + p->mbrp_start == ptstart)
+			if (ext->sector + p->mbrp_start == pm->ptstart)
 				fl |= NETBSD_NAMED;
 			else if (p->mbrp_flag == MBR_PFLAG_ACTIVE)
 				fl |= ACTIVE_NAMED;
@@ -264,13 +264,13 @@ md_check_partitions(void)
 int
 md_pre_disklabel(void)
 {
-	if (no_mbr)
+	if (pm->no_mbr)
 		return 0;
 
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -285,7 +285,7 @@ int
 md_post_disklabel(void)
 {
 	if (get_ramsize() <= 32)
-		set_swap(diskdev, bsdlabel);
+		set_swap(pm->diskdev, pm->bsdlabel);
 
 	return 0;
 }
@@ -330,7 +330,7 @@ md_post_newfs(void)
 	}
 
 	process_menu(MENU_getboottype, &boottype);
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	if (bp.bp_consdev == ~0u)
 		return 0;
 
@@ -341,7 +341,7 @@ md_post_newfs(void)
 	/* Copy bootstrap in by hand - /sbin/installboot explodes ramdisks */
 	ret = 1;
 
-	snprintf(bootxx, sizeof bootxx, "/dev/r%s%c", diskdev, 'a' + rootpart);
+	snprintf(bootxx, sizeof bootxx, "/dev/r%s%c", pm->diskdev, 'a' + pm->rootpart);
 	td = open(bootxx, O_RDWR, 0);
 	bootxx_filename = bootxx_name();
 	if (bootxx_filename != NULL) {
@@ -410,7 +410,7 @@ int
 md_pre_update(void)
 {
 	if (get_ramsize() <= 8)
-		set_swap(diskdev, NULL);
+		set_swap(pm->diskdev, NULL);
 	return 1;
 }
 
@@ -468,7 +468,7 @@ get_bios_info(char *dev)
 	if (nip == NULL || nip->ni_nmatches == 0) {
 nogeom:
 		if (nip != NULL)
-			msg_display(MSG_nobiosgeom, dlcyl, dlhead, dlsec);
+			msg_display(MSG_nobiosgeom, pm->dlcyl, pm->dlhead, pm->dlsec);
 		if (guess_biosgeom_from_mbr(&mbr, &cyl, &head, &sec) >= 0
 		    && nip != NULL)
 			msg_display_add(MSG_biosguess, cyl, head, sec);
@@ -524,7 +524,7 @@ nogeom:
 static int
 mbr_root_above_chs(void)
 {
-	return ptstart + DEFROOTSIZE * (MEG / 512) >= bcyl * bhead * bsec;
+	return pm->ptstart + DEFROOTSIZE * (MEG / 512) >= bcyl * bhead * bsec;
 }
 
 static void
@@ -533,10 +533,10 @@ md_upgrade_mbrtype(void)
 	struct mbr_partition *mbrp;
 	int i, netbsdpart = -1, oldbsdpart = -1, oldbsdcount = 0;
 
-	if (no_mbr)
+	if (pm->no_mbr)
 		return;
 
-	if (read_mbr(diskdev, &mbr) < 0)
+	if (read_mbr(pm->diskdev, &mbr) < 0)
 		return;
 
 	mbrp = &mbr.mbr.mbr_parts[0];
@@ -551,7 +551,7 @@ md_upgrade_mbrtype(void)
 
 	if (netbsdpart == -1 && oldbsdcount == 1) {
 		mbrp[oldbsdpart].mbrp_type = MBR_PTYPE_NETBSD;
-		write_mbr(diskdev, &mbr, 0);
+		write_mbr(pm->diskdev, &mbr, 0);
 	}
 }
 
diff --git a/distrib/utils/sysinst/arch/landisk/md.c b/distrib/utils/sysinst/arch/landisk/md.c
index da86bd2..f1ffa64 100644
--- a/distrib/utils/sysinst/arch/landisk/md.c
+++ b/distrib/utils/sysinst/arch/landisk/md.c
@@ -85,15 +85,15 @@ md_check_partitions(void)
 int
 md_pre_disklabel(void)
 {
-	if (no_mbr)
+	if (pm->no_mbr)
 		return 0;
 
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0 ||
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0 ||
 	    run_program(RUN_SILENT | RUN_ERROR_OK,
-	    "/sbin/fdisk -f -i -c /usr/mdec/mbr %s", diskdev)) {
+	    "/sbin/fdisk -f -i -c /usr/mdec/mbr %s", pm->diskdev)) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -124,12 +124,12 @@ md_post_newfs(void)
 	char *bootxx;
 	int error;
 
-	printf (msg_string(MSG_dobootblks), diskdev);
+	printf (msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot", "/boot");
 	bootxx = bootxx_name();
 	if (bootxx != NULL) {
 		error = run_program(RUN_DISPLAY | RUN_NO_CLEAR,
-		    "/usr/sbin/installboot -v /dev/r%sa %s", diskdev, bootxx);
+		    "/usr/sbin/installboot -v /dev/r%sa %s", pm->diskdev, bootxx);
 		free(bootxx);
 	} else
 		error = -1;
diff --git a/distrib/utils/sysinst/arch/luna68k/md.c b/distrib/utils/sysinst/arch/luna68k/md.c
index 42cb144..b27b69f 100644
--- a/distrib/utils/sysinst/arch/luna68k/md.c
+++ b/distrib/utils/sysinst/arch/luna68k/md.c
@@ -68,7 +68,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", diskdev);
+	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -84,21 +84,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl * dlhead * dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -156,11 +156,11 @@ md_post_newfs(void)
 #if 0	/* no bootloader (yet) */
 	const char *bootfile = "/boot";
 
-	printf(msg_string(MSG_dobootblks), diskdev);
+	printf(msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot", bootfile);
 	sync();
 	run_program(RUN_DISPLAY, "/usr/sbin/installboot /dev/r%sc %s %s",
-	    diskdev, "/usr/mdec/bootxx", bootfile);
+	    pm->diskdev, "/usr/mdec/bootxx", bootfile);
 #endif
 	return 0;
 }
diff --git a/distrib/utils/sysinst/arch/mac68k/md.c b/distrib/utils/sysinst/arch/mac68k/md.c
index f47052d..c2ad149 100644
--- a/distrib/utils/sysinst/arch/mac68k/md.c
+++ b/distrib/utils/sysinst/arch/mac68k/md.c
@@ -140,7 +140,7 @@ md_get_info(void)
 	struct apple_part_map_entry block;
 
 	snprintf(dev_name, sizeof(dev_name), "/dev/r%s%c",
-		diskdev, 'a' + getrawpartition());
+		pm->diskdev, 'a' + getrawpartition());
 
 	/*
 	 * Open the disk as a raw device
@@ -165,29 +165,29 @@ md_get_info(void)
 	 *  obained them by querying the disk itself.
 	 */
 	blk_size = disklabel.d_secsize;
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
 	/*
 	 * Just in case, initialize the structures we'll need if we
 	 *  need to completely initialize the disk.
 	 */
-	dlsize = disklabel.d_secperunit;
+	pm->dlsize = disklabel.d_secperunit;
 	for (i=0;i<NEW_MAP_SIZE;i++) {
 	   if (i > 0)
 		new_map[i].pmPyPartStart = new_map[i-1].pmPyPartStart +
 			new_map[i-1].pmPartBlkCnt;
 	   new_map[i].pmDataCnt = new_map[i].pmPartBlkCnt;
 	   if (new_map[i].pmPartBlkCnt == 0) {
-		new_map[i].pmPartBlkCnt = dlsize;
-		new_map[i].pmDataCnt = dlsize;
+		new_map[i].pmPartBlkCnt = pm->dlsize;
+		new_map[i].pmDataCnt = pm->dlsize;
 		break;
 	   }
-	   dlsize -= new_map[i].pmPartBlkCnt;
+	   pm->dlsize -= new_map[i].pmPartBlkCnt;
 	}
-	dlsize = disklabel.d_secperunit;
+	pm->dlsize = disklabel.d_secperunit;
 #if 0
-	msg_display(MSG_dldebug, blk_size, dlcyl, dlhead, dlsec, dlsize);
+	msg_display(MSG_dldebug, blk_size, pm->dlcyl, pm->dlhead, pm->dlsec, pm->dlsize);
 	process_menu(MENU_ok, NULL);
 #endif
 	map.size = 0;
@@ -223,11 +223,11 @@ md_get_info(void)
 	/*
 	 * Setup the disktype so /etc/disktab gets proper info
 	 */
-	if (strncmp(diskdev, "sd", 2) == 0) {
-		disktype = "SCSI";
-		doessf = "sf:";
+	if (strncmp(pm->diskdev, "sd", 2) == 0) {
+		pm->disktype = "SCSI";
+		pm->doessf = "sf:";
 	} else
-		disktype = "IDE";
+		pm->disktype = "IDE";
 
 	return edit_diskmap();
 }
@@ -261,13 +261,13 @@ md_make_bsd_partitions(void)
 	}
 
 	/* Build standard partitions */
-	memset(&bsdlabel, 0, sizeof bsdlabel);
+	memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
 
 	/*
 	 * The mac68k port has a predefined partition for "c" which
 	 *  is the size of the disk, everything else is unused.
 	 */
-	bsdlabel[RAW_PART].pi_size = dlsize;
+	pm->bsdlabel[RAW_PART].pi_size = pm->dlsize;
 	/*
 	 * Now, scan through the Disk Partition Map and transfer the
 	 *  information into the incore disklabel.
@@ -279,37 +279,37 @@ md_make_bsd_partitions(void)
 		pl = bzb->flags.part - 'a';
 		switch (whichType(&map.blk[j])) {
 		    case HFS_PART:
-			bsdlabel[pl].pi_fstype = FS_HFS;
-			strcpy (bsdlabel[pl].pi_mount, (char *)bzb->mount_point);
+			pm->bsdlabel[pl].pi_fstype = FS_HFS;
+			strcpy (pm->bsdlabel[pl].pi_mount, (char *)bzb->mount_point);
 			break;
 		    case ROOT_PART:
 		    case UFS_PART:
-			bsdlabel[pl].pi_fstype = FS_BSDFFS;
-			strcpy (bsdlabel[pl].pi_mount, (char *)bzb->mount_point);
-			bsdlabel[pl].pi_flags |= PIF_NEWFS | PIF_MOUNT;
+			pm->bsdlabel[pl].pi_fstype = FS_BSDFFS;
+			strcpy (pm->bsdlabel[pl].pi_mount, (char *)bzb->mount_point);
+			pm->bsdlabel[pl].pi_flags |= PIF_NEWFS | PIF_MOUNT;
 			break;
 		    case SWAP_PART:
-			bsdlabel[pl].pi_fstype = FS_SWAP;
+			pm->bsdlabel[pl].pi_fstype = FS_SWAP;
 			break;
 		    case SCRATCH_PART:
-			bsdlabel[pl].pi_fstype = FS_OTHER;
-			strcpy (bsdlabel[pl].pi_mount, (char *)bzb->mount_point);
+			pm->bsdlabel[pl].pi_fstype = FS_OTHER;
+			strcpy (pm->bsdlabel[pl].pi_mount, (char *)bzb->mount_point);
 		    default:
 			break;
 		}
-	        if (bsdlabel[pl].pi_fstype != FS_UNUSED) {
-		    bsdlabel[pl].pi_size = map.blk[j].pmPartBlkCnt;
-		    bsdlabel[pl].pi_offset = map.blk[j].pmPyPartStart;
-		    if (bsdlabel[pl].pi_fstype != FS_SWAP) {
-		        bsdlabel[pl].pi_frag = 8;
-		        bsdlabel[pl].pi_fsize = 1024;
+	        if (pm->bsdlabel[pl].pi_fstype != FS_UNUSED) {
+		    pm->bsdlabel[pl].pi_size = map.blk[j].pmPartBlkCnt;
+		    pm->bsdlabel[pl].pi_offset = map.blk[j].pmPyPartStart;
+		    if (pm->bsdlabel[pl].pi_fstype != FS_SWAP) {
+		        pm->bsdlabel[pl].pi_frag = 8;
+		        pm->bsdlabel[pl].pi_fsize = 1024;
 		    }
 		}
 	    }
 	}
 
 	/* Disk name  - don't bother asking, just use the physical name*/
-	strcpy (bsddiskname, diskdev);
+	strcpy (pm->bsddiskname, pm->diskdev);
 
 #ifdef DEBUG
 	f = fopen ("/tmp/disktab", "w");
@@ -321,26 +321,26 @@ md_make_bsd_partitions(void)
 		(void) fprintf (stderr, "Could not open /etc/disktab");
 		exit (1);
 	}
-	(void)fprintf (f, "%s|NetBSD installation generated:\\\n", bsddiskname);
-	(void)fprintf (f, "\t:dt=%s:ty=winchester:\\\n", disktype);
-	(void)fprintf (f, "\t:nc#%d:nt#%d:ns#%d:\\\n", dlcyl, dlhead, dlsec);
-	(void)fprintf (f, "\t:sc#%d:su#%" PRIu32 ":\\\n", dlhead*dlsec, (uint32_t)dlsize);
-	(void)fprintf (f, "\t:se#%d:%s\\\n", blk_size, doessf);
+	(void)fprintf (f, "%s|NetBSD installation generated:\\\n", pm->bsddiskname);
+	(void)fprintf (f, "\t:dt=%s:ty=winchester:\\\n", pm->disktype);
+	(void)fprintf (f, "\t:nc#%d:nt#%d:ns#%d:\\\n", pm->dlcyl, pm->dlhead, pm->dlsec);
+	(void)fprintf (f, "\t:sc#%d:su#%" PRIu32 ":\\\n", pm->dlhead*pm->dlsec, (uint32_t)pm->dlsize);
+	(void)fprintf (f, "\t:se#%d:%s\\\n", blk_size, pm->doessf);
 	for (i=0; i<8; i++) {
-		if (bsdlabel[i].pi_fstype == FS_HFS)
+		if (pm->bsdlabel[i].pi_fstype == FS_HFS)
 		    (void)fprintf (f, "\t:p%c#%d:o%c#%d:t%c=macos:",
-			       'a'+i, bsdlabel[i].pi_size,
-			       'a'+i, bsdlabel[i].pi_offset,
+			       'a'+i, pm->bsdlabel[i].pi_size,
+			       'a'+i, pm->bsdlabel[i].pi_offset,
 			       'a'+i);
 		else
 		    (void)fprintf (f, "\t:p%c#%d:o%c#%d:t%c=%s:",
-			       'a'+i, bsdlabel[i].pi_size,
-			       'a'+i, bsdlabel[i].pi_offset,
-			       'a'+i, getfslabelname(bsdlabel[i].pi_fstype));
-		if (bsdlabel[i].pi_fstype == FS_BSDFFS)
+			       'a'+i, pm->bsdlabel[i].pi_size,
+			       'a'+i, pm->bsdlabel[i].pi_offset,
+			       'a'+i, getfslabelname(pm->bsdlabel[i].pi_fstype));
+		if (pm->bsdlabel[i].pi_fstype == FS_BSDFFS)
 			(void)fprintf (f, "b%c#%d:f%c#%d",
-			   'a'+i, bsdlabel[i].pi_fsize * bsdlabel[i].pi_frag,
-			   'a'+i, bsdlabel[i].pi_fsize);
+			   'a'+i, pm->bsdlabel[i].pi_fsize * pm->bsdlabel[i].pi_frag,
+			   'a'+i, pm->bsdlabel[i].pi_fsize);
 		if (i < 7)
 			(void)fprintf (f, "\\\n");
 		else
@@ -379,7 +379,7 @@ md_pre_disklabel(void)
      */
     printf ("%s", msg_string (MSG_dodiskmap));
 
-    snprintf (dev_name, sizeof(dev_name), "/dev/r%sc", diskdev);
+    snprintf (dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
     /*
      * Open the disk as a raw device
      */
@@ -400,7 +400,7 @@ md_pre_disklabel(void)
 	    close (fd);
 	    exit (1);
 	}
-	new_block0.sbBlkCount = dlsize;		/* Set disk size */
+	new_block0.sbBlkCount = pm->dlsize;		/* Set disk size */
 	if (write (fd, &new_block0, blk_size) != blk_size) {
 	    endwin();
 	    fprintf (stderr, "I/O error writing Block0\n");
@@ -429,7 +429,7 @@ md_pre_disklabel(void)
      * should be done by disklabel -- which is normally called right after
      * we return -- but may be commented out for the mac68k port. We'll
      * instead update the incore table by forcing a dummy write here. This
-     * relies on a change in the mac68k-specific writedisklabel() routine.
+     * relies on a change in the mac68k-specific write_disklabel() routine.
      * If that change doesn't exist nothing bad happens here. If disklabel
      * properly updates the ondisk and incore labels everything still
      * works. Only if we fail here and if disklabel fails are we in
@@ -465,7 +465,7 @@ md_post_disklabel(void)
 			"9660", "boot", "ados", "hfs ", "fcor", "ex2f",
 			"ntfs", "raid", "ccd "};
 
-    snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", diskdev);
+    snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
     /*
      * Open the disk as a raw device
      */
@@ -484,12 +484,12 @@ md_post_disklabel(void)
     for (i=0;i<MAXPARTITIONS;i++) {
         if (i > updated_label.d_npartitions)
            break;
-        if (bsdlabel[i].pi_size != updated_label.d_partitions[i].p_size)
+        if (pm->bsdlabel[i].pi_size != updated_label.d_partitions[i].p_size)
            no_match = 1;
-        if (bsdlabel[i].pi_size) {
-           if (bsdlabel[i].pi_offset != updated_label.d_partitions[i].p_offset)
+        if (pm->bsdlabel[i].pi_size) {
+           if (pm->bsdlabel[i].pi_offset != updated_label.d_partitions[i].p_offset)
                no_match = 1;
-           if (bsdlabel[i].pi_fstype != updated_label.d_partitions[i].p_fstype)
+           if (pm->bsdlabel[i].pi_fstype != updated_label.d_partitions[i].p_fstype)
                no_match = 1;
         }
         if (no_match)
@@ -505,8 +505,8 @@ md_post_disklabel(void)
            " in-core: offset      size type on-disk: offset      size type");
        for (i=0;i<MAXPARTITIONS;i++) {
            sprintf(buf, " %c:%13.8x%10.8x%5s%16.8x%10.8x%5s", i+'a',
-              bsdlabel[i].pi_offset, bsdlabel[i].pi_size,
-              fst[bsdlabel[i].pi_fstype],
+              pm->bsdlabel[i].pi_offset, pm->bsdlabel[i].pi_size,
+              fst[pm->bsdlabel[i].pi_fstype],
               updated_label.d_partitions[i].p_offset,
               updated_label.d_partitions[i].p_size,
               fst[updated_label.d_partitions[i].p_fstype]);
@@ -759,7 +759,7 @@ getName(part, len_name, name)
 		/*
 		 * OK, this is stupid but it's damn nice to know!
 		 */
-		snprintf (dev_name, sizeof(dev_name), "/dev/r%sc", diskdev);
+		snprintf (dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
 		/*
 		 * Open the disk as a raw device
 		 */
@@ -1048,7 +1048,7 @@ disp_selected_part(sel)
 	    getUse(&map.blk[j], sizeof(use), use);
 	    getName(&map.blk[j], sizeof(name), name);
 	    bzb = (EBZB *)&map.blk[j].pmBootArgs[0];
-	    msg_table_add(MSG_part_row, diskdev,
+	    msg_table_add(MSG_part_row, pm->diskdev,
 		bzb->flags.part, map.blk[j].pmPyPartStart,
                  map.blk[j].pmPartBlkCnt, fstyp, use, name);
 	    if (i == sel) msg_standend();
@@ -1070,9 +1070,9 @@ check_for_errors()
 
     for (i=0;i<map.usable_cnt;i++) {
 	j = map.mblk[i];
-	if (map.blk[j].pmPyPartStart > dlsize)
+	if (map.blk[j].pmPyPartStart > pm->dlsize)
 		errs++;
-	if ((map.blk[j].pmPyPartStart + map.blk[j].pmPartBlkCnt) > dlsize + 1)
+	if ((map.blk[j].pmPyPartStart + map.blk[j].pmPartBlkCnt) > pm->dlsize + 1)
 		errs++;
     }
     return(errs);
@@ -1106,16 +1106,16 @@ report_errors()
     }
     for (i=0;i<map.usable_cnt;i++) {
 	j = map.mblk[i];
-	if (map.blk[j].pmPyPartStart > dlsize) {
+	if (map.blk[j].pmPyPartStart > pm->dlsize) {
 	    bzb = (EBZB *)&map.blk[j].pmBootArgs[0];
 	    msg_display_add(MSG_disksetup_part_beginning,
-		diskdev, bzb->flags.part);
+		pm->diskdev, bzb->flags.part);
 	    errs++;
 	}
-	if ((map.blk[j].pmPyPartStart + map.blk[j].pmPartBlkCnt) > dlsize) {
+	if ((map.blk[j].pmPyPartStart + map.blk[j].pmPartBlkCnt) > pm->dlsize) {
 	    bzb = (EBZB *)&map.blk[j].pmBootArgs[0];
 	    msg_display_add(MSG_disksetup_part_size,
-		diskdev, bzb->flags.part);
+		pm->diskdev, bzb->flags.part);
 	    errs++;
 	}
     }
@@ -1130,7 +1130,7 @@ edit_diskmap(void)
     int i;
 
 	/* Ask full/part */
-	msg_display (MSG_fullpart, diskdev);
+	msg_display (MSG_fullpart, pm->diskdev);
 	process_menu (MENU_fullpart, NULL);
 
 	map.selected = 0;
diff --git a/distrib/utils/sysinst/arch/mac68k/menus.md.de b/distrib/utils/sysinst/arch/mac68k/menus.md.de
index 5164dad..79830b0 100644
--- a/distrib/utils/sysinst/arch/mac68k/menus.md.de
+++ b/distrib/utils/sysinst/arch/mac68k/menus.md.de
@@ -39,7 +39,7 @@ menu fullpart, title  "Bitte w
 	option "Die ganze Festplatte für NetBSD verwenden", exit, action  {usefull = 1;};
 
 menu nodiskmap, title "Bitte wählen Sie", y=16;
-	display action { msg_display (MSG_nodiskmap, diskdev); };
+	display action { msg_display (MSG_nodiskmap, pm->diskdev); };
 	option "Installation abbrechen", exit, action {
 		endwin();  exit(1);
 	};
@@ -99,9 +99,9 @@ menu editparttable, title  "W
 			bzb->mount_point[0] = '\0';
 			strcpy (map.blk[k].pmPartType, "Apple_Free");
 			map.blk[k].pmPyPartStart += size;
-			if ((map.blk[k].pmPyPartStart + free_size) > dlsize)
+			if ((map.blk[k].pmPyPartStart + free_size) > pm->dlsize)
 			    map.blk[k].pmPartBlkCnt =
-				dlsize - map.blk[k].pmPyPartStart;
+				pm->dlsize - map.blk[k].pmPyPartStart;
 			else
 			    map.blk[k].pmPartBlkCnt = free_size;
 			map.blk[k].pmDataCnt = map.blk[k].pmPartBlkCnt;
@@ -129,20 +129,20 @@ menu editparttable, title  "W
 	option "Partition korrigieren", action {
 		int i = map.mblk[map.selected];
 		EBZB *bzb = (EBZB *)&map.blk[i].pmBootArgs[0];
-		msg_display(MSG_partdebug, diskdev, bzb->flags.part,
+		msg_display(MSG_partdebug, pm->diskdev, bzb->flags.part,
 			map.blk[i].pmPyPartStart,
 			map.blk[i].pmPartBlkCnt);
 		if ((map.blk[i].pmPyPartStart +
-		    map.blk[i].pmPartBlkCnt) > dlsize) {
+		    map.blk[i].pmPartBlkCnt) > pm->dlsize) {
 			msg_display_add(MSG_parttable_fix_fixing,
-				diskdev, bzb->flags.part);
+				pm->diskdev, bzb->flags.part);
 			map.blk[i].pmPartBlkCnt =
-			    dlsize - map.blk[i].pmPyPartStart;
+			    pm->dlsize - map.blk[i].pmPyPartStart;
 			map.blk[i].pmDataCnt =
 			    map.blk[i].pmPartBlkCnt;
 		} else {
 		    msg_display_add(MSG_parttable_fix_fine,
-			diskdev, bzb->flags.part);
+			pm->diskdev, bzb->flags.part);
 		}
 		process_menu(MENU_ok, NULL);
 		};
diff --git a/distrib/utils/sysinst/arch/mac68k/menus.md.en b/distrib/utils/sysinst/arch/mac68k/menus.md.en
index a4c18e3..4ae1bce 100644
--- a/distrib/utils/sysinst/arch/mac68k/menus.md.en
+++ b/distrib/utils/sysinst/arch/mac68k/menus.md.en
@@ -39,7 +39,7 @@ menu fullpart, title  "Select your choice";
 	option "Use the entire disk", 	    exit, action  {usefull = 1;};
 
 menu nodiskmap, title "Choose an option", y=16;
-	display action { msg_display (MSG_nodiskmap, diskdev); };
+	display action { msg_display (MSG_nodiskmap, pm->diskdev); };
 	option "Abort install", exit, action {
 		endwin();  exit(1);
 	};
@@ -99,9 +99,9 @@ menu editparttable, title  "Choose your partition", exit, y=14;
 			bzb->mount_point[0] = '\0';
 			strcpy ((char *)map.blk[k].pmPartType, "Apple_Free");
 			map.blk[k].pmPyPartStart += size;
-			if ((map.blk[k].pmPyPartStart + free_size) > dlsize)
+			if ((map.blk[k].pmPyPartStart + free_size) > pm->dlsize)
 			    map.blk[k].pmPartBlkCnt =
-				dlsize - map.blk[k].pmPyPartStart;
+				pm->dlsize - map.blk[k].pmPyPartStart;
 			else
 			    map.blk[k].pmPartBlkCnt = free_size;
 			map.blk[k].pmDataCnt = map.blk[k].pmPartBlkCnt;
@@ -129,20 +129,20 @@ menu editparttable, title  "Choose your partition", exit, y=14;
 	option "Fix selected partition", action {
 		int i = map.mblk[map.selected];
 		EBZB *bzb = (EBZB *)&map.blk[i].pmBootArgs[0];
-		msg_display(MSG_partdebug, diskdev, bzb->flags.part,
+		msg_display(MSG_partdebug, pm->diskdev, bzb->flags.part,
 			map.blk[i].pmPyPartStart,
 			map.blk[i].pmPartBlkCnt);
 		if ((map.blk[i].pmPyPartStart +
-		    map.blk[i].pmPartBlkCnt) > dlsize) {
+		    map.blk[i].pmPartBlkCnt) > pm->dlsize) {
 			msg_display_add(MSG_parttable_fix_fixing,
-				diskdev, bzb->flags.part);
+				pm->diskdev, bzb->flags.part);
 			map.blk[i].pmPartBlkCnt =
-			    dlsize - map.blk[i].pmPyPartStart;
+			    pm->dlsize - map.blk[i].pmPyPartStart;
 			map.blk[i].pmDataCnt =
 			    map.blk[i].pmPartBlkCnt;
 		} else {
 		    msg_display_add(MSG_parttable_fix_fine,
-			diskdev, bzb->flags.part);
+			pm->diskdev, bzb->flags.part);
 		}
 		process_menu(MENU_ok, NULL);
 		};
diff --git a/distrib/utils/sysinst/arch/mac68k/menus.md.es b/distrib/utils/sysinst/arch/mac68k/menus.md.es
index 3c81043..d79e4cd 100644
--- a/distrib/utils/sysinst/arch/mac68k/menus.md.es
+++ b/distrib/utils/sysinst/arch/mac68k/menus.md.es
@@ -39,7 +39,7 @@ menu fullpart, title  "Seleccione su opcion";
 	option "Usar el disco entero", 	    exit, action  {usefull = 1;};
 
 menu nodiskmap, title "Escoja una opcion", y=16;
-	display action { msg_display (MSG_nodiskmap, diskdev); };
+	display action { msg_display (MSG_nodiskmap, pm->diskdev); };
 	option "Abortar instalacion", exit, action {
 		endwin();  exit(1);
 	};
@@ -99,9 +99,9 @@ menu editparttable, title  "Escoja su particion", exit, y=14;
 			bzb->mount_point[0] = '\0';
 			strcpy (map.blk[k].pmPartType, "Apple_Free");
 			map.blk[k].pmPyPartStart += size;
-			if ((map.blk[k].pmPyPartStart + free_size) > dlsize)
+			if ((map.blk[k].pmPyPartStart + free_size) > pm->dlsize)
 			    map.blk[k].pmPartBlkCnt =
-				dlsize - map.blk[k].pmPyPartStart;
+				pm->dlsize - map.blk[k].pmPyPartStart;
 			else
 			    map.blk[k].pmPartBlkCnt = free_size;
 			map.blk[k].pmDataCnt = map.blk[k].pmPartBlkCnt;
@@ -129,20 +129,20 @@ menu editparttable, title  "Escoja su particion", exit, y=14;
 	option "Arreglar particion seleccionada", action {
 		int i = map.mblk[map.selected];
 		EBZB *bzb = (EBZB *)&map.blk[i].pmBootArgs[0];
-		msg_display(MSG_partdebug, diskdev, bzb->flags.part,
+		msg_display(MSG_partdebug, pm->diskdev, bzb->flags.part,
 			map.blk[i].pmPyPartStart,
 			map.blk[i].pmPartBlkCnt);
 		if ((map.blk[i].pmPyPartStart +
-		    map.blk[i].pmPartBlkCnt) > dlsize) {
+		    map.blk[i].pmPartBlkCnt) > pm->dlsize) {
 			msg_display_add(MSG_parttable_fix_fixing,
-				diskdev, bzb->flags.part);
+				pm->diskdev, bzb->flags.part);
 			map.blk[i].pmPartBlkCnt =
-			    dlsize - map.blk[i].pmPyPartStart;
+			    pm->dlsize - map.blk[i].pmPyPartStart;
 			map.blk[i].pmDataCnt =
 			    map.blk[i].pmPartBlkCnt;
 		} else {
 		    msg_display_add(MSG_parttable_fix_fine,
-			diskdev, bzb->flags.part);
+			pm->diskdev, bzb->flags.part);
 		}
 		process_menu(MENU_ok, NULL);
 		};
diff --git a/distrib/utils/sysinst/arch/mac68k/menus.md.pl b/distrib/utils/sysinst/arch/mac68k/menus.md.pl
index 8d5a70d..41de635 100644
--- a/distrib/utils/sysinst/arch/mac68k/menus.md.pl
+++ b/distrib/utils/sysinst/arch/mac68k/menus.md.pl
@@ -41,7 +41,7 @@ menu fullpart, title  "Wybierz";
 	option "Uzyj calego dysku", 	    exit, action  {usefull = 1;};
 
 menu nodiskmap, title "Wybierz opcje", y=16;
-       display action { msg_display (MSG_nodiskmap, diskdev); };
+       display action { msg_display (MSG_nodiskmap, pm->diskdev); };
        option "Przerwij instalacje", exit, action {
 		endwin();  exit(1);
 	};
@@ -101,9 +101,9 @@ menu editparttable, title  "Wybierz swoje partycje", exit, y=14;
 			bzb->mount_point[0] = '\0';
 			strcpy (map.blk[k].pmPartType, "Apple_Free");
 			map.blk[k].pmPyPartStart += size;
-			if ((map.blk[k].pmPyPartStart + free_size) > dlsize)
+			if ((map.blk[k].pmPyPartStart + free_size) > pm->dlsize)
 			    map.blk[k].pmPartBlkCnt =
-				dlsize - map.blk[k].pmPyPartStart;
+				pm->dlsize - map.blk[k].pmPyPartStart;
 			else
 			    map.blk[k].pmPartBlkCnt = free_size;
 			map.blk[k].pmDataCnt = map.blk[k].pmPartBlkCnt;
@@ -131,20 +131,20 @@ menu editparttable, title  "Wybierz swoje partycje", exit, y=14;
 	option "Napraw wybrana partycje", action {
 		int i = map.mblk[map.selected];
 		EBZB *bzb = (EBZB *)&map.blk[i].pmBootArgs[0];
-		msg_display(MSG_partdebug, diskdev, bzb->flags.part,
+		msg_display(MSG_partdebug, pm->diskdev, bzb->flags.part,
 			map.blk[i].pmPyPartStart,
 			map.blk[i].pmPartBlkCnt);
 		if ((map.blk[i].pmPyPartStart +
-		    map.blk[i].pmPartBlkCnt) > dlsize) {
+		    map.blk[i].pmPartBlkCnt) > pm->dlsize) {
 			msg_display_add(MSG_parttable_fix_fixing,
-				diskdev, bzb->flags.part);
+				pm->diskdev, bzb->flags.part);
 			map.blk[i].pmPartBlkCnt =
-			    dlsize - map.blk[i].pmPyPartStart;
+			    pm->dlsize - map.blk[i].pmPyPartStart;
 			map.blk[i].pmDataCnt =
 			    map.blk[i].pmPartBlkCnt;
 		} else {
 		    msg_display_add(MSG_parttable_fix_fine,
-			diskdev, bzb->flags.part);
+			pm->diskdev, bzb->flags.part);
 		}
 		process_menu(MENU_ok, NULL);
 		};
diff --git a/distrib/utils/sysinst/arch/macppc/md.c b/distrib/utils/sysinst/arch/macppc/md.c
index 2b9d90c..d9138ea 100644
--- a/distrib/utils/sysinst/arch/macppc/md.c
+++ b/distrib/utils/sysinst/arch/macppc/md.c
@@ -67,7 +67,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf (dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf (dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open (dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -83,21 +83,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -172,14 +172,14 @@ md_post_newfs(void)
 	 * yet, so assume partition a has some offset on OF3 machines
 	 * and don't try installboot(8) in that case.
 	 */
-	if (bsdlabel[PART_A].pi_offset != 0)
+	if (pm->bsdlabel[PART_A].pi_offset != 0)
 		return 0;
 
-	printf (msg_string(MSG_dobootblks), diskdev);
+	printf (msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/ofwboot", bootfile);
 	sync();
 	run_program(RUN_DISPLAY, "/usr/sbin/installboot /dev/r%sa %s %s",
-	    diskdev, "/usr/mdec/bootxx", bootfile);
+	    pm->diskdev, "/usr/mdec/bootxx", bootfile);
 	return 0;
 }
 
diff --git a/distrib/utils/sysinst/arch/mipsco/md.c b/distrib/utils/sysinst/arch/mipsco/md.c
index 1a035d5..5722452 100644
--- a/distrib/utils/sysinst/arch/mipsco/md.c
+++ b/distrib/utils/sysinst/arch/mipsco/md.c
@@ -67,7 +67,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -88,21 +88,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -160,10 +160,10 @@ md_post_newfs(void)
 		return 0;
 	}
 
-	printf(msg_string(MSG_dobootblks), diskdev);
+	printf(msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot", "/boot");
 	if (run_program(RUN_DISPLAY | RUN_NO_CLEAR,
-	    "/usr/mdec/installboot /dev/r%sc /usr/mdec/bootxx_ffs", diskdev))
+	    "/usr/mdec/installboot /dev/r%sc /usr/mdec/bootxx_ffs", pm->diskdev))
 		process_menu(MENU_ok,
 			deconst("Warning: disk is probably not bootable"));
 	return 0;
diff --git a/distrib/utils/sysinst/arch/mvme68k/md.c b/distrib/utils/sysinst/arch/mvme68k/md.c
index 77064f6..4d774ca 100644
--- a/distrib/utils/sysinst/arch/mvme68k/md.c
+++ b/distrib/utils/sysinst/arch/mvme68k/md.c
@@ -66,7 +66,7 @@ md_get_info(void)
 	char dev_name[100];
 	struct disklabel disklabel;
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -92,12 +92,12 @@ md_get_info(void)
 		exit(1);
 	}
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
-	dlsize = dlcyl*dlhead*dlsec;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
 
 	if (read(fd, buf, 1024) < 0) {
 		endwin();
@@ -107,7 +107,7 @@ md_get_info(void)
 	}
 
 	/* preserve first cylinder for system. */
-	ptstart = disklabel.d_secpercyl;
+	pm->ptstart = disklabel.d_secpercyl;
 
 	close(fd);
 
@@ -137,22 +137,22 @@ md_check_partitions(void)
 	for (part = PART_A; part < 8; part++) {
 		if (part == PART_C)
 			continue;
-		if (last >= PART_A && bsdlabel[part].pi_size > 0) {
+		if (last >= PART_A && pm->bsdlabel[part].pi_size > 0) {
 			msg_display(MSG_emptypart, part+'a');
 			process_menu(MENU_ok, NULL);
 			return 0;
 		}
-		if (bsdlabel[part].pi_size == 0) {
+		if (pm->bsdlabel[part].pi_size == 0) {
 			if (last < PART_A)
 				last = part;
 		} else {
-			if (start > bsdlabel[part].pi_offset) {
+			if (start > pm->bsdlabel[part].pi_offset) {
 				msg_display(MSG_ordering, part+'a');
 				process_menu(MENU_yesno, NULL);
 				if (yesno)
 					return 0;
 			}
-			start = bsdlabel[part].pi_offset;
+			start = pm->bsdlabel[part].pi_offset;
 		}
 	}
 
@@ -175,7 +175,7 @@ int
 md_post_disklabel(void)
 {
 	if (get_ramsize() < 6)
-		set_swap(diskdev, bsdlabel);
+		set_swap(pm->diskdev, pm->bsdlabel);
 
 	return 0;
 }
@@ -192,11 +192,11 @@ md_post_newfs(void)
 {
 
 	/* boot blocks ... */
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	cp_to_target("/usr/mdec/bootsd", "/.bootsd");
 	if (run_program(RUN_DISPLAY | RUN_NO_CLEAR,
 	    "/usr/mdec/installboot %s /usr/mdec/bootxx /dev/r%sa",
-	    target_expand("/.bootsd"), diskdev))
+	    target_expand("/.bootsd"), pm->diskdev))
 		process_menu(MENU_ok,
 			deconst("Warning: disk is probably not bootable"));
 	return 0;
@@ -220,7 +220,7 @@ int
 md_pre_update(void)
 {
 	if (get_ramsize() < 6)
-		set_swap(diskdev, NULL);
+		set_swap(pm->diskdev, NULL);
 	return 1;
 }
 
diff --git a/distrib/utils/sysinst/arch/news68k/md.c b/distrib/utils/sysinst/arch/news68k/md.c
index 021c24d..385cfa7 100644
--- a/distrib/utils/sysinst/arch/news68k/md.c
+++ b/distrib/utils/sysinst/arch/news68k/md.c
@@ -68,7 +68,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", diskdev);
+	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -84,21 +84,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl * dlhead * dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -155,11 +155,11 @@ md_post_newfs(void)
 {
 	const char *bootfile = "/boot";
 
-	printf(msg_string(MSG_dobootblks), diskdev);
+	printf(msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot", bootfile);
 	sync();
 	run_program(RUN_DISPLAY, "/usr/sbin/installboot /dev/r%sc %s %s",
-	    diskdev, "/usr/mdec/bootxx", bootfile);
+	    pm->diskdev, "/usr/mdec/bootxx", bootfile);
 	return 0;
 }
 
diff --git a/distrib/utils/sysinst/arch/newsmips/md.c b/distrib/utils/sysinst/arch/newsmips/md.c
index 11e4163..a37c56b 100644
--- a/distrib/utils/sysinst/arch/newsmips/md.c
+++ b/distrib/utils/sysinst/arch/newsmips/md.c
@@ -67,7 +67,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf (dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf (dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open (dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -83,21 +83,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -150,11 +150,11 @@ md_post_newfs()
 {
 	const char *bootfile = "/boot";
 
-	printf (msg_string(MSG_dobootblks), diskdev);
+	printf (msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot", bootfile);
 	sync();
 	run_program(RUN_DISPLAY, "/usr/sbin/installboot /dev/r%sc %s %s",
-	    diskdev, "/usr/mdec/bootxx", bootfile);
+	    pm->diskdev, "/usr/mdec/bootxx", bootfile);
 	return 0;
 }
 
diff --git a/distrib/utils/sysinst/arch/ofppc/md.c b/distrib/utils/sysinst/arch/ofppc/md.c
index 0ff9339..7d6d7aea 100644
--- a/distrib/utils/sysinst/arch/ofppc/md.c
+++ b/distrib/utils/sysinst/arch/ofppc/md.c
@@ -105,24 +105,24 @@ md_make_bsd_partitions(void)
 		 * So just use what we have got.
 		 */
 		for (part = 0; part < maxpart; part++) {
-			if (PI_ISBSDFS(&bsdlabel[part])) {
-				bsdlabel[part].pi_flags |=
+			if (PI_ISBSDFS(&pm->bsdlabel[part])) {
+				pm->bsdlabel[part].pi_flags |=
 				    PIF_NEWFS | PIF_MOUNT;
 
 				if (part == PART_A)
-					strcpy(bsdlabel[part].pi_mount, "/");
+					strcpy(pm->bsdlabel[part].pi_mount, "/");
 			}
 		}
 
 		part_bsd = part_raw = getrawpartition();
 		if (part_raw == -1)
 			part_raw = PART_C;	/* for sanity... */
-		bsdlabel[part_raw].pi_offset = 0;
-		bsdlabel[part_raw].pi_size = dlsize;
+		pm->bsdlabel[part_raw].pi_offset = 0;
+		pm->bsdlabel[part_raw].pi_size = pm->dlsize;
 
 		set_sizemultname_meg();
 rdb_edit_check:
-		if (edit_and_check_label(bsdlabel, maxpart, part_raw,
+		if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw,
 		    part_bsd) == 0) {
 			msg_display(MSG_abort);
 			return 0;
@@ -137,72 +137,72 @@ rdb_edit_check:
 	 * Initialize global variables that track space used on this disk.
 	 * Standard 4.4BSD 8-partition labels always cover whole disk.
 	 */
-	if (ptsize == 0)
-		ptsize = dlsize - ptstart;
-	if (dlsize == 0)
-		dlsize = ptstart + ptsize;
+	if (pm->ptsize == 0)
+		pm->ptsize = pm->dlsize - pm->ptstart;
+	if (pm->dlsize == 0)
+		pm->dlsize = pm->ptstart + pm->ptsize;
 
-	partstart = ptstart;
-	ptend = ptstart + ptsize;
+	partstart = pm->ptstart;
+	ptend = pm->ptstart + pm->ptsize;
 
 	/* Ask for layout type -- standard or special */
 	msg_display(MSG_layout,
-		    ptsize / (MEG / sectorsize),
+		    pm->ptsize / (MEG / pm->sectorsize),
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);
 
 	process_menu(MENU_layout, NULL);
 
 	/* Set so we use the 'real' geometry for rounding, input in MB */
-	current_cylsize = dlcylsize;
+	pm->current_cylsize = pm->dlcylsize;
 	set_sizemultname_meg();
 
 	/* Build standard partitions */
-	memset(&bsdlabel, 0, sizeof bsdlabel);
+	memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
 
 	/* Set initial partition types to unused */
 	for (part = 0 ; part < maxpart ; ++part)
-		bsdlabel[part].pi_fstype = FS_UNUSED;
+		pm->bsdlabel[part].pi_fstype = FS_UNUSED;
 
 	/* Whole disk partition */
 	part_raw = getrawpartition();
 	if (part_raw == -1)
 		part_raw = PART_C;	/* for sanity... */
-	bsdlabel[part_raw].pi_offset = 0;
-	bsdlabel[part_raw].pi_size = dlsize;
+	pm->bsdlabel[part_raw].pi_offset = 0;
+	pm->bsdlabel[part_raw].pi_size = pm->dlsize;
 
 	if (part_raw == PART_D) {
 		/* Probably a system that expects an i386 style mbr */
 		part_bsd = PART_C;
-		bsdlabel[PART_C].pi_offset = ptstart;
-		bsdlabel[PART_C].pi_size = ptsize;
+		pm->bsdlabel[PART_C].pi_offset = pm->ptstart;
+		pm->bsdlabel[PART_C].pi_size = pm->ptsize;
 	} else {
 		part_bsd = part_raw;
 	}
 
-	if (bootsize != 0) {
-		bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
-		bsdlabel[PART_BOOT_FAT12].pi_size = bootsize;
-		bsdlabel[PART_BOOT_FAT12].pi_offset = bootstart;
-		bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
-		strlcpy(bsdlabel[PART_BOOT_FAT12].pi_mount,
+	if (pm->bootsize != 0) {
+		pm->bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
+		pm->bsdlabel[PART_BOOT_FAT12].pi_size = pm->bootsize;
+		pm->bsdlabel[PART_BOOT_FAT12].pi_offset = pm->bootstart;
+		pm->bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
+		strlcpy(pm->bsdlabel[PART_BOOT_FAT12].pi_mount,
 		    PART_BOOT_FAT12_PI_MOUNT,
-		    sizeof bsdlabel[PART_BOOT_FAT12].pi_mount);
+		    sizeof pm->bsdlabel[PART_BOOT_FAT12].pi_mount);
 	}
 	if (binfosize != 0) {
-		bsdlabel[PART_BOOT_BINFO].pi_fstype = FS_OTHER;
-		bsdlabel[PART_BOOT_BINFO].pi_size = binfosize;
-		bsdlabel[PART_BOOT_BINFO].pi_offset = binfostart;
+		pm->bsdlabel[PART_BOOT_BINFO].pi_fstype = FS_OTHER;
+		pm->bsdlabel[PART_BOOT_BINFO].pi_size = binfosize;
+		pm->bsdlabel[PART_BOOT_BINFO].pi_offset = binfostart;
 	}
 	if (bprepsize != 0) {
-		bsdlabel[PART_BOOT_PREP].pi_fstype = FS_BOOT;
-		bsdlabel[PART_BOOT_PREP].pi_size = bprepsize;
-		bsdlabel[PART_BOOT_PREP].pi_offset = bprepstart;
+		pm->bsdlabel[PART_BOOT_PREP].pi_fstype = FS_BOOT;
+		pm->bsdlabel[PART_BOOT_PREP].pi_size = bprepsize;
+		pm->bsdlabel[PART_BOOT_PREP].pi_offset = bprepstart;
 	}
 
 #ifdef PART_REST
-	bsdlabel[PART_REST].pi_offset = 0;
-	bsdlabel[PART_REST].pi_size = ptstart;
+	pm->bsdlabel[PART_REST].pi_offset = 0;
+	pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
 #endif
 
 	/*
@@ -212,27 +212,27 @@ rdb_edit_check:
 	 * partitions on a multiboot i386 system.
 	 */
 	 for (i = maxpart; i--;) {
-		if (bsdlabel[i].pi_size != 0)
+		if (pm->bsdlabel[i].pi_size != 0)
 			/* Don't overwrite special partitions */
 			continue;
-		p = &oldlabel[i];
+		p = &pm->oldlabel[i];
 		if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
 			continue;
-		if (layoutkind == 4) {
+		if (layoutkind == LY_USEEXIST) {
 			if (PI_ISBSDFS(p))
 				p->pi_flags |= PIF_MOUNT;
 		} else {
-			if (p->pi_offset < ptstart + ptsize &&
-			    p->pi_offset + p->pi_size > ptstart)
+			if (p->pi_offset < pm->ptstart + pm->ptsize &&
+			    p->pi_offset + p->pi_size > pm->ptstart)
 				/* Not outside area we are allocating */
 				continue;
 			if (p->pi_fstype == FS_SWAP)
 				no_swap = 1;
 		}
-		bsdlabel[i] = oldlabel[i];
+		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/* XXX Check we have a sensible layout */
 		;
 	} else
@@ -243,7 +243,7 @@ rdb_edit_check:
 	 * edit it and verify it's OK, or abort altogether.
 	 */
  edit_check:
-	if (edit_and_check_label(bsdlabel, maxpart, part_raw, part_bsd) == 0) {
+	if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
 		msg_display(MSG_abort);
 		return 0;
 	}
@@ -251,10 +251,10 @@ rdb_edit_check:
 		goto edit_check;
 
 	/* Disk name */
-	msg_prompt(MSG_packname, bsddiskname, bsddiskname, sizeof bsddiskname);
+	msg_prompt(MSG_packname, pm->bsddiskname, pm->bsddiskname, sizeof pm->bsddiskname);
 
 	/* save label to disk for MI code to update. */
-	(void) savenewlabel(bsdlabel, maxpart);
+	(void) savenewlabel(pm->bsdlabel, maxpart);
 
 	/* Everything looks OK. */
 	return 1;
@@ -277,13 +277,13 @@ md_check_partitions(void)
 	 * from the MBR partition.
 	 */
 	for (part = PART_A; part < MAXPARTITIONS; part++) {
-		if (bsdlabel[part].pi_fstype == FS_MSDOS) {
+		if (pm->bsdlabel[part].pi_fstype == FS_MSDOS) {
 			bootpart_fat12 = part;
 			ffat++;
-		} else if (bsdlabel[part].pi_fstype == FS_BOOT) {
+		} else if (pm->bsdlabel[part].pi_fstype == FS_BOOT) {
 			bootpart_prep = part;
 			fprep++;
-		} else if (bsdlabel[part].pi_fstype == FS_OTHER) {
+		} else if (pm->bsdlabel[part].pi_fstype == FS_OTHER) {
 			bootpart_binfo = part;
 			fprep++;
 		}
@@ -314,7 +314,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -330,10 +330,10 @@ md_post_disklabel(void)
 {
 	char bootdev[100];
 
-	if (bootstart == 0 || bootsize == 0 || rdb_found)
+	if (pm->bootstart == 0 || pm->bootsize == 0 || rdb_found)
 		return 0;
 
-	snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", diskdev,
+	snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", pm->diskdev,
 	    'a'+bootpart_fat12);
 	run_program(RUN_DISPLAY, "/sbin/newfs_msdos %s", bootdev);
 
@@ -380,18 +380,18 @@ md_post_extract(void)
 	}
 
 	if (!noprepfix) {
-		snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", diskdev,
+		snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", pm->diskdev,
 		    'a'+bootpart_prep);
-		snprintf(bootbdev, sizeof bootbdev, "/dev/%s%c", diskdev,
+		snprintf(bootbdev, sizeof bootbdev, "/dev/%s%c", pm->diskdev,
 		    'a'+bootpart_prep);
 		run_program(RUN_DISPLAY, "/bin/dd if=/dev/zero of=%s bs=512",
 		    bootdev);
 		run_program(RUN_DISPLAY, "/bin/dd if=/usr/mdec/ofwboot "
 		    "of=%s bs=512", bootbdev);
 
-		snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", diskdev,
+		snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", pm->diskdev,
 		    'a'+bootpart_binfo);
-		snprintf(bootbdev, sizeof bootbdev, "/dev/%s%c", diskdev,
+		snprintf(bootbdev, sizeof bootbdev, "/dev/%s%c", pm->diskdev,
 		    'a'+bootpart_binfo);
 		run_program(RUN_DISPLAY, "/bin/dd if=/dev/zero of=%s bs=512",
 		    bootdev);
@@ -421,7 +421,7 @@ md_pre_update(void)
 	if (check_rdb())
 		return 1;
 
-	read_mbr(diskdev, &mbr);
+	read_mbr(pm->diskdev, &mbr);
 	/* do a sanity check of the partition table */
 	for (ext = &mbr; ext; ext = ext->extended) {
 		part = ext->mbr.mbr_parts;
@@ -474,8 +474,8 @@ md_check_mbr(mbr_info_t *mbri)
 		part = ext->mbr.mbr_parts;
 		for (i = 0; i < MBR_PART_COUNT; part++, i++) {
 			if (part->mbrp_type == MBR_PTYPE_FAT12) {
-				bootstart = part->mbrp_start;
-				bootsize = part->mbrp_size;
+				pm->bootstart = part->mbrp_start;
+				pm->bootsize = part->mbrp_size;
 			} else if (part->mbrp_type == MBR_PTYPE_PREP &&
 			    part->mbrp_size < 50) {
 				/* this is the bootinfo partition */
@@ -493,7 +493,7 @@ md_check_mbr(mbr_info_t *mbri)
 
 	/* we need to either have a pair of prep partitions, or a single
 	 * fat.  if neither, things are broken. */
-	if (!(bootsize >= (MIN_FAT12_BOOT/512) ||
+	if (!(pm->bootsize >= (MIN_FAT12_BOOT/512) ||
 		(binfosize >= (MIN_BINFO_BOOT/512) &&
 		    bprepsize >= (MIN_PREP_BOOT/512)))) {
 		msg_display(MSG_bootnotright);
@@ -517,7 +517,7 @@ md_check_mbr(mbr_info_t *mbri)
 	}
 
 	/* check the fat12 parititons */
-	if (bootsize > 0 && bootsize < (MIN_FAT12_BOOT/512)) {
+	if (pm->bootsize > 0 && pm->bootsize < (MIN_FAT12_BOOT/512)) {
 		msg_display(MSG_boottoosmall);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -527,7 +527,7 @@ md_check_mbr(mbr_info_t *mbri)
 	}
 
 	/* if both sets contain zero, thats bad */
-	if ((bootstart == 0 || bootsize == 0) &&
+	if ((pm->bootstart == 0 || pm->bootsize == 0) &&
 	    (binfosize == 0 || binfostart == 0 ||
 		bprepsize == 0 || bprepstart == 0)) {
 		msg_display(MSG_nobootpart);
@@ -571,7 +571,7 @@ md_mbr_use_wholedisk(mbr_info_t *mbri)
 	part[0].mbrp_flag = 0;
 
 	part[1].mbrp_type = MBR_PTYPE_NETBSD;
-	part[1].mbrp_size = dlsize - (bsec + FAT12_BOOT_SIZE/512 +
+	part[1].mbrp_size = pm->dlsize - (bsec + FAT12_BOOT_SIZE/512 +
 	    BINFO_BOOT_SIZE/512 + PREP_BOOT_SIZE/512);
 	part[1].mbrp_start = bsec + FAT12_BOOT_SIZE/512 + BINFO_BOOT_SIZE/512 +
 	    PREP_BOOT_SIZE/512;
@@ -587,10 +587,10 @@ md_mbr_use_wholedisk(mbr_info_t *mbri)
 	part[3].mbrp_start = bsec + FAT12_BOOT_SIZE/512 + BINFO_BOOT_SIZE/512;
 	part[3].mbrp_flag = 0;
 
-	ptstart = part[1].mbrp_start;
-	ptsize = part[1].mbrp_size;
-	bootstart = part[0].mbrp_start;
-	bootsize = part[0].mbrp_size;
+	pm->ptstart = part[1].mbrp_start;
+	pm->ptsize = part[1].mbrp_size;
+	pm->bootstart = part[0].mbrp_start;
+	pm->bootsize = part[0].mbrp_size;
 	binfostart = part[2].mbrp_start;
 	binfosize= part[2].mbrp_size;
 	bprepstart = part[3].mbrp_start;
@@ -620,7 +620,7 @@ check_rdb(void)
 
 	/* Find out if this disk has a valid RDB, before continuing. */
 	rdb = (struct rdblock *)buf;
-	fd = opendisk(diskdev, O_RDONLY, diskpath, sizeof(diskpath), 0);
+	fd = opendisk(pm->diskdev, O_RDONLY, diskpath, sizeof(diskpath), 0);
 	if (fd < 0)
 		return 0;
 	for (blk = 0; blk < RDB_MAXBLOCKS; blk++) {
diff --git a/distrib/utils/sysinst/arch/pmax/md.c b/distrib/utils/sysinst/arch/pmax/md.c
index e8bd354..a0033a2 100644
--- a/distrib/utils/sysinst/arch/pmax/md.c
+++ b/distrib/utils/sysinst/arch/pmax/md.c
@@ -66,7 +66,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -87,21 +87,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -161,12 +161,12 @@ md_post_newfs(void)
 		return 0;
 	}
 
-	printf(msg_string(MSG_dobootblks), diskdev);
+	printf(msg_string(MSG_dobootblks), pm->diskdev);
 	cp_to_target("/usr/mdec/boot.pmax", "/boot.pmax");
 	bootxx = bootxx_name();
 	if (bootxx != NULL) {
 		error = run_program(RUN_DISPLAY | RUN_NO_CLEAR,
-		    "/usr/sbin/installboot /dev/r%sc %s", diskdev, bootxx);
+		    "/usr/sbin/installboot /dev/r%sc %s", pm->diskdev, bootxx);
 		free(bootxx);
 	} else
 		error = -1;
diff --git a/distrib/utils/sysinst/arch/prep/md.c b/distrib/utils/sysinst/arch/prep/md.c
index 36fd490..0d36771 100644
--- a/distrib/utils/sysinst/arch/prep/md.c
+++ b/distrib/utils/sysinst/arch/prep/md.c
@@ -87,7 +87,7 @@ md_check_partitions(void)
 	 * something stupid, like move it away from the MBR partition.
 	 */
 	for (part = PART_A; part < MAXPARTITIONS; part++)
-		if (bsdlabel[part].pi_fstype == FS_BOOT) {
+		if (pm->bsdlabel[part].pi_fstype == FS_BOOT) {
 			prep_bootpart = part;
 			return 1;
 		}
@@ -106,7 +106,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -149,8 +149,8 @@ md_post_extract(void)
 	else
 		snprintf(bootloader, 100, "/usr/mdec/boot");
 
-	snprintf(rawdev, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
-	snprintf(bootpart, 100, "/dev/r%s%c", diskdev, 'a' + prep_bootpart);
+	snprintf(rawdev, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
+	snprintf(bootpart, 100, "/dev/r%s%c", pm->diskdev, 'a' + prep_bootpart);
 	if (prep_rawdevfix)
 		run_program(RUN_DISPLAY|RUN_CHROOT,
 		    "/usr/mdec/mkbootimage -b %s -k /netbsd "
@@ -181,7 +181,7 @@ md_pre_update(void)
 	mbr_info_t *ext;
 	int i;
 
-	read_mbr(diskdev, &mbr);
+	read_mbr(pm->diskdev, &mbr);
 	/* do a sanity check of the partition table */
 	for (ext = &mbr; ext; ext = ext->extended) {
 		part = ext->mbr.mbr_parts;
@@ -225,12 +225,12 @@ md_check_mbr(mbr_info_t *mbri)
 		for (i = 0; i < MBR_PART_COUNT; part++, i++) {
 			if (part->mbrp_type != MBR_PTYPE_PREP)
 				continue;
-			bootstart = part->mbrp_start;
-			bootsize = part->mbrp_size;
+			pm->bootstart = part->mbrp_start;
+			pm->bootsize = part->mbrp_size;
 			break;
 		}
 	}
-	if (bootsize < (MIN_PREP_BOOT/512)) {
+	if (pm->bootsize < (MIN_PREP_BOOT/512)) {
 		msg_display(MSG_preptoosmall);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -238,7 +238,7 @@ md_check_mbr(mbr_info_t *mbri)
 			return 0;
 		return 1;
 	}
-	if (bootstart == 0 || bootsize == 0) {
+	if (pm->bootstart == 0 || pm->bootsize == 0) {
 		msg_display(MSG_nopreppart);
 		msg_display_add(MSG_reeditpart, 0);
 		process_menu(MENU_yesno, NULL);
@@ -272,14 +272,14 @@ md_mbr_use_wholedisk(mbr_info_t *mbri)
 	part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
 
 	part[1].mbrp_type = MBR_PTYPE_NETBSD;
-	part[1].mbrp_size = dlsize - (bsec + PREP_BOOT_SIZE/512);
+	part[1].mbrp_size = pm->dlsize - (bsec + PREP_BOOT_SIZE/512);
 	part[1].mbrp_start = bsec + PREP_BOOT_SIZE/512;
 	part[1].mbrp_flag = 0;
 
-	ptstart = part[1].mbrp_start;
-	ptsize = part[1].mbrp_size;
-	bootstart = part[0].mbrp_start;
-	bootsize = part[0].mbrp_size;
+	pm->ptstart = part[1].mbrp_start;
+	pm->ptsize = part[1].mbrp_size;
+	pm->bootstart = part[0].mbrp_start;
+	pm->bootsize = part[0].mbrp_size;
 	return 1;
 }
 
diff --git a/distrib/utils/sysinst/arch/sandpoint/md.c b/distrib/utils/sysinst/arch/sandpoint/md.c
index 5872e39..76a9156 100644
--- a/distrib/utils/sysinst/arch/sandpoint/md.c
+++ b/distrib/utils/sysinst/arch/sandpoint/md.c
@@ -122,7 +122,7 @@ md_pre_disklabel(void)
 	printf ("%s", msg_string (MSG_dofdisk));
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -137,10 +137,10 @@ int
 md_post_disklabel(void)
 {
 	/* Sector forwarding / badblocks ... */
-	if (*doessf) {
+	if (*pm->doessf) {
 		printf ("%s", msg_string (MSG_dobad144));
 		return run_program(RUN_DISPLAY, "/usr/sbin/bad144 %s 0",
-		    diskdev);
+		    pm->diskdev);
 	}
 	return 0;
 }
diff --git a/distrib/utils/sysinst/arch/sgimips/md.c b/distrib/utils/sysinst/arch/sgimips/md.c
index bece141..d13f78e 100644
--- a/distrib/utils/sysinst/arch/sgimips/md.c
+++ b/distrib/utils/sysinst/arch/sgimips/md.c
@@ -83,7 +83,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
+	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -104,21 +104,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -156,19 +156,19 @@ md_pre_disklabel(void)
 int
 md_post_disklabel(void)
 {
-	set_swap(diskdev, bsdlabel);
-        if (strstr(instsys.version, "(INSTALL32_IP3x)"))
+	set_swap(pm->diskdev, pm->bsdlabel);
+    if (strstr(instsys.version, "(INSTALL32_IP3x)"))
 		return run_program(RUN_DISPLAY,
 		    "%s %s", "/usr/mdec/sgivol -f -w boot /usr/mdec/ip3xboot",
-		    diskdev);
+		    pm->diskdev);
 
 	if (strstr(instsys.version, "(INSTALL32_IP2x)")) {
 		run_program(RUN_DISPLAY,
 		  "%s %s", "/usr/mdec/sgivol -f -w aoutboot /usr/mdec/aoutboot",
-		  diskdev);
+		  pm->diskdev);
 		return run_program(RUN_DISPLAY,
 		  "%s %s", "/usr/mdec/sgivol -f -w boot /usr/mdec/ip2xboot",
-		  diskdev);
+		  pm->diskdev);
 	}
 
 	/* Presumably an IP12, we add the boot code later... */
@@ -201,7 +201,7 @@ md_cleanup_install(void)
 
 	if (strstr(instsys.version, "(GENERIC32_IP12)"))
 		run_program(0, "/usr/mdec/sgivol -f -w netbsd %s %s",
-			    target_expand("/netbsd.ecoff"), diskdev);
+			    target_expand("/netbsd.ecoff"), pm->diskdev);
 }
 
 int
diff --git a/distrib/utils/sysinst/arch/shark/md.c b/distrib/utils/sysinst/arch/shark/md.c
index 070336a..ae41583 100644
--- a/distrib/utils/sysinst/arch/shark/md.c
+++ b/distrib/utils/sysinst/arch/shark/md.c
@@ -69,12 +69,12 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	if (strncmp(diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+	if (strncmp(pm->diskdev, "wd", 2) == 0)
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -90,21 +90,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -135,7 +135,7 @@ md_pre_disklabel(void)
 {
 	char diskpath[MAXPATHLEN];
 
-	if (clear_mbr(diskdev, diskpath, sizeof(diskpath)) == -1) {
+	if (clear_mbr(pm->diskdev, diskpath, sizeof(diskpath)) == -1) {
 		msg_display(MSG_badclearmbr, diskpath);
 		process_menu(MENU_ok, NULL);
 	}
diff --git a/distrib/utils/sysinst/arch/sparc/md.c b/distrib/utils/sysinst/arch/sparc/md.c
index 6934ed6..01b1270 100644
--- a/distrib/utils/sysinst/arch/sparc/md.c
+++ b/distrib/utils/sysinst/arch/sparc/md.c
@@ -72,7 +72,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
+	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -93,21 +93,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -160,8 +160,8 @@ md_post_newfs(void)
 {
 
 	/* boot blocks ... */
-	msg_display(MSG_dobootblks, diskdev);
-	return (run_program(RUN_DISPLAY, "/sbin/disklabel -W %s", diskdev) ||
+	msg_display(MSG_dobootblks, pm->diskdev);
+	return (run_program(RUN_DISPLAY, "/sbin/disklabel -W %s", pm->diskdev) ||
 	    run_program(RUN_DISPLAY, "/usr/mdec/binstall ffs %s",
 		targetroot_mnt));
 }
diff --git a/distrib/utils/sysinst/arch/sparc64/md.c b/distrib/utils/sysinst/arch/sparc64/md.c
index f4ab543..03be22d 100644
--- a/distrib/utils/sysinst/arch/sparc64/md.c
+++ b/distrib/utils/sysinst/arch/sparc64/md.c
@@ -73,7 +73,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -94,21 +94,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -195,10 +195,10 @@ static void
 install_bootblocks(void)
 {
 	/* Install boot blocks before mounting the target disk */
-	msg_display(MSG_dobootblks, diskdev);
-	run_program(RUN_DISPLAY, "/sbin/disklabel -W %s", diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
+	run_program(RUN_DISPLAY, "/sbin/disklabel -W %s", pm->diskdev);
 	run_program(RUN_DISPLAY, "/usr/sbin/installboot /dev/r%sc"
-	    " /usr/mdec/bootblk", diskdev);
+	    " /usr/mdec/bootblk", pm->diskdev);
 }
 
 /* install/update secondary bootstrap */
diff --git a/distrib/utils/sysinst/arch/vax/md.c b/distrib/utils/sysinst/arch/vax/md.c
index cb71b83..4f026e3 100644
--- a/distrib/utils/sysinst/arch/vax/md.c
+++ b/distrib/utils/sysinst/arch/vax/md.c
@@ -70,7 +70,7 @@ md_get_info(void)
 	int fd;
 	char dev_name[100];
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -91,21 +91,21 @@ md_get_info(void)
 	}
 	close(fd);
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
 
 	/*
-	 * Compute whole disk size. Take max of (dlcyl*dlhead*dlsec)
+	 * Compute whole disk size. Take max of (pm->dlcyl*pm->dlhead*pm->dlsec)
 	 * and secperunit,  just in case the disk is already labelled.
 	 * (If our new label's RAW_PART size ends up smaller than the
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
-	dlsize = dlcyl*dlhead*dlsec;
-	if (disklabel.d_secperunit > dlsize)
-		dlsize = disklabel.d_secperunit;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
@@ -156,9 +156,9 @@ md_post_disklabel(void)
 int
 md_post_newfs(void)
 {
-	printf(msg_string(MSG_dobootblks), diskdev);
+	printf(msg_string(MSG_dobootblks), pm->diskdev);
 	run_program(0, "/usr/sbin/installboot /dev/r%s%c /usr/mdec/%.2sboot",
-	    diskdev, 'a' + getrawpartition(), diskdev);
+	    pm->diskdev, 'a' + getrawpartition(), pm->diskdev);
 	return 0;
 }
 
diff --git a/distrib/utils/sysinst/arch/x68k/md.c b/distrib/utils/sysinst/arch/x68k/md.c
index 1da75ef..762036c 100644
--- a/distrib/utils/sysinst/arch/x68k/md.c
+++ b/distrib/utils/sysinst/arch/x68k/md.c
@@ -83,7 +83,7 @@ md_get_info(void)
 	char dev_name[100];
 	struct disklabel disklabel;
 
-	snprintf(dev_name, 100, "/dev/r%sc", diskdev);
+	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
 	fd = open(dev_name, O_RDONLY, 0);
 	if (fd < 0) {
@@ -109,12 +109,12 @@ md_get_info(void)
 		exit(1);
 	}
 
-	dlcyl = disklabel.d_ncylinders;
-	dlhead = disklabel.d_ntracks;
-	dlsec = disklabel.d_nsectors;
-	sectorsize = disklabel.d_secsize;
-	dlcylsize = disklabel.d_secpercyl;
-	dlsize = dlcyl*dlhead*dlsec;
+	pm->dlcyl = disklabel.d_ncylinders;
+	pm->dlhead = disklabel.d_ntracks;
+	pm->dlsec = disklabel.d_nsectors;
+	pm->sectorsize = disklabel.d_secsize;
+	pm->dlcylsize = disklabel.d_secpercyl;
+	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
 
 	if (read(fd, buf, 1024) < 0) {
 		endwin();
@@ -134,7 +134,7 @@ md_get_info(void)
 		}
 #endif
 	/* preserve first 64 sectors for system. */
-	ptstart = 64;
+	pm->ptstart = 64;
 
 	/* preserve existing partitions? */
 
@@ -165,22 +165,22 @@ md_check_partitions(void)
 	for (part = PART_A; part < 8; part++) {
 		if (part == PART_C)
 			continue;
-		if (last >= PART_A && bsdlabel[part].pi_size > 0) {
+		if (last >= PART_A && pm->bsdlabel[part].pi_size > 0) {
 			msg_display(MSG_emptypart, part+'a');
 			process_menu(MENU_ok, NULL);
 			return 0;
 		}
-		if (bsdlabel[part].pi_size == 0) {
+		if (pm->bsdlabel[part].pi_size == 0) {
 			if (last < PART_A)
 				last = part;
 		} else {
-			if (start >= bsdlabel[part].pi_offset) {
+			if (start >= pm->bsdlabel[part].pi_offset) {
 				msg_display(MSG_ordering, part+'a');
 				process_menu(MENU_yesno, NULL);
 				if (yesno)
 					return 0;
 			}
-			start = bsdlabel[part].pi_offset;
+			start = pm->bsdlabel[part].pi_offset;
 		}
 	}
 
@@ -205,10 +205,10 @@ md_check_partitions(void)
 			break;
 		}
 	}
-	emptylabel(bsdlabel);
-	bsdlabel[C].pi_fstype = FS_UNUSED;
-	bsdlabel[C].pi_offset = 0;
-	bsdlabel[C].pi_size = dlsize;
+	emptylabel(pm->bsdlabel);
+	pm->bsdlabel[C].pi_fstype = FS_UNUSED;
+	pm->bsdlabel[C].pi_offset = 0;
+	pm->bsdlabel[C].pi_size = pm->dlsize;
 	for (i = 0, j = A; i < NDOSPART;) {
 		if (j == C) {
 			j++;
@@ -221,22 +221,22 @@ md_check_partitions(void)
 			i++;
 			continue;
 		}
-		bsdlabel[j].pi_fstype = (i == 1) ? FS_SWAP : FS_BSDFFS;
-		bsdlabel[j].pi_offset = md_disklabel.dosparts[i].dp_start*2;
-		bsdlabel[j].pi_size = md_disklabel.dosparts[i].dp_size*2;
+		pm->bsdlabel[j].pi_fstype = (i == 1) ? FS_SWAP : FS_BSDFFS;
+		pm->bsdlabel[j].pi_offset = md_disklabel.dosparts[i].dp_start*2;
+		pm->bsdlabel[j].pi_size = md_disklabel.dosparts[i].dp_size*2;
 		i++;
 		j++;
 	}
 	if (j > 6) {
-		msg_display(MSG_nofreepart, diskdev);
+		msg_display(MSG_nofreepart, pm->diskdev);
 		return 0;
 	}
 	md_nfreepart = 8 - j;
 
 	/* check for free space */
-	fsptsize = bsdlabel[A].pi_offset - 64;
-	if (fptsize <= 0) {	/* XXX: should not be 0; minfsdb?  */
-		msg_display(MSG_notfirst, diskdev);
+	fspm->ptsize = pm->bsdlabel[A].pi_offset - 64;
+	if (fpm->ptsize <= 0) {	/* XXX: should not be 0; minfsdb?  */
+		msg_display(MSG_notfirst, pm->diskdev);
 		process_menu(MENU_ok);
 		exit(1);
 	}
@@ -263,7 +263,7 @@ int
 md_post_disklabel(void)
 {
 	if (get_ramsize() < 6)
-		set_swap(diskdev, bsdlabel);
+		set_swap(pm->diskdev, pm->bsdlabel);
 	return 0;
 }
 
@@ -278,11 +278,11 @@ int
 md_post_newfs(void)
 {
 	/* boot blocks ... */
-	msg_display(MSG_dobootblks, diskdev);
+	msg_display(MSG_dobootblks, pm->diskdev);
 	cp_to_target("/usr/mdec/boot", "/boot");
 	if (run_program(RUN_DISPLAY | RUN_NO_CLEAR,
 	    "/usr/mdec/installboot.new /usr/mdec/sdboot_ufs /dev/r%sa",
-	    diskdev))
+	    pm->diskdev))
 		process_menu(MENU_ok,
 			deconst("Warning: disk is probably not bootable"));
 	return 0;
@@ -306,7 +306,7 @@ int
 md_pre_update(void)
 {
 	if (get_ramsize() < 6)
-		set_swap(diskdev, NULL);
+		set_swap(pm->diskdev, NULL);
 	return 1;
 }
 
@@ -321,10 +321,10 @@ md_update(void)
 static int
 md_newdisk(void)
 {
-	msg_display(MSG_newdisk, diskdev, diskdev);
+	msg_display(MSG_newdisk, pm->diskdev, pm->diskdev);
 
 	return run_program(RUN_FATAL|RUN_DISPLAY,
-	    "/usr/mdec/newdisk -v %s", diskdev);
+	    "/usr/mdec/newdisk -v %s", pm->diskdev);
 }
 
 
diff --git a/distrib/utils/sysinst/arch/zaurus/md.c b/distrib/utils/sysinst/arch/zaurus/md.c
index fe2c043..5d49a61 100644
--- a/distrib/utils/sysinst/arch/zaurus/md.c
+++ b/distrib/utils/sysinst/arch/zaurus/md.c
@@ -100,7 +100,7 @@ md_pre_disklabel(void)
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
-	if (write_mbr(diskdev, &mbr, 1) != 0) {
+	if (write_mbr(pm->diskdev, &mbr, 1) != 0) {
 		msg_display(MSG_wmbrfail);
 		process_menu(MENU_ok, NULL);
 		return 1;
@@ -130,7 +130,7 @@ md_post_newfs(void)
 	ssize_t sz;
 	int fd = -1;
 
-	snprintf(adevname, sizeof(adevname), "/dev/r%sa", diskdev);
+	snprintf(adevname, sizeof(adevname), "/dev/r%sa", pm->diskdev);
 	fd = open(adevname, O_RDWR);
 	if (fd < 0)
 		goto out;
diff --git a/distrib/utils/sysinst/bsddisklabel.c b/distrib/utils/sysinst/bsddisklabel.c
index 6916792..888e1e6 100644
--- a/distrib/utils/sysinst/bsddisklabel.c
+++ b/distrib/utils/sysinst/bsddisklabel.c
@@ -52,8 +52,6 @@
 #include "msg_defs.h"
 #include "menu_defs.h"
 
-static int check_partitions(void);
-
 /* For the current state of this file blame abs@NetBSD.org */
 /* Even though he wasn't the last to hack it, but he did admit doing so :-) */
 
@@ -91,11 +89,12 @@ save_ptn(int ptn, daddr_t start, daddr_t size, int fstype, const char *mountpt)
 	static int maxptn;
 	partinfo *p;
 	int pp;
+	char *buf;
 
 	if (maxptn == 0)
 		maxptn = getmaxpartitions();
 
-	if (ptn < 0 || bsdlabel[ptn].pi_fstype != FS_UNUSED) {
+	if (ptn < 0 || pm->bsdlabel[ptn].pi_fstype != FS_UNUSED) {
 		ptn = getrawpartition() + 1;
 #ifdef PART_FIRST_FREE
 		if (ptn < PART_FIRST_FREE)
@@ -106,7 +105,7 @@ save_ptn(int ptn, daddr_t start, daddr_t size, int fstype, const char *mountpt)
 				return -1;
 			if (ptn == PART_USR)
 				continue;
-			if (bsdlabel[ptn].pi_fstype == FS_UNUSED)
+			if (pm->bsdlabel[ptn].pi_fstype == FS_UNUSED)
 				break;
 		}
 	}
@@ -114,17 +113,25 @@ save_ptn(int ptn, daddr_t start, daddr_t size, int fstype, const char *mountpt)
 	if (fstype == FS_UNUSED)
 		return ptn;
 
-	p = bsdlabel + ptn;
+	p = pm->bsdlabel + ptn;
 	p->pi_offset = start;
 	p->pi_size = size;
 	set_ptype(p, fstype, mountpt ? PIF_NEWFS : 0);
 
-	if (mountpt != NULL) {
+	/* Hack because we does not have something like FS_LVMPV */
+	p->lvmpv = 0;
+	if (mountpt != NULL && strcmp(mountpt, "lvm") == 0)
+		p->lvmpv = 1;
+	else if (mountpt != NULL) {
 		for (pp = 0; pp < maxptn; pp++) {
-			if (strcmp(bsdlabel[pp].pi_mount, mountpt) == 0)
-				bsdlabel[pp].pi_flags &= ~PIF_MOUNT;
+			if (strcmp(pm->bsdlabel[pp].pi_mount, mountpt) == 0)
+				pm->bsdlabel[pp].pi_flags &= ~PIF_MOUNT;
 		}
-		strlcpy(p->pi_mount, mountpt, sizeof p->pi_mount);
+		if (mountpt[0] != '/')
+			asprintf(&buf, "/%s", mountpt);
+		else
+			asprintf(&buf, "%s", mountpt);
+		strlcpy(p->pi_mount, buf, sizeof p->pi_mount);
 		p->pi_flags |= PIF_MOUNT;
 		/* Default to logging, UFS2. */
 		if (p->pi_fstype == FS_BSDFFS) {
@@ -136,6 +143,7 @@ save_ptn(int ptn, daddr_t start, daddr_t size, int fstype, const char *mountpt)
 				p->pi_flags |= PIF_FFSv2;
 #endif
 		}
+		free(buf);
 	}
 
 	return ptn;
@@ -146,7 +154,7 @@ set_ptn_titles(menudesc *m, int opt, void *arg)
 {
 	struct ptn_info *pi = arg;
 	struct ptn_size *p;
-	int sm = MEG / sectorsize;
+	int sm = MEG / pm->sectorsize;
 	daddr_t size;
 	char inc_free[12];
 
@@ -162,7 +170,7 @@ set_ptn_titles(menudesc *m, int opt, void *arg)
 	else
 		inc_free[0] = 0;
 	wprintw(m->mw, "%6" PRIi64 "%8s%10" PRIi64 "%10" PRIi64 " %c %s",
-		size / sm, inc_free, size / dlcylsize, size,
+		size / sm, inc_free, size / pm->dlcylsize, size,
 		p == pi->pool_part ? '+' : ' ', p->mount);
 }
 
@@ -218,8 +226,8 @@ set_ptn_size(menudesc *m, void *arg)
 		return 0;
 
 	if (p->mount[0] == 0) {
-		msg_prompt_win(MSG_askfsmount, -1, 18, 0, 0,
-			NULL, p->mount, sizeof p->mount);
+		msg_prompt_win(partman_go?MSG_askfsmountadv:MSG_askfsmount,
+			-1, 18, 0, 0, NULL, p->mount, sizeof p->mount);
 		if (p->mount[0] == 0)
 			return 0;
 	}
@@ -260,15 +268,15 @@ set_ptn_size(menudesc *m, void *arg)
 			mult = 1;
 			break;
 		case 'c':
-			mult = dlcylsize;
+			mult = pm->dlcylsize;
 			break;
 		case 'm':
 		case 'M':
-			mult = MEG / sectorsize;
+			mult = MEG / pm->sectorsize;
 			break;
 		case 'g':
 		case 'G':
-			mult = 1024 * MEG / sectorsize;
+			mult = 1024 * MEG / pm->sectorsize;
 			break;
 		case '+':
 			cp--;
@@ -285,7 +293,7 @@ set_ptn_size(menudesc *m, void *arg)
 			break;
 	}
 
-	size = NUMSEC(size, mult, dlcylsize);
+	size = NUMSEC(size, mult, pm->dlcylsize);
 	if (p->ptn_id == PART_TMP_RAMDISK) {
 		p->size = size;
 		return 0;
@@ -295,7 +303,7 @@ set_ptn_size(menudesc *m, void *arg)
 	if (*cp == '+' && p->limit == 0) {
 		pi->pool_part = p;
 		if (size == 0)
-			size = dlcylsize;
+			size = pm->dlcylsize;
 	}
 	if (p->limit != 0 && size > p->limit)
 		size = p->limit;
@@ -321,9 +329,9 @@ set_ptn_size(menudesc *m, void *arg)
 			 * but keep cylinder alignment
 			 */
 			if (f < 0)
-				f = -roundup(-f, dlcylsize);
+				f = -roundup(-f, pm->dlcylsize);
 			else
-				f = rounddown(f, dlcylsize);
+				f = rounddown(f, pm->dlcylsize);
 			size += f;
 			if (size != 0) {
 				pi->free_space -= f;
@@ -337,6 +345,7 @@ set_ptn_size(menudesc *m, void *arg)
 	return 0;
 }
 
+/* Menu to change sizes of /, /usr, /home and etc. partitions */
 void
 get_ptn_sizes(daddr_t part_start, daddr_t sectors, int no_swap)
 {
@@ -345,8 +354,10 @@ get_ptn_sizes(daddr_t part_start, daddr_t sectors, int no_swap)
 	int sm;				/* sectors in 1MB */
 	struct ptn_size *p;
 	daddr_t size;
+	static int swap_created = 0, root_created = 0;
 
-	static struct ptn_info pi = { -1, {
+	if (pm->pi.menu_no < 0)
+	pm->pi = (struct ptn_info) { -1, {
 #define PI_ROOT 0
 		{ PART_ROOT,	{ '/', '\0' },
 		  DEFROOTSIZE,	DEFROOTSIZE , 0, 0},
@@ -378,134 +389,139 @@ get_ptn_sizes(daddr_t part_start, daddr_t sectors, int no_swap)
 	msg_display(MSG_ptnsizes);
 	msg_table_add(MSG_ptnheaders);
 
-	if (pi.menu_no < 0) {
+	if (pm->pi.menu_no < 0) {
 		/* If there is a swap partition elsewhere, don't add one here.*/
-		if (no_swap) {
-			pi.ptn_sizes[PI_SWAP].size = 0;
+		if (no_swap || (swap_created && partman_go)) {
+			pm->pi.ptn_sizes[PI_SWAP].size = 0;
 		} else {
 #if DEFSWAPSIZE == -1
 			/* Dynamic swap size. */
-			pi.ptn_sizes[PI_SWAP].dflt_size = get_ramsize();
-			pi.ptn_sizes[PI_SWAP].size =
-			    pi.ptn_sizes[PI_SWAP].dflt_size;
+			pm->pi.ptn_sizes[PI_SWAP].dflt_size = get_ramsize();
+			pm->pi.ptn_sizes[PI_SWAP].size =
+			    pm->pi.ptn_sizes[PI_SWAP].dflt_size;
 #endif
 		}
 
 		/* If installing X increase default size of /usr */
 		if (set_X11_selected())
-			pi.ptn_sizes[PI_USR].dflt_size += XNEEDMB;
+			pm->pi.ptn_sizes[PI_USR].dflt_size += XNEEDMB;
 
 		/* Start of planning to give free space to / */
-		pi.pool_part = &pi.ptn_sizes[PI_ROOT];
+		pm->pi.pool_part = &pm->pi.ptn_sizes[PI_ROOT];
 		/* Make size of root include default size of /usr */
-		pi.ptn_sizes[PI_ROOT].size += pi.ptn_sizes[PI_USR].dflt_size;
+		pm->pi.ptn_sizes[PI_ROOT].size += pm->pi.ptn_sizes[PI_USR].dflt_size;
 
-		sm = MEG / sectorsize;
+		sm = MEG / pm->sectorsize;
 
 		if (root_limit != 0) {
 			/* Bah - bios can not read all the disk, limit root */
-			pi.ptn_sizes[PI_ROOT].limit = root_limit - part_start;
+			pm->pi.ptn_sizes[PI_ROOT].limit = root_limit - part_start;
 			/* Allocate a /usr partition if bios can't read
 			 * everything except swap.
 			 */
-			if (pi.ptn_sizes[PI_ROOT].limit
-			    < sectors - pi.ptn_sizes[PI_SWAP].size * sm) {
+			if (pm->pi.ptn_sizes[PI_ROOT].limit
+			    < sectors - pm->pi.ptn_sizes[PI_SWAP].size * sm) {
 				/* Root won't be able to access all the space */
 				/* Claw back space for /usr */
-				pi.ptn_sizes[PI_USR].size =
-						pi.ptn_sizes[PI_USR].dflt_size;
-				pi.ptn_sizes[PI_ROOT].size -=
-						pi.ptn_sizes[PI_USR].dflt_size;
-				pi.ptn_sizes[PI_ROOT].changed = 1;
+				pm->pi.ptn_sizes[PI_USR].size =
+						pm->pi.ptn_sizes[PI_USR].dflt_size;
+				pm->pi.ptn_sizes[PI_ROOT].size -=
+						pm->pi.ptn_sizes[PI_USR].dflt_size;
+				pm->pi.ptn_sizes[PI_ROOT].changed = 1;
 				/* Give free space to /usr */
-				pi.pool_part = &pi.ptn_sizes[PI_USR];
+				pm->pi.pool_part = &pm->pi.ptn_sizes[PI_USR];
 			}
 		}
 
 		/* Change preset sizes from MB to sectors */
-		pi.free_space = sectors;
-		for (p = pi.ptn_sizes; p->mount[0]; p++) {
-			p->size = NUMSEC(p->size, sm, dlcylsize);
-			p->dflt_size = NUMSEC(p->dflt_size, sm, dlcylsize);
-			pi.free_space -= p->size;
+		pm->pi.free_space = sectors;
+		for (p = pm->pi.ptn_sizes; p->mount[0]; p++) {
+			p->size = NUMSEC(p->size, sm, pm->dlcylsize);
+			p->dflt_size = NUMSEC(p->dflt_size, sm, pm->dlcylsize);
+			pm->pi.free_space -= p->size;
 		}
 
 		/* Steal space from swap to make things fit.. */
-		if (pi.free_space < 0) {
-			i = roundup(-pi.free_space, dlcylsize);
-			if (i > pi.ptn_sizes[PI_SWAP].size)
-				i = pi.ptn_sizes[PI_SWAP].size;
-			pi.ptn_sizes[PI_SWAP].size -= i;
-			pi.free_space += i;
+		if (pm->pi.free_space < 0) {
+			i = roundup(-pm->pi.free_space, pm->dlcylsize);
+			if (i > pm->pi.ptn_sizes[PI_SWAP].size)
+				i = pm->pi.ptn_sizes[PI_SWAP].size;
+			pm->pi.ptn_sizes[PI_SWAP].size -= i;
+			pm->pi.free_space += i;
 		}
 
 		/* Add space for 2 system dumps to / (traditional) */
 		i = get_ramsize() * sm;
-		i = roundup(i, dlcylsize);
-		if (pi.free_space > i * 2)
+		i = roundup(i, pm->dlcylsize);
+		if (pm->pi.free_space > i * 2)
 			i *= 2;
-		if (pi.free_space > i) {
-			pi.ptn_sizes[PI_ROOT].size += i;
-			pi.free_space -= i;
+		if (pm->pi.free_space > i) {
+			pm->pi.ptn_sizes[PI_ROOT].size += i;
+			pm->pi.free_space -= i;
+		}
+
+		if (root_created && partman_go) {
+			pm->pi.ptn_sizes[PI_ROOT].size = 0;
+			pm->pi.pool_part = 0;
 		}
 
 		/* Ensure all of / is readable by the system boot code */
-		i = pi.ptn_sizes[PI_ROOT].limit;
-		if (i != 0 && (i -= pi.ptn_sizes[PI_ROOT].size) < 0) {
-			pi.ptn_sizes[PI_ROOT].size += i;
-			pi.free_space -= i;
+		i = pm->pi.ptn_sizes[PI_ROOT].limit;
+		if (i != 0 && (i -= pm->pi.ptn_sizes[PI_ROOT].size) < 0) {
+			pm->pi.ptn_sizes[PI_ROOT].size += i;
+			pm->pi.free_space -= i;
 		}
 
 		/* Count free partition slots */
-		pi.free_parts = 0;
+		pm->pi.free_parts = 0;
 		for (i = 0; i < maxpart; i++) {
-			if (bsdlabel[i].pi_size == 0)
-				pi.free_parts++;
+			if (pm->bsdlabel[i].pi_size == 0)
+				pm->pi.free_parts++;
 		}
 		for (i = 0; i < MAXPARTITIONS; i++) {
-			p = &pi.ptn_sizes[i];
+			p = &pm->pi.ptn_sizes[i];
 			if (i != 0 && p->ptn_id == 0)
 				p->ptn_id = PART_EXTRA;
 			if (p->size != 0)
-				pi.free_parts--;
+				pm->pi.free_parts--;
 		}
 
-		pi.menu_no = new_menu(0, pi.ptn_menus, nelem(pi.ptn_menus),
+		pm->pi.menu_no = new_menu(0, pm->pi.ptn_menus, nelem(pm->pi.ptn_menus),
 			3, -1, 12, 70,
-			MC_NOSHORTCUT |
 			MC_ALWAYS_SCROLL | MC_NOBOX | MC_NOCLEAR,
 			NULL, set_ptn_titles, NULL,
-			"help", pi.exit_msg);
+			"help", pm->pi.exit_msg);
 
-		if (pi.menu_no < 0)
+		if (pm->pi.menu_no < 0)
 			return;
 	}
 
 	do {
-		set_ptn_menu(&pi);
-		current_cylsize = dlcylsize;
-		process_menu(pi.menu_no, &pi);
-	} while (pi.free_space < 0 || pi.free_parts < 0);
+		set_ptn_menu(&pm->pi);
+		pm->current_cylsize = pm->dlcylsize;
+		process_menu(pm->pi.menu_no, &pm->pi);
+	} while (pm->pi.free_space < 0 || pm->pi.free_parts < 0);
 
 	/* Give any cylinder fragment to last partition */
-	if (pi.pool_part != NULL || pi.free_space < dlcylsize) {
-		for (p = pi.ptn_sizes + nelem(pi.ptn_sizes) - 1; ;p--) {
+	if (pm->pi.pool_part != NULL || pm->pi.free_space < pm->dlcylsize) {
+		for (p = pm->pi.ptn_sizes + nelem(pm->pi.ptn_sizes) - 1; ;p--) {
 			if (p->size == 0) {
-				if (p == pi.ptn_sizes)
+				if (p == pm->pi.ptn_sizes)
 					break;
 				continue;
 			}
 			if (p->ptn_id == PART_TMP_RAMDISK)
 				continue;
-			p->size += pi.free_space % dlcylsize;
+			p->size += pm->pi.free_space % pm->dlcylsize;
+			pm->pi.free_space -= pm->pi.free_space % pm->dlcylsize;
 			break;
 		}
 	}
 
-	for (p = pi.ptn_sizes; p->mount[0]; p++, part_start += size) {
+	for (p = pm->pi.ptn_sizes; p->mount[0]; p++, part_start += size) {
 		size = p->size;
-		if (p == pi.pool_part) {
-			size += rounddown(pi.free_space, dlcylsize);
+		if (p == pm->pi.pool_part) {
+			size += rounddown(pm->pi.free_space, pm->dlcylsize);
 			if (p->limit != 0 && size > p->limit)
 				size = p->limit;
 		}
@@ -517,10 +533,21 @@ get_ptn_sizes(daddr_t part_start, daddr_t sectors, int no_swap)
 		}
 		if (size == 0)
 			continue;
+		if (i == PART_ROOT && size > 0)
+			root_created = 1;
 		if (i == PART_SWAP) {
+			if (size > 0)
+				swap_created = 1;
 			save_ptn(i, part_start, size, FS_SWAP, NULL);
 			continue;
 		}
+		if (!strcmp(p->mount, "raid")) {
+			save_ptn(i, part_start, size, FS_RAID, NULL);
+			continue;			
+		} else if (!strcmp(p->mount, "cgd")) {
+			save_ptn(i, part_start, size, FS_CGD, NULL);
+			continue;
+		}
 		save_ptn(i, part_start, size, FS_BSDFFS, p->mount);
 	}
 }
@@ -538,51 +565,54 @@ make_bsd_partitions(void)
 	int part_raw, part_bsd;
 	daddr_t ptend;
 	int no_swap = 0, valid_part = -1;
-	partinfo *p;
+	partinfo *p, savedlabel[MAXPARTITIONS];
+
+	memcpy(&savedlabel, &pm->bsdlabel, sizeof savedlabel);
 
 	/*
 	 * Initialize global variables that track space used on this disk.
 	 * Standard 4.4BSD 8-partition labels always cover whole disk.
 	 */
-	if (ptsize == 0)
-		ptsize = dlsize - ptstart;
-	if (dlsize == 0)
-		dlsize = ptstart + ptsize;
+	if (pm->ptsize == 0)
+		pm->ptsize = pm->dlsize - pm->ptstart;
+	if (pm->dlsize == 0)
+		pm->dlsize = pm->ptstart + pm->ptsize;
 
-	partstart = ptstart;
-	ptend = ptstart + ptsize;
+	partstart = pm->ptstart;
+	ptend = pm->ptstart + pm->ptsize;
 
 	/* Ask for layout type -- standard or special */
-	msg_display(MSG_layout,
-		    (int) (ptsize / (MEG / sectorsize)),
+	if (partman_go == 0) {
+		msg_display(MSG_layout,
+		    (int) (pm->ptsize / (MEG / pm->sectorsize)),
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
 		    DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);
-
-	process_menu(MENU_layout, NULL);
+		process_menu(MENU_layout, NULL);
+	}
 
 	/* Set so we use the 'real' geometry for rounding, input in MB */
-	current_cylsize = dlcylsize;
+	pm->current_cylsize = pm->dlcylsize;
 	set_sizemultname_meg();
 
 	/* Build standard partitions */
-	memset(&bsdlabel, 0, sizeof bsdlabel);
+	memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
 
 	/* Set initial partition types to unused */
 	for (part = 0 ; part < maxpart ; ++part)
-		bsdlabel[part].pi_fstype = FS_UNUSED;
+		pm->bsdlabel[part].pi_fstype = FS_UNUSED;
 
 	/* Whole disk partition */
 	part_raw = getrawpartition();
 	if (part_raw == -1)
 		part_raw = PART_C;	/* for sanity... */
-	bsdlabel[part_raw].pi_offset = 0;
-	bsdlabel[part_raw].pi_size = dlsize;
+	pm->bsdlabel[part_raw].pi_offset = 0;
+	pm->bsdlabel[part_raw].pi_size = pm->dlsize;
 
 	if (part_raw == PART_D) {
 		/* Probably a system that expects an i386 style mbr */
 		part_bsd = PART_C;
-		bsdlabel[PART_C].pi_offset = ptstart;
-		bsdlabel[PART_C].pi_size = ptsize;
+		pm->bsdlabel[PART_C].pi_offset = pm->ptstart;
+		pm->bsdlabel[PART_C].pi_size = pm->ptsize;
 	} else {
 		part_bsd = part_raw;
 	}
@@ -591,51 +621,51 @@ make_bsd_partitions(void)
 	i = BOOT_SIZE;
 	if (i >= 1024) {
 		/* Treat big numbers as a byte count */
-		i = (i + dlcylsize * sectorsize - 1) / (dlcylsize * sectorsize);
-		i *= dlcylsize;
+		i = (i + pm->dlcylsize * pm->sectorsize - 1) / (pm->dlcylsize * pm->sectorsize);
+		i *= pm->dlcylsize;
 	}
-	bsdlabel[PART_BOOT].pi_fstype = FS_BOOT;
-	bsdlabel[PART_BOOT].pi_size = i;
+	pm->bsdlabel[PART_BOOT].pi_fstype = FS_BOOT;
+	pm->bsdlabel[PART_BOOT].pi_size = i;
 #ifdef BOOT_HIGH
-	bsdlabel[PART_BOOT].pi_offset = ptend - i;
+	pm->bsdlabel[PART_BOOT].pi_offset = ptend - i;
 	ptend -= i;
 #else
-	bsdlabel[PART_BOOT].pi_offset = ptstart;
+	pm->bsdlabel[PART_BOOT].pi_offset = pm->ptstart;
 	partstart += i;
 #endif
 #elif defined(PART_BOOT)
-	if (bootsize != 0) {
-		bsdlabel[PART_BOOT].pi_fstype = FS_BOOT;
-		bsdlabel[PART_BOOT].pi_size = bootsize;
-		bsdlabel[PART_BOOT].pi_offset = bootstart;
+	if (pm->bootsize != 0) {
+		pm->bsdlabel[PART_BOOT].pi_fstype = FS_BOOT;
+		pm->bsdlabel[PART_BOOT].pi_size = pm->bootsize;
+		pm->bsdlabel[PART_BOOT].pi_offset = pm->bootstart;
 #if defined(PART_BOOT_PI_FLAGS)
-		bsdlabel[PART_BOOT].pi_flags |= PART_BOOT_PI_FLAGS;
+		pm->bsdlabel[PART_BOOT].pi_flags |= PART_BOOT_PI_FLAGS;
 #endif
 #if defined(PART_BOOT_PI_MOUNT)
-		strlcpy(bsdlabel[PART_BOOT].pi_mount, PART_BOOT_PI_MOUNT,
-		    sizeof bsdlabel[PART_BOOT].pi_mount);
+		strlcpy(pm->bsdlabel[PART_BOOT].pi_mount, PART_BOOT_PI_MOUNT,
+		    sizeof pm->bsdlabel[PART_BOOT].pi_mount);
 #endif
 	}
 #endif /* PART_BOOT w/o BOOT_SIZE */
 
 #if defined(PART_SYSVBFS) && defined(SYSVBFS_SIZE)
-	bsdlabel[PART_SYSVBFS].pi_offset = partstart;
-	bsdlabel[PART_SYSVBFS].pi_fstype = FS_SYSVBFS;
-	bsdlabel[PART_SYSVBFS].pi_size = SYSVBFS_SIZE;
-	bsdlabel[PART_SYSVBFS].pi_flags |= PIF_NEWFS | PIF_MOUNT;
-	strlcpy(bsdlabel[PART_SYSVBFS].pi_mount, "/stand",
-	    sizeof bsdlabel[PART_SYSVBFS].pi_mount);
+	pm->bsdlabel[PART_SYSVBFS].pi_offset = partstart;
+	pm->bsdlabel[PART_SYSVBFS].pi_fstype = FS_SYSVBFS;
+	pm->bsdlabel[PART_SYSVBFS].pi_size = SYSVBFS_SIZE;
+	pm->bsdlabel[PART_SYSVBFS].pi_flags |= PIF_NEWFS | PIF_MOUNT;
+	strlcpy(pm->bsdlabel[PART_SYSVBFS].pi_mount, "/stand",
+	    sizeof pm->bsdlabel[PART_SYSVBFS].pi_mount);
 	partstart += SYSVBFS_SIZE;
 #endif
 
 #ifdef PART_REST
-	bsdlabel[PART_REST].pi_offset = 0;
-	bsdlabel[PART_REST].pi_size = ptstart;
+	pm->bsdlabel[PART_REST].pi_offset = 0;
+	pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
 #endif
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/*
-		 * If 'oldlabel' is a default label created by the kernel it
+		 * If 'pm->oldlabel' is a default label created by the kernel it
 		 * will have exactly one valid partition besides raw_part
 		 * which covers the whole disk - but might lie outside the
 		 * mbr partition we (by now) have offset by a few sectors.
@@ -645,7 +675,7 @@ make_bsd_partitions(void)
 		for (i = 0; i < maxpart; i++) {
 			if (i == part_raw)
 				continue;
-			if (oldlabel[i].pi_size > 0 && PI_ISBSDFS(&oldlabel[i])) {
+			if (pm->oldlabel[i].pi_size > 0 && PI_ISBSDFS(&pm->oldlabel[i])) {
 				if (valid_part >= 0) {
 					/* nope, not the default case */
 					valid_part = -1;
@@ -654,9 +684,9 @@ make_bsd_partitions(void)
 				valid_part = i;
 			}
 		}
-		if (valid_part >= 0 && oldlabel[valid_part].pi_offset < ptstart) {
-			oldlabel[valid_part].pi_offset = ptstart;
-			oldlabel[valid_part].pi_size -= ptstart;
+		if (valid_part >= 0 && pm->oldlabel[valid_part].pi_offset < pm->ptstart) {
+			pm->oldlabel[valid_part].pi_offset = pm->ptstart;
+			pm->oldlabel[valid_part].pi_size -= pm->ptstart;
 		}
 	}
 
@@ -667,16 +697,16 @@ make_bsd_partitions(void)
 	 * partitions on a multiboot i386 system.
 	 */
 	 for (i = maxpart; i--;) {
-		if (bsdlabel[i].pi_size != 0)
+		if (pm->bsdlabel[i].pi_size != 0)
 			/* Don't overwrite special partitions */
 			continue;
-		p = &oldlabel[i];
+		p = &pm->oldlabel[i];
 		if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
 			continue;
-		if (layoutkind == 4) {
+		if (layoutkind == LY_USEEXIST) {
 			if (PI_ISBSDFS(p)) {
 				p->pi_flags |= PIF_MOUNT;
-				if (layoutkind == 4 && i == valid_part) {
+				if (layoutkind == LY_USEEXIST && i == valid_part) {
 					int fstype = p->pi_fstype;
 					p->pi_fstype = 0;
 					strcpy(p->pi_mount, "/");
@@ -684,36 +714,53 @@ make_bsd_partitions(void)
 				}
 			}
 		} else {
-			if (p->pi_offset < ptstart + ptsize &&
-			    p->pi_offset + p->pi_size > ptstart)
+			if (p->pi_offset < pm->ptstart + pm->ptsize &&
+			    p->pi_offset + p->pi_size > pm->ptstart)
 				/* Not outside area we are allocating */
 				continue;
 			if (p->pi_fstype == FS_SWAP)
 				no_swap = 1;
 		}
-		bsdlabel[i] = oldlabel[i];
+		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind != 4)
+	if (layoutkind == LY_SETNEW)
 		get_ptn_sizes(partstart, ptend - partstart, no_swap);
+	
+	else if (layoutkind == LY_NEWRAID) {
+		set_ptype(&(pm->bsdlabel[PART_E]), FS_RAID, 0);
+		pm->bsdlabel[PART_E].pi_size = pm->ptsize;
+	}
+	else if (layoutkind == LY_NEWCGD) {
+		set_ptype(&(pm->bsdlabel[PART_E]), FS_CGD, 0);
+		pm->bsdlabel[PART_E].pi_size = pm->ptsize;
+	}
+	else if (layoutkind == LY_NEWLVM) {
+		set_ptype(&(pm->bsdlabel[PART_E]), FS_BSDFFS, 0);
+		pm->bsdlabel[PART_E].pi_size = pm->ptsize;
+		pm->bsdlabel[PART_E].lvmpv = 1;
+	}
 
 	/*
 	 * OK, we have a partition table. Give the user the chance to
 	 * edit it and verify it's OK, or abort altogether.
 	 */
- edit_check:
-	if (edit_and_check_label(bsdlabel, maxpart, part_raw, part_bsd) == 0) {
-		msg_display(MSG_abort);
-		return 0;
-	}
-	if (check_partitions() == 0)
-		goto edit_check;
+ 	do {
+		if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
+			msg_display(MSG_abort);
+			memcpy(&pm->bsdlabel, &savedlabel, sizeof pm->bsdlabel);
+			return 0;
+		}
+	} while (partman_go == 0 && check_partitions() == 0);
 
 	/* Disk name */
-	msg_prompt(MSG_packname, bsddiskname, bsddiskname, sizeof bsddiskname);
+	if (!partman_go)
+		msg_prompt(MSG_packname, pm->bsddiskname, pm->bsddiskname,
+			sizeof pm->bsddiskname);
 
 	/* save label to disk for MI code to update. */
-	(void) savenewlabel(bsdlabel, maxpart);
+	if (! partman_go)
+		(void) savenewlabel(pm->bsdlabel, maxpart);
 
 	/* Everything looks OK. */
 	return (1);
@@ -722,11 +769,11 @@ make_bsd_partitions(void)
 /*
  * check that there is at least a / somewhere.
  */
-static int
+int
 check_partitions(void)
 {
 #ifdef HAVE_BOOTXX_xFS
-	int rv;
+	int rv = 1;
 	char *bootxx;
 #endif
 #ifndef HAVE_UFS2_BOOT
@@ -746,9 +793,9 @@ check_partitions(void)
 	}
 #endif
 #ifndef HAVE_UFS2_BOOT
-	fstype = bsdlabel[rootpart].pi_fstype;
+	fstype = pm->bsdlabel[pm->rootpart].pi_fstype;
 	if (fstype == FS_BSDFFS &&
-	    (bsdlabel[rootpart].pi_flags & PIF_FFSv2) != 0) {
+	    (pm->bsdlabel[pm->rootpart].pi_flags & PIF_FFSv2) != 0) {
 		process_menu(MENU_ok, deconst(MSG_cannot_ufs2_root));
 		return 0;
 	}
diff --git a/distrib/utils/sysinst/configmenu.c b/distrib/utils/sysinst/configmenu.c
index 32f1ff5..1d2c50d 100644
--- a/distrib/utils/sysinst/configmenu.c
+++ b/distrib/utils/sysinst/configmenu.c
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <curses.h>
 #include <unistd.h>
+#include <errno.h>
 #include "defs.h"
 #include "msg_defs.h"
 #include "menu_defs.h"
@@ -67,6 +68,10 @@ enum {
 	CONFIGOPT_NTPD,
 	CONFIGOPT_NTPDATE,
 	CONFIGOPT_MDNSD,
+	CONFIGOPT_XDM,
+	CONFIGOPT_CGD,
+	CONFIGOPT_LVM,
+	CONFIGOPT_RAIDFRAME,
 	CONFIGOPT_LAST
 };
 
@@ -84,12 +89,16 @@ configinfo config_list[] = {
 	{MSG_timezone, CONFIGOPT_TZ, NULL, set_timezone_menu, NULL},
 	{MSG_Root_shell, CONFIGOPT_ROOTSH, NULL, set_root_shell, NULL},
 	{MSG_change_rootpw, CONFIGOPT_ROOTPW, NULL, change_root_password, MSG_change},
-	{MSG_enable_binpkg, CONFIGOPT_BINPKG, NULL, set_binpkg, MSG_configure},
+	{MSG_enable_binpkg, CONFIGOPT_BINPKG, NULL, set_binpkg, MSG_install},
 	{MSG_get_pkgsrc, CONFIGOPT_PKGSRC, NULL, set_pkgsrc, MSG_install},
 	{MSG_enable_sshd, CONFIGOPT_SSHD, "sshd", toggle_rcvar, NULL},
 	{MSG_enable_ntpd, CONFIGOPT_NTPD, "ntpd", toggle_rcvar, NULL},
 	{MSG_run_ntpdate, CONFIGOPT_NTPDATE, "ntpdate", toggle_rcvar, NULL},
 	{MSG_enable_mdnsd, CONFIGOPT_MDNSD, "mdnsd", toggle_rcvar, NULL},
+	{MSG_enable_xdm, CONFIGOPT_XDM, "xdm", toggle_rcvar, NULL},
+	{MSG_enable_cgd, CONFIGOPT_CGD, "cgd", toggle_rcvar, NULL},
+	{MSG_enable_lvm, CONFIGOPT_LVM, "lvm", toggle_rcvar, NULL},
+	{MSG_enable_raid, CONFIGOPT_RAIDFRAME, "raidframe", toggle_rcvar, NULL},
 	{NULL,		CONFIGOPT_LAST,	NULL, NULL, NULL}
 };
 
@@ -198,8 +207,9 @@ set_root_shell(struct menudesc *menu, void *arg)
 	configinfo **confp = arg;
 	
 	process_menu(MENU_rootsh, &confp[menu->cursel]->setting);
-	run_program(RUN_PROGRESS | RUN_CHROOT,
-		"chpass -s %s root", confp[menu->cursel]->setting);
+	if (run_program(RUN_PROGRESS | RUN_CHROOT,
+		"chpass -s %s root", confp[menu->cursel]->setting) != 0)
+		confp[menu->cursel]->setting = MSG_failed;
 	return 0;
 }
 
@@ -243,10 +253,13 @@ change_root_password(struct menudesc *menu, void *arg)
 
 	msg_display(MSG_rootpw);
 	process_menu(MENU_yesno, NULL);
-	if (yesno)
-		run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
-			"passwd -l root");
-	confp[menu->cursel]->setting = MSG_password_set;
+	if (yesno) {
+		if (run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
+			"passwd -l root") == 0)
+			confp[menu->cursel]->setting = MSG_password_set;
+		else
+			confp[menu->cursel]->setting = MSG_failed;
+	}
 	return 0;
 }
 
@@ -254,25 +267,24 @@ static int
 set_binpkg(struct menudesc *menu, void *arg)
 {
 	configinfo **confp = arg;
-
+	char additional_pkgs[STRSIZE] = {0};
 	char pattern[STRSIZE];
+	int allok = 0;
 
-	/* binary pkg config requires network at this point, so if
-	   it's not already configured, do it. */
-	if (network_up == 0) {
-		if (config_network())
-			mnt_net_config();
-	}
-
-	process_menu(MENU_binpkg, NULL);
-	make_url(pkgpath, &pkg, pkg_dir);
-	if ( run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
-		"pkg_add %s/pkgin", pkgpath) != 0) {
-		msg_display(MSG_pkgin_failed);
-		process_menu(MENU_ok, NULL);
-		confp[menu->cursel]->setting = MSG_failed;
-		return 0;
-	}
+	do {
+		yesno = -1;
+		process_menu(MENU_binpkg, additional_pkgs);
+		if (yesno == SET_SKIP) {
+			confp[menu->cursel]->setting = MSG_abandoned;
+			return 0;
+		}
+		
+		make_url(pkgpath, &pkg, pkg_dir);
+		if (run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
+			"pkg_add %s/pkgin", pkgpath) == 0) {
+			allok = 1;
+		}
+	} while (allok == 0);
 
 	/* configure pkgin to use $pkgpath as a repository */
 	snprintf(pattern, STRSIZE, "s,^[^#].*$,%s,", pkgpath);
@@ -281,9 +293,13 @@ set_binpkg(struct menudesc *menu, void *arg)
 	run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
 		"/usr/pkg/bin/pkgin -y update");
 
+	if (strlen(additional_pkgs) > 0)
+		run_program(RUN_DISPLAY | RUN_PROGRESS | RUN_CHROOT,
+		"/usr/pkg/bin/pkgin -y install %s", additional_pkgs);
+	
 	msg_display(MSG_binpkg_installed);
 	process_menu(MENU_ok, NULL);
-	
+
 	confp[menu->cursel]->setting = MSG_DONE;
 	return 0;
 }
@@ -317,8 +333,7 @@ set_pkgsrc(struct menudesc *menu, void *arg)
 		}
 	}
 	while (status == SET_RETRY);
-	
-	
+
 	confp[menu->cursel]->setting = MSG_DONE;
 	return 0;
 }
@@ -349,9 +364,9 @@ toggle_rcvar(struct menudesc *menu, void *arg)
 	}
 
 	if (!(fp = fopen(target_expand("/etc/rc.conf"), "r"))) {
-		msg_display(MSG_rcconf_delete_failed, varname);
+		msg_display(MSG_openfail, target_expand("/etc/rc.conf"), strerror(errno));
 		process_menu(MENU_ok, NULL);
-		return -1;
+		return 0;
 	}
 
 	while (fgets(buf, sizeof buf, fp) != NULL) {
@@ -402,13 +417,9 @@ do_configmenu()
 	menu_ent	me[CONFIGOPT_LAST];
 	configinfo	*ce[CONFIGOPT_LAST];
 
-        wrefresh(curscr);
-        wmove(stdscr, 0, 0);
-        wclear(stdscr);
-        wrefresh(stdscr);
-	
 	/* if the target isn't mounted already, figure it out. */
 	if (target_mounted() == 0) {
+		partman_go = 0;
 		if (find_disks(msg_string(MSG_configure_prior)) < 0)
 			return;
 
@@ -420,6 +431,11 @@ do_configmenu()
 	make_url(pkgpath, &pkg, pkg_dir);
 	opts = init_config_menu(config_list, me, ce);
 
+	wrefresh(curscr);
+	wmove(stdscr, 0, 0);
+	wclear(stdscr);
+	wrefresh(stdscr);
+
 	menu_no = new_menu(NULL, me, opts, 0, -4, 0, 70,
 		MC_SCROLL | MC_NOBOX | MC_DFLTEXIT,
 		configmenu_hdr, set_config, NULL, "XXX Help String",
@@ -427,7 +443,4 @@ do_configmenu()
 
 	process_menu(menu_no, ce);
 	free_menu(menu_no);
-
-	sanity_check();
-
 }
diff --git a/distrib/utils/sysinst/defs.h b/distrib/utils/sysinst/defs.h
index 1ffdb9a..6b56f0f 100644
--- a/distrib/utils/sysinst/defs.h
+++ b/distrib/utils/sysinst/defs.h
@@ -38,8 +38,10 @@
 /* defs.h -- definitions for use in the sysinst program. */
 
 /* System includes needed for this. */
+#include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/disklabel.h>
+#include <sys/disk.h>
 
 const char *getfslabelname(uint8_t);
 
@@ -83,6 +85,9 @@ deconst(const void *p)
 #define RUN_NO_CLEAR	0x0100		/* Leave program output after error */
 #define RUN_XFER_DIR	0x0200		/* cd to xfer_dir in child */
 
+/* for bsddisklabel.c */
+enum { LY_SETNEW, LY_NEWRAID, LY_NEWCGD, LY_NEWLVM, LY_USEEXIST };
+
 /* Installation sets */
 enum {
     SET_NONE,
@@ -184,6 +189,7 @@ typedef struct distinfo {
 	const char	*marker_file;	/* set assumed installed if exists */
 } distinfo;
 
+#define MOUNTLEN 20
 typedef struct _partinfo {
 	struct partition pi_partition;
 #define pi_size		pi_partition.p_size
@@ -192,7 +198,7 @@ typedef struct _partinfo {
 #define pi_fstype	pi_partition.p_fstype
 #define pi_frag		pi_partition.p_frag
 #define pi_cpg		pi_partition.p_cpg
-	char	pi_mount[20];
+	char	pi_mount[MOUNTLEN];
 	uint	pi_isize;		/* bytes per inode (for # inodes) */
 	uint	pi_flags;
 #define PIF_NEWFS	0x0001		/* need to 'newfs' partition */
@@ -208,13 +214,17 @@ typedef struct _partinfo {
 #define PIF_LOG		0x0800		/* mount -o log */
 #define PIF_MOUNT_OPTS	0x0ff0		/* all above mount flags */
 #define PIF_RESET	0x1000		/* internal - restore previous values */
+    const char *mnt_opts;
+    const char *fsname;
+    char mounted[MOUNTLEN];
+    int lvmpv; /* should we use partition as LVM PV? */
 } partinfo;	/* Single partition from a disklabel */
 
 struct ptn_info {
 	int		menu_no;
 	struct ptn_size {
 		int	ptn_id;
-		char	mount[20];
+		char	mount[MOUNTLEN];
 		daddr_t	dflt_size;
 		daddr_t	size;
 		int	limit;
@@ -241,41 +251,79 @@ pid_t ttysig_forward;
 int layoutkind;
 int sizemult;
 const char *multname;
+int partman_go; /* run extended partition manager */
 
-/* loging variables */
+/* logging variables */
 
 FILE *logfp;
 FILE *script;
 
-/* Actual name of the disk. */
-char diskdev[SSTRSIZE];
-int no_mbr;				/* set for raid (etc) */
-int rootpart;				/* partition we install into */
-const char *disktype;		/* ST506, SCSI, ... */
-
-/* Area of disk we can allocate, start and size in disk sectors. */
-daddr_t ptstart, ptsize;
-/* If we have an MBR boot partition, start and size in sectors */
-int bootstart, bootsize;
-
-/* Actual values for current disk - set by find_disks() or md_get_info() */
-int sectorsize;
-int dlcyl, dlhead, dlsec, dlcylsize;
-daddr_t dlsize;
-int current_cylsize;
-unsigned int root_limit;		/* BIOS (etc) read limit */
-
 /* Information for the NetBSD disklabel */
+
 enum DLTR { PART_A, PART_B, PART_C, PART_D, PART_E, PART_F, PART_G, PART_H,
 	    PART_I, PART_J, PART_K, PART_L, PART_M, PART_N, PART_O, PART_P};
 #define partition_name(x)	('a' + (x))
-partinfo oldlabel[MAXPARTITIONS];	/* What we found on the disk */
-partinfo bsdlabel[MAXPARTITIONS];	/* What we want it to look like */
 daddr_t tmp_ramdisk_size;
+#define MAX_DISKS 15
+
+unsigned int root_limit;    /* BIOS (etc) read limit */
 
+enum SHRED_T { SHRED_NONE=0, SHRED_ZEROS, SHRED_RANDOM, SHRED_CRYPTO };
+
+/* All information that is unique for each drive */
+SLIST_HEAD(pm_head_t, pm_devs_t) pm_head;
+
+typedef struct pm_devs_t {
+    int unsaved; /* Flag indicating to partman that device need saving */
+    int found; /* Flag to delete unplugged and unconfigured devices */
+    int blocked; /* Device is busy and cannot be changed */
+    void *refdev; /* If device is blocked thats is a pointers to a parent dev */
+    int isspecial; /* LVM LV or DK device that doesnot accept disklabel */
+    char diskdev[SSTRSIZE]; /* Actual name of the disk. */
+    char diskdev_descr[STRSIZE];
+    int bootable;
 #define DISKNAME_SIZE 16
-char bsddiskname[DISKNAME_SIZE];
-const char *doessf;
+    char bsddiskname[DISKNAME_SIZE];
+    partinfo oldlabel[MAXPARTITIONS]; /* What we found on the disk */
+    partinfo bsdlabel[MAXPARTITIONS]; /* What we want it to look like */
+    int gpt;
+    int no_mbr; /* set for raid (etc) */
+    int rootpart; /* partition we install into */
+    const char *disktype; /* ST506, SCSI, ... */
+    const char *doessf;
+    /* Actual values for current disk - set by find_disks() or md_get_info() */
+    int sectorsize, dlcyl, dlhead, dlsec, dlcylsize, current_cylsize;
+    daddr_t dlsize;
+    /* Area of disk we can allocate, start and size in disk sectors. */
+    daddr_t ptstart, ptsize;
+    /* If we have an MBR boot partition, start and size in sectors */
+    int bootstart, bootsize;
+    struct ptn_info pi;
+    SLIST_ENTRY(pm_devs_t) l;
+} pm_devs_t;
+pm_devs_t *pm; /* Pointer to currend device with which we work */
+pm_devs_t *pm_new; /* Pointer for next allocating device in find_disks() */
+
+#define MAX_WEDGES 16 /* num of dk* devices */
+typedef struct pm_wedge_t {
+    int allocated;
+    int todel;
+    pm_devs_t *pm;
+    int ptn;
+} pm_wedge_t;
+pm_wedge_t wedges[MAX_WEDGES];
+
+/* Generic structure for partman */
+typedef struct {
+    int retvalue;
+    int dev_num;
+    int wedge_num;
+    void *dev_ptr;
+    int dev_ptr_delta;
+    char fullname[SSTRSIZE];
+    enum {PM_DISK_T=1, PM_PART_T, PM_WEDGE_T, PM_SPEC_T, PM_RAID_T, PM_CGD_T,
+        PM_VND_T, PM_LVM_T, PM_LVMLV_T} type;
+} part_entry_t;
 
 /* Relative file name for storing a distribution. */
 char xfer_dir[STRSIZE];
@@ -389,7 +437,11 @@ int	make_fstab(void);
 int	mount_disks(void);
 int	set_swap(const char *, partinfo *);
 int	check_swap(const char *, int);
-char	*bootxx_name(void);
+char *bootxx_name(void);
+void label_read(void);
+int get_dkwedges(struct dkwedge_info **, const char *);
+const char *get_gptfs_by_id(int);
+
 
 /* from disks_lfs.c */
 int	fs_is_lfs(void *);
@@ -402,6 +454,8 @@ int	edit_and_check_label(partinfo *, int, int, int);
 void	set_bsize(partinfo *, int);
 void	set_fsize(partinfo *, int);
 void	set_ptype(partinfo *, int, int);
+int edit_ptn(menudesc *, void *);
+int checkoverlap(partinfo *, int, int, int);
 
 /* from install.c */
 void	do_install(void);
@@ -476,6 +530,8 @@ const char *ext_dir_for_set(const char *);
 void	replace(const char *, const char *, ...);
 void	get_tz_default(void);
 int	extract_file(distinfo *, int);
+void	do_coloring (unsigned int, unsigned int);
+int set_menu_select(menudesc *, void *);
 
 /* from target.c */
 #if defined(DEBUG)  ||	defined(DEBUG_ROOT)
@@ -501,6 +557,7 @@ void	dup_file_into_target(const char *);
 void	mv_within_target_or_die(const char *, const char *);
 int	cp_within_target(const char *, const char *, int);
 int	target_mount(const char *, const char *, int, const char *);
+int target_mount_do(const char *, const char *, const char *);
 int	target_test(unsigned int, const char *);
 int	target_dir_exists_p(const char *);
 int	target_file_exists_p(const char *);
@@ -508,6 +565,21 @@ int	target_symlink_exists_p(const char *);
 void	unwind_mounts(void);
 int	target_mounted(void);
 
+/* from partman.c */
+int partman(void);
+int pm_partusage(pm_devs_t *, int, int);
+int pm_getrefdev(pm_devs_t *);
+void pm_setfstype(pm_devs_t *, int, int);
+int pm_editpart(int);
+void pm_rename(pm_devs_t *);
+int pm_shred(pm_devs_t *, int, int);
+void pm_umount(pm_devs_t *, int);
+int pm_unconfigure(pm_devs_t *);
+int pm_cgd_edit(void *, part_entry_t *);
+int pm_gpt_convert(pm_devs_t *);
+void pm_wedges_fill(pm_devs_t *);
+void pm_make_bsd_partitions(pm_devs_t *);
+
 /* from bsddisklabel.c */
 int	make_bsd_partitions(void);
 int	save_ptn(int, daddr_t, daddr_t, int, const char *);
@@ -515,6 +587,7 @@ void	set_ptn_titles(menudesc *, int, void *);
 void	set_ptn_menu(struct ptn_info *);
 int	set_ptn_size(menudesc *, void *);
 void	get_ptn_sizes(daddr_t, daddr_t, int);
+int check_partitions(void);
 
 /* from aout2elf.c */
 int move_aout_libs(void);
@@ -533,4 +606,6 @@ void	do_configmenu(void);
 /* from checkrc.c */
 int	check_rcvar(const char *);
 int	check_rcdefault(const char *);
+	WINDOW *mainwin;
+
 #endif	/* _DEFS_H_ */
diff --git a/distrib/utils/sysinst/disks.c b/distrib/utils/sysinst/disks.c
index d4a04b5..251eb54 100644
--- a/distrib/utils/sysinst/disks.c
+++ b/distrib/utils/sysinst/disks.c
@@ -41,6 +41,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <util.h>
+#include <uuid.h>
 
 #include <sys/param.h>
 #include <sys/swap.h>
@@ -48,6 +49,7 @@
 #include <ufs/ffs/fs.h>
 #define FSTYPENAMES
 #include <sys/disklabel.h>
+#include <sys/disklabel_gpt.h>
 
 #include <dev/scsipi/scsipi_all.h>
 #include <sys/scsiio.h>
@@ -62,7 +64,6 @@
 #include "txtwalk.h"
 
 /* Disk descriptions */
-#define MAX_DISKS 15
 struct disk_desc {
 	char	dd_name[SSTRSIZE];
 	char	dd_descr[70];
@@ -74,6 +75,29 @@ struct disk_desc {
 	uint	dd_totsec;
 };
 
+/* gpt(8) use different filesystem names.
+   So, we cant use ./common/lib/libutil/getfstypename.c */
+struct gptfs_t {
+    const char *name;
+    int id;
+    uuid_t uuid;
+};
+static const struct gptfs_t gpt_filesystems[] = {
+    { "swap", FS_SWAP, GPT_ENT_TYPE_NETBSD_SWAP, },
+    { "ffs", FS_BSDFFS, GPT_ENT_TYPE_NETBSD_FFS, },
+    { "lfs", FS_BSDLFS, GPT_ENT_TYPE_NETBSD_LFS, },
+    { "linux", FS_EX2FS, GPT_ENT_TYPE_LINUX_DATA, },
+    { "windows,", FS_MSDOS, GPT_ENT_TYPE_MS_BASIC_DATA, },
+    { "hfs", FS_HFS, GPT_ENT_TYPE_APPLE_HFS, },
+    { "ufs", FS_OTHER, GPT_ENT_TYPE_APPLE_UFS, },
+    { "ccd", FS_CCD, GPT_ENT_TYPE_NETBSD_CCD, },
+    { "raid", FS_RAID, GPT_ENT_TYPE_NETBSD_RAIDFRAME, },
+    { "cgd", FS_CGD, GPT_ENT_TYPE_NETBSD_CGD, },
+    { "efi", FS_OTHER, GPT_ENT_TYPE_EFI, },
+    { "bios", FS_OTHER, GPT_ENT_TYPE_BIOS, },
+    { NULL, -1, GPT_ENT_TYPE_UNUSED, },
+};
+
 /* Local prototypes */
 static int foundffs(struct data *, size_t);
 #ifdef USE_SYSVBFS
@@ -81,12 +105,14 @@ static int foundsysvbfs(struct data *, size_t);
 #endif
 static int fsck_preen(const char *, int, const char *);
 static void fixsb(const char *, const char *, char);
+static int is_gpt(const char *);
+static int incoregpt(pm_devs_t *, partinfo *);
 
 #ifndef DISK_NAMES
 #define DISK_NAMES "wd", "sd", "ld", "raid"
 #endif
 
-static const char *disk_names[] = { DISK_NAMES, "vnd", NULL };
+static const char *disk_names[] = { DISK_NAMES, "vnd", "cgd", NULL };
 
 const char *
 getfslabelname(uint8_t f)
@@ -297,6 +323,7 @@ get_descr(struct disk_desc *dd)
 	/* try SCSI */
 	if (get_descr_scsi(dd, fd))
 		goto done;
+	/* XXX: get description from raid, cgd, vnd... */
 
 done:
 	if (fd >= 0)
@@ -349,23 +376,16 @@ get_disks(struct disk_desc *dd)
 	return numdisks;
 }
 
-static int
-set_dsk_select(menudesc *m, void *arg)
-{
-	*(int *)arg = m->cursel;
-	return 1;
-}
-
 int
 find_disks(const char *doingwhat)
 {
 	struct disk_desc disks[MAX_DISKS];
-	menu_ent dsk_menu[nelem(disks)];
+	menu_ent dsk_menu[nelem(disks) + 1]; // + 1 for extended partitioning entry
 	struct disk_desc *disk;
-	int i;
-	int numdisks;
-	int selected_disk = 0;
+	int i, already_found;
+	int numdisks, selected_disk = -1;
 	int menu_no;
+	pm_devs_t *pm_i, *pm_last = NULL;
 
 	/* Find disks. */
 	numdisks = get_disks(disks);
@@ -376,66 +396,127 @@ find_disks(const char *doingwhat)
 	/* Kill typeahead, it won't be what the user had in mind */
 	fpurge(stdin);
 
-	if (numdisks == 0) {
-		/* No disks found! */
-		msg_display(MSG_nodisk);
-		process_menu(MENU_ok, NULL);
-		/*endwin();*/
-		return -1;
+	/* partman_go: <0 - we want to see menu with extended partitioning
+				  ==0 - we want to see simple select disk menu
+				   >0 - we do not want to see any menus, just detect all disks */
+	if (partman_go <= 0) {
+		if (numdisks == 0) {
+			/* No disks found! */
+			msg_display(MSG_nodisk);
+			process_menu(MENU_ok, NULL);
+			/*endwin();*/
+			return -1;
+		} else {
+			/* One or more disks found! */
+			for (i = 0; i < numdisks; i++) {
+				dsk_menu[i].opt_name = disks[i].dd_descr;
+				dsk_menu[i].opt_menu = OPT_NOMENU;
+				dsk_menu[i].opt_flags = OPT_EXIT;
+				dsk_menu[i].opt_action = set_menu_select;
+			}
+			if (partman_go < 0) {
+				dsk_menu[i].opt_name = MSG_partman;
+				dsk_menu[i].opt_menu = OPT_NOMENU;
+				dsk_menu[i].opt_flags = OPT_EXIT;
+				dsk_menu[i].opt_action = set_menu_select;
+			}
+			menu_no = new_menu(MSG_Available_disks,
+				dsk_menu, numdisks + ((partman_go<0)?1:0), -1, 4, 0, 0, MC_SCROLL,
+				NULL, NULL, NULL, NULL, NULL);
+			if (menu_no == -1)
+				return -1;
+			msg_display(MSG_ask_disk, doingwhat);
+			process_menu(menu_no, &selected_disk);
+			free_menu(menu_no);
+		}
+		if (partman_go < 0 && selected_disk == numdisks) {
+			partman_go = 1;
+	    	return -2;
+		} else
+			partman_go = 0;
+		if (selected_disk < 0 || selected_disk >= numdisks)
+	    	return -1;
 	}
 
-	if (numdisks == 1) {
-		/* One disk found! */
-		msg_display(MSG_onedisk, disks[0].dd_descr, doingwhat);
-		process_menu(MENU_ok, NULL);
-	} else {
-		/* Multiple disks found! */
-		for (i = 0; i < numdisks; i++) {
-			dsk_menu[i].opt_name = disks[i].dd_descr;
-			dsk_menu[i].opt_menu = OPT_NOMENU;
-			dsk_menu[i].opt_flags = OPT_EXIT;
-			dsk_menu[i].opt_action = set_dsk_select;
+	/* Fill pm struct with device(s) info */
+	for (i = 0; i < numdisks; i++) {
+		if (! partman_go)
+			disk = disks + selected_disk;
+		else {
+			disk = disks + i;
+			already_found = 0;
+			SLIST_FOREACH(pm_i, &pm_head, l) {
+				pm_last = pm_i;
+				if (!already_found && 
+						strcmp(pm_i->diskdev, disk->dd_name) == 0) {
+					pm_i->found = 1;
+					break;
+				}
+			}
+			if (pm_i != NULL && pm_i->found)
+				/* We already added this device, skipping */
+				continue;
 		}
-		menu_no = new_menu(MSG_Available_disks,
-			dsk_menu, numdisks, -1, 4, 0, 0,
-			MC_SCROLL | MC_NOEXITOPT,
-			NULL, NULL, NULL, NULL, NULL);
-		if (menu_no == -1)
+		pm = pm_new;
+		pm->found = 1;
+		pm->bootable = 0;
+		pm->pi.menu_no = -1;
+		pm->disktype = "unknown";
+		pm->doessf = "";
+		strlcpy(pm->diskdev, disk->dd_name, sizeof pm->diskdev);
+		strlcpy(pm->diskdev_descr, disk->dd_descr, sizeof pm->diskdev_descr);
+		/* Use as a default disk if the user has the sets on a local disk */
+		strlcpy(localfs_dev, disk->dd_name, sizeof localfs_dev);
+
+		pm->gpt = is_gpt(pm->diskdev);
+		pm->no_mbr = disk->dd_no_mbr || pm->gpt;
+		pm->sectorsize = disk->dd_secsize;
+		pm->dlcyl = disk->dd_cyl;
+		pm->dlhead = disk->dd_head;
+		pm->dlsec = disk->dd_sec;
+		pm->dlsize = disk->dd_totsec;
+		if (pm->dlsize == 0)
+			pm->dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec;
+		if (pm->dlsize > UINT32_MAX && ! partman_go) {
+			if (logfp)
+				fprintf(logfp, "Cannot process disk %s: too big size (%d)\n",
+					pm->diskdev, (int)pm->dlsize);
+			msg_display(MSG_toobigdisklabel);
+			process_menu(MENU_ok, NULL);
 			return -1;
-		msg_display(MSG_ask_disk, doingwhat);
-		process_menu(menu_no, &selected_disk);
-		free_menu(menu_no);
-	}
+		}
+		pm->dlcylsize = pm->dlhead * pm->dlsec;
 
-	disk = disks + selected_disk;
-	strlcpy(diskdev, disk->dd_name, sizeof diskdev);
-
-	/* Use as a default disk if the user has the sets on a local disk */
-	strlcpy(localfs_dev, disk->dd_name, sizeof localfs_dev);
-
-	sectorsize = disk->dd_secsize;
-	dlcyl = disk->dd_cyl;
-	dlhead = disk->dd_head;
-	dlsec = disk->dd_sec;
-	dlsize = disk->dd_totsec;
-	no_mbr = disk->dd_no_mbr;
-	if (dlsize == 0)
-		dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec;
-	if (dlsize > UINT32_MAX) {
-		msg_display(MSG_toobigdisklabel);
-		process_menu(MENU_ok, NULL);
-		return -1;
+		label_read();
+		if (partman_go) {
+			pm_getrefdev(pm_new);
+			if (SLIST_EMPTY(&pm_head) || pm_last == NULL)
+				 SLIST_INSERT_HEAD(&pm_head, pm_new, l);
+			else
+				 SLIST_INSERT_AFTER(pm_last, pm_new, l);
+			pm_new = malloc(sizeof (pm_devs_t));
+			memset(pm_new, 0, sizeof *pm_new);
+		} else
+			/* We is not in partman and do not want to process all devices, exit */
+			break;
 	}
-	dlcylsize = dlhead * dlsec;
 
-	/* Get existing/default label */
-	memset(&oldlabel, 0, sizeof oldlabel);
-	incorelabel(diskdev, oldlabel);
+	return numdisks;
+}
 
+void
+label_read(void)
+{
+	/* Get existing/default label */
+	memset(&pm->oldlabel, 0, sizeof pm->oldlabel);
+	if (! pm->gpt)
+		incorelabel(pm->diskdev, pm->oldlabel);
+	else
+		incoregpt(pm, pm->oldlabel);
 	/* Set 'target' label to current label in case we don't change it */
-	memcpy(&bsdlabel, &oldlabel, sizeof bsdlabel);
-
-	return numdisks;
+	memcpy(&pm->bsdlabel, &pm->oldlabel, sizeof pm->bsdlabel);
+	if (! pm->gpt)
+		savenewlabel(pm->oldlabel, getmaxpartitions());
 }
 
 void
@@ -444,7 +525,7 @@ fmt_fspart(menudesc *m, int ptn, void *arg)
 	unsigned int poffset, psize, pend;
 	const char *desc;
 	static const char *Yes, *No;
-	partinfo *p = bsdlabel + ptn;
+	partinfo *p = pm->bsdlabel + ptn;
 
 	if (Yes == NULL) {
 		Yes = msg_string(MSG_Yes);
@@ -502,7 +583,7 @@ write_disklabel (void)
 #ifdef DISKLABEL_CMD
 	/* disklabel the disk */
 	return run_program(RUN_DISPLAY, "%s -f /tmp/disktab %s '%s'",
-	    DISKLABEL_CMD, diskdev, bsddiskname);
+	    DISKLABEL_CMD, pm->diskdev, pm->bsddiskname);
 #else
 	return 0;
 #endif
@@ -512,8 +593,8 @@ write_disklabel (void)
 static int
 ptn_sort(const void *a, const void *b)
 {
-	return strcmp(bsdlabel[*(const int *)a].pi_mount,
-		      bsdlabel[*(const int *)b].pi_mount);
+	return strcmp(pm->bsdlabel[*(const int *)a].pi_mount,
+		      pm->bsdlabel[*(const int *)b].pi_mount);
 }
 
 int
@@ -521,16 +602,14 @@ make_filesystems(void)
 {
 	unsigned int i;
 	int ptn;
-	int ptn_order[nelem(bsdlabel)];
+	int ptn_order[nelem(pm->bsdlabel)];
 	int error = 0;
 	unsigned int maxpart = getmaxpartitions();
-	char *newfs;
-	const char *mnt_opts;
-	const char *fsname;
+	char *newfs = NULL, *dev = NULL, *devdev = NULL;
 	partinfo *lbl;
 
-	if (maxpart > nelem(bsdlabel))
-		maxpart = nelem(bsdlabel);
+	if (maxpart > nelem(pm->bsdlabel))
+		maxpart = nelem(pm->bsdlabel);
 
 	/* Making new file systems and mounting them */
 
@@ -546,24 +625,36 @@ make_filesystems(void)
 		 * point defined, or is marked preserve, don't touch it!
 		 */
 		ptn = ptn_order[i];
-		lbl = bsdlabel + ptn;
+		lbl = pm->bsdlabel + ptn;
 
-		if (is_active_rootpart(diskdev, ptn))
+		if (is_active_rootpart(pm->diskdev, ptn))
 			continue;
 
 		if (*lbl->pi_mount == 0)
 			/* No mount point */
 			continue;
 
+		if (pm->isspecial) {
+			asprintf(&dev, "%s", pm->diskdev);
+			ptn = 0 - 'a';
+		} else {
+			asprintf(&dev, "%s%c", pm->diskdev, 'a' + ptn);
+		}
+		if (dev == NULL)
+			return (ENOMEM);
+		asprintf(&devdev, "/dev/%s", dev);
+		if (devdev == NULL)
+			return (ENOMEM);
+
 		newfs = NULL;
-		mnt_opts = NULL;
-		fsname = NULL;
+		lbl->mnt_opts = NULL;
+		lbl->fsname = NULL;
 		switch (lbl->pi_fstype) {
 		case FS_APPLEUFS:
 			asprintf(&newfs, "/sbin/newfs %s%.0d",
 				lbl->pi_isize != 0 ? "-i" : "", lbl->pi_isize);
-			mnt_opts = "-tffs -o async";
-			fsname = "ffs";
+			lbl->mnt_opts = "-tffs -o async";
+			lbl->fsname = "ffs";
 			break;
 		case FS_BSDFFS:
 			asprintf(&newfs,
@@ -572,36 +663,36 @@ make_filesystems(void)
 			    lbl->pi_fsize * lbl->pi_frag, lbl->pi_fsize,
 			    lbl->pi_isize != 0 ? " -i " : "", lbl->pi_isize);
 			if (lbl->pi_flags & PIF_LOG)
-				mnt_opts = "-tffs -o log";
+				lbl->mnt_opts = "-tffs -o log";
 			else
-				mnt_opts = "-tffs -o async";
-			fsname = "ffs";
+				lbl->mnt_opts = "-tffs -o async";
+			lbl->fsname = "ffs";
 			break;
 		case FS_BSDLFS:
 			asprintf(&newfs, "/sbin/newfs_lfs -b %d",
 				lbl->pi_fsize * lbl->pi_frag);
-			mnt_opts = "-tlfs";
-			fsname = "lfs";
+			lbl->mnt_opts = "-tlfs";
+			lbl->fsname = "lfs";
 			break;
 		case FS_MSDOS:
 #ifdef USE_NEWFS_MSDOS
 			asprintf(&newfs, "/sbin/newfs_msdos");
 #endif
-			mnt_opts = "-tmsdos";
-			fsname = "msdos";
+			lbl->mnt_opts = "-tmsdos";
+			lbl->fsname = "msdos";
 			break;
 #ifdef USE_SYSVBFS
 		case FS_SYSVBFS:
 			asprintf(&newfs, "/sbin/newfs_sysvbfs");
-			mnt_opts = "-tsysvbfs";
-			fsname = "sysvbfs";
+			lbl->mnt_opts = "-tsysvbfs";
+			lbl->fsname = "sysvbfs";
 			break;
 #endif
 #ifdef USE_EXT2FS
 		case FS_EX2FS:
 			asprintf(&newfs, "/sbin/newfs_ext2fs");
-			mnt_opts = "-text2fs";
-			fsname = "ext2fs";
+			lbl->mnt_opts = "-text2fs";
+			lbl->fsname = "ext2fs";
 			break;
 #endif
 		}
@@ -610,42 +701,43 @@ make_filesystems(void)
 			if (lbl->pi_fstype == FS_MSDOS) {
 			        /* newfs only if mount fails */
 			        if (run_program(RUN_SILENT | RUN_ERROR_OK,
-				    "mount -rt msdos /dev/%s%c /mnt2",
-				    diskdev, 'a' + ptn) != 0)
+				    "mount -rt msdos /dev/%s /mnt2", dev) != 0)
 					error = run_program(
 					    RUN_DISPLAY | RUN_PROGRESS,
-					    "%s /dev/r%s%c",
-					    newfs, diskdev, 'a' + ptn);
+					    "%s /dev/r%s",
+					    newfs, dev);
 				else {
-			        	run_program(RUN_SILENT | RUN_ERROR_OK,
+			        run_program(RUN_SILENT | RUN_ERROR_OK,
 					    "umount /mnt2");
 					error = 0;
 				}
 			} else
 #endif
 			error = run_program(RUN_DISPLAY | RUN_PROGRESS,
-			    "%s /dev/r%s%c", newfs, diskdev, 'a' + ptn);
+			    "%s /dev/r%s", newfs, dev);
 		} else {
 			/* We'd better check it isn't dirty */
-			error = fsck_preen(diskdev, ptn, fsname);
+			error = fsck_preen(pm->diskdev, ptn, lbl->fsname);
 		}
 		free(newfs);
 		if (error != 0)
 			return error;
 
+		lbl->pi_flags ^= PIF_NEWFS;
 		md_pre_mount();
 
-		if (lbl->pi_flags & PIF_MOUNT && mnt_opts != NULL) {
+		if (partman_go == 0 && lbl->pi_flags & PIF_MOUNT &&
+				lbl->mnt_opts != NULL) {
 			make_target_dir(lbl->pi_mount);
-			error = target_mount(mnt_opts, diskdev, ptn,
-					    lbl->pi_mount);
+			error = target_mount_do(lbl->mnt_opts, devdev, lbl->pi_mount);
 			if (error) {
-				msg_display(MSG_mountfail,
-					    diskdev, 'a' + ptn, lbl->pi_mount);
+				msg_display(MSG_mountfail, dev, ' ', lbl->pi_mount);
 				process_menu(MENU_ok, NULL);
 				return error;
 			}
 		}
+		free(devdev);
+		free(dev);
 	}
 	return 0;
 }
@@ -656,21 +748,24 @@ make_fstab(void)
 	FILE *f;
 	int i, swap_dev = -1;
 	const char *dump_dev;
+	char *dev = NULL;
+	pm_devs_t *pm_i, *pm_with_swap;
 
 	/* Create the fstab. */
 	make_target_dir("/etc");
 	f = target_fopen("/etc/fstab", "w");
-	if (logfp)
-		(void)fprintf(logfp,
-		    "Creating %s/etc/fstab.\n", target_prefix());
 	scripting_fprintf(NULL, "cat <<EOF >%s/etc/fstab\n", target_prefix());
 
+	if (logfp)
+		(void)fprintf(logfp,
+		    "Making %s/etc/fstab (%s).\n", target_prefix(), pm->diskdev);
+	
 	if (f == NULL) {
-#ifndef DEBUG
 		msg_display(MSG_createfstab);
 		if (logfp)
 			(void)fprintf(logfp, "Failed to make /etc/fstab!\n");
 		process_menu(MENU_ok, NULL);
+#ifndef DEBUG
 		return 1;
 #else
 		f = stdout;
@@ -678,90 +773,115 @@ make_fstab(void)
 	}
 
 	scripting_fprintf(f, "# NetBSD %s/etc/fstab\n# See /usr/share/examples/"
-		"fstab/ for more examples.\n", target_prefix());
-	for (i = 0; i < getmaxpartitions(); i++) {
-		const char *s = "";
-		const char *mp = bsdlabel[i].pi_mount;
-		const char *fstype = "ffs";
-		int fsck_pass = 0, dump_freq = 0;
-
-		if (!*mp) {
-			/*
-			 * No mount point specified, comment out line and
-			 * use /mnt as a placeholder for the mount point.
-			 */
-			s = "# ";
-			mp = "/mnt";
-		}
-
-		switch (bsdlabel[i].pi_fstype) {
-		case FS_UNUSED:
-			continue;
-		case FS_BSDLFS:
-			/* If there is no LFS, just comment it out. */
-			if (!check_lfs_progs())
+			"fstab/ for more examples.\n", target_prefix());
+	if (! partman_go) {
+		/* We want to process only one disk... */
+		pm_i = pm;
+		goto onlyonediskinfstab;
+	}
+	SLIST_FOREACH(pm_i, &pm_head, l) {
+		onlyonediskinfstab:
+		for (i = 0; i < getmaxpartitions(); i++) {
+			const char *s = "";
+			const char *mp = pm_i->bsdlabel[i].pi_mount;
+			const char *fstype = "ffs";
+			int fsck_pass = 0, dump_freq = 0;
+			
+			if (dev != NULL)
+				free(dev);
+			if (pm_i->isspecial)
+				asprintf(&dev, "%s", pm_i->diskdev);
+			else
+				asprintf(&dev, "%s%c", pm_i->diskdev, 'a' + i);
+			if (dev == NULL)
+				return (ENOMEM);
+
+			if (!*mp) {
+				/*
+				 * No mount point specified, comment out line and
+				 * use /mnt as a placeholder for the mount point.
+				 */
 				s = "# ";
-			fstype = "lfs";
-			/* XXX fsck_lfs considered harmfull */
-			fsck_pass = 0;
-			dump_freq = 1;
-			break;
-		case FS_BSDFFS:
-			fsck_pass = (strcmp(mp, "/") == 0) ? 1 : 2;
-			dump_freq = 1;
-			break;
-		case FS_MSDOS:
-			fstype = "msdos";
-			break;
-		case FS_SWAP:
-			if (swap_dev == -1) {
-				swap_dev = i;
-				dump_dev = ",dp";
-			} else {
-				dump_dev ="";
+				mp = "/mnt";
 			}
-			scripting_fprintf(f, "/dev/%s%c\t\tnone\tswap\tsw%s\t\t 0 0\n",
-				diskdev, 'a' + i, dump_dev);
-			continue;
+
+			switch (pm_i->bsdlabel[i].pi_fstype) {
+			case FS_UNUSED:
+				continue;
+			case FS_BSDLFS:
+				/* If there is no LFS, just comment it out. */
+				if (!check_lfs_progs())
+					s = "# ";
+				fstype = "lfs";
+				/* XXX fsck_lfs considered harmfull */
+				fsck_pass = 0;
+				dump_freq = 1;
+				break;
+			case FS_BSDFFS:
+				fsck_pass = (strcmp(mp, "/") == 0) ? 1 : 2;
+				dump_freq = 1;
+				break;
+			case FS_MSDOS:
+				fstype = "msdos";
+				break;
+			case FS_SWAP:
+				if (pm_i->isspecial)
+					continue;
+				if (swap_dev == -1) {
+					swap_dev = i;
+					dump_dev = ",dp";
+					pm_with_swap = pm_i;
+				} else {
+					dump_dev = "";
+				}
+				scripting_fprintf(f, "/dev/%s\t\tnone\tswap\tsw%s\t\t 0 0\n",
+					dev, dump_dev);
+				continue;
 #ifdef USE_SYSVBFS
-		case FS_SYSVBFS:
-			fstype = "sysvbfs";
-			make_target_dir("/stand");
-			break;
+			case FS_SYSVBFS:
+				fstype = "sysvbfs";
+				make_target_dir("/stand");
+				break;
 #endif
-		default:
-			fstype = "???";
-			s = "# ";
-			break;
+			default:
+				fstype = "???";
+				s = "# ";
+				break;
+			}
+			/* The code that remounts root rw doesn't check the partition */
+			if (strcmp(mp, "/") == 0 && !(pm_i->bsdlabel[i].pi_flags & PIF_MOUNT))
+				s = "# ";
+
+	 		scripting_fprintf(f,
+			  "%s/dev/%s\t\t%s\t%s\trw%s%s%s%s%s%s%s%s\t\t %d %d\n",
+			   s, dev, mp, fstype,
+			   pm_i->bsdlabel[i].pi_flags & PIF_LOG ? ",log" : "",
+			   pm_i->bsdlabel[i].pi_flags & PIF_MOUNT ? "" : ",noauto",
+			   pm_i->bsdlabel[i].pi_flags & PIF_ASYNC ? ",async" : "",
+			   pm_i->bsdlabel[i].pi_flags & PIF_NOATIME ? ",noatime" : "",
+			   pm_i->bsdlabel[i].pi_flags & PIF_NODEV ? ",nodev" : "",
+			   pm_i->bsdlabel[i].pi_flags & PIF_NODEVMTIME ? ",nodevmtime" : "",
+			   pm_i->bsdlabel[i].pi_flags & PIF_NOEXEC ? ",noexec" : "",
+			   pm_i->bsdlabel[i].pi_flags & PIF_NOSUID ? ",nosuid" : "",
+			   dump_freq, fsck_pass);
+	 		if (pm_i->isspecial)
+	 			/* Special device (such as dk*) have only one partition */
+	 			break;
 		}
-		/* The code that remounts root rw doesn't check the partition */
-		if (strcmp(mp, "/") == 0 && !(bsdlabel[i].pi_flags & PIF_MOUNT))
-			s = "# ";
-
- 		scripting_fprintf(f,
-		  "%s/dev/%s%c\t\t%s\t%s\trw%s%s%s%s%s%s%s%s\t\t %d %d\n",
-		   s, diskdev, 'a' + i, mp, fstype,
-		   bsdlabel[i].pi_flags & PIF_LOG ? ",log" : "",
-		   bsdlabel[i].pi_flags & PIF_MOUNT ? "" : ",noauto",
-		   bsdlabel[i].pi_flags & PIF_ASYNC ? ",async" : "",
-		   bsdlabel[i].pi_flags & PIF_NOATIME ? ",noatime" : "",
-		   bsdlabel[i].pi_flags & PIF_NODEV ? ",nodev" : "",
-		   bsdlabel[i].pi_flags & PIF_NODEVMTIME ? ",nodevmtime" : "",
-		   bsdlabel[i].pi_flags & PIF_NOEXEC ? ",noexec" : "",
-		   bsdlabel[i].pi_flags & PIF_NOSUID ? ",nosuid" : "",
-		   dump_freq, fsck_pass);
+		/* Simple install, only one disk */
+		if (!partman_go)
+			break;
 	}
-
 	if (tmp_ramdisk_size != 0) {
 #ifdef HAVE_TMPFS
 		scripting_fprintf(f, "tmpfs\t\t/tmp\ttmpfs\trw,-m=1777,-s=%"
 		    PRIi64 "\n",
 		    tmp_ramdisk_size * 512);
 #else
-		if (swap_dev != -1)
+		if (swap_dev != -1 && pm_with_swap != NULL)
 			scripting_fprintf(f, "/dev/%s%c\t\t/tmp\tmfs\trw,-s=%"
 			    PRIi64 "\n",
-			    diskdev, 'a' + swap_dev, tmp_ramdisk_size);
+			    pm_with_swap->diskdev, 'a' + swap_dev, tmp_ramdisk_size);
 		else
 			scripting_fprintf(f, "swap\t\t/tmp\tmfs\trw,-s=%"
 			    PRIi64 "\n",
@@ -781,10 +901,10 @@ make_fstab(void)
 
 	scripting_fprintf(NULL, "EOF\n");
 
-#ifndef DEBUG
+	if (dev != NULL)
+		free(dev);
 	fclose(f);
 	fflush(NULL);
-#endif
 	return 0;
 }
 
@@ -839,7 +959,7 @@ fsck_preen(const char *disk, int ptn, const char *fsname)
 	char *prog;
 	int error;
 
-	ptn += 'a';
+	ptn = (ptn < 0)? 0 : 'a' + ptn;
 	if (fsname == NULL)
 		return 0;
 	/* first, check if fsck program exists, if not, assume ok */
@@ -880,7 +1000,7 @@ fixsb(const char *prog, const char *disk, char ptn)
 	struct fs *fs = &sblk.fs;
 
 	snprintf(sblk.buf, sizeof(sblk.buf), "/dev/r%s%c",
-		disk, ptn == ' ' ? 0 : ptn);
+		disk, (ptn == ' ' || ptn < 0)? 0 : ptn);
 	fd = open(sblk.buf, O_RDONLY);
 	if (fd == -1)
 		return;
@@ -921,8 +1041,9 @@ static int
 mount_root(void)
 {
 	int	error;
+	int ptn = (pm->isspecial)? 0 - 'a' : pm->rootpart;
 
-	error = fsck_preen(diskdev, rootpart, "ffs");
+	error = fsck_preen(pm->diskdev, ptn, "ffs");
 	if (error != 0)
 		return error;
 
@@ -934,7 +1055,7 @@ mount_root(void)
 	 * XXX consider -o remount in case target root is
 	 * current root, still readonly from single-user?
 	 */
-	return target_mount("", diskdev, rootpart, "");
+	return target_mount("", pm->diskdev, ptn, "");
 }
 
 /* Get information on the file systems mounted from the root filesystem.
@@ -966,15 +1087,15 @@ mount_disks(void)
 	else {
 		error = mount_root();
 		if (error != 0 && error != EBUSY)
-			return 0;
+			return error;
 	}
 
 	/* Check the target /etc/fstab exists before trying to parse it. */
 	if (target_dir_exists_p("/etc") == 0 ||
 	    target_file_exists_p("/etc/fstab") == 0) {
-		msg_display(MSG_noetcfstab, diskdev);
+		msg_display(MSG_noetcfstab, pm->diskdev);
 		process_menu(MENU_ok, NULL);
-		return 0;
+		return -1;
 	}
 
 
@@ -982,9 +1103,9 @@ mount_disks(void)
 	fstabsize = target_collect_file(T_FILE, &fstab, "/etc/fstab");
 	if (fstabsize < 0) {
 		/* error ! */
-		msg_display(MSG_badetcfstab, diskdev);
+		msg_display(MSG_badetcfstab, pm->diskdev);
 		process_menu(MENU_ok, NULL);
-		return 0;
+		return -2;
 	}
 	error = walk(fstab, (size_t)fstabsize, fstabbuf, numfstabbuf);
 	free(fstab);
@@ -1000,7 +1121,7 @@ set_swap(const char *disk, partinfo *pp)
 	int rval;
 
 	if (pp == NULL)
-		pp = oldlabel;
+		pp = pm->oldlabel;
 
 	for (i = 0; i < MAXPARTITIONS; i++) {
 		if (pp[i].pi_fstype != FS_SWAP)
@@ -1076,11 +1197,11 @@ bootxx_name(void)
 	char *bootxx;
 
 	/* check we have boot code for the root partition type */
-	fstype = bsdlabel[rootpart].pi_fstype;
+	fstype = pm->bsdlabel[pm->rootpart].pi_fstype;
 	switch (fstype) {
 #if defined(BOOTXX_FFSV1) || defined(BOOTXX_FFSV2)
 	case FS_BSDFFS:
-		if (bsdlabel[rootpart].pi_flags & PIF_FFSv2) {
+		if (pm->bsdlabel[pm->rootpart].pi_flags & PIF_FFSv2) {
 #ifdef BOOTXX_FFSV2
 			bootxxname = BOOTXX_FFSV2;
 #else
@@ -1112,3 +1233,147 @@ bootxx_name(void)
 	return bootxx;
 }
 #endif
+
+static int
+get_fsid_by_gptuuid(const char *str)
+{
+	int i;
+	uuid_t uuid;
+	uint32_t status;
+
+	uuid_from_string(str, &uuid, &status);
+	if (status == uuid_s_ok) {
+		for (i = 0; gpt_filesystems[i].id > 0; i++)
+			if (uuid_equal(&uuid, &(gpt_filesystems[i].uuid), NULL))
+				return gpt_filesystems[i].id;
+	}
+	return FS_OTHER;
+}
+
+const char *
+get_gptfs_by_id(int filesystem)
+{
+	int i;
+	for (i = 0; gpt_filesystems[i].id > 0; i++)
+		if (filesystem == gpt_filesystems[i].id)
+			return gpt_filesystems[i].name;
+	return NULL;
+}
+
+/* from dkctl.c */
+static int
+get_dkwedges_sort(const void *a, const void *b)
+{
+	const struct dkwedge_info *dkwa = a, *dkwb = b;
+	const daddr_t oa = dkwa->dkw_offset, ob = dkwb->dkw_offset;
+	return (oa < ob) ? -1 : (oa > ob) ? 1 : 0;
+}
+
+int
+get_dkwedges(struct dkwedge_info **dkw, const char *diskdev)
+{
+	int fd;
+	char buf[STRSIZE];
+	size_t bufsize;
+	struct dkwedge_list dkwl;
+
+	*dkw = NULL;
+	dkwl.dkwl_buf = *dkw;
+	dkwl.dkwl_bufsize = 0;
+	fd = opendisk(diskdev, O_RDONLY, buf, STRSIZE, 0);
+	if (fd < 0)
+		return -1;
+
+	for (;;) {
+		if (ioctl(fd, DIOCLWEDGES, &dkwl) == -1)
+			return -2;
+		if (dkwl.dkwl_nwedges == dkwl.dkwl_ncopied)
+			break;
+		bufsize = dkwl.dkwl_nwedges * sizeof(**dkw);
+		if (dkwl.dkwl_bufsize < bufsize) {
+			*dkw = realloc(dkwl.dkwl_buf, bufsize);
+			if (*dkw == NULL)
+				return -3;
+			dkwl.dkwl_buf = *dkw;
+			dkwl.dkwl_bufsize = bufsize;
+		}
+	}
+
+	if (dkwl.dkwl_nwedges > 0)
+		qsort(*dkw, dkwl.dkwl_nwedges, sizeof(**dkw), get_dkwedges_sort);
+
+	close(fd);
+	return dkwl.dkwl_nwedges;
+}
+
+/* XXX: rewrite */
+static int
+incoregpt(pm_devs_t *pm_cur, partinfo *lp)
+{
+	int i, num;
+	uint32_t p_start, p_size, p_num;
+	char *textbuf, *t, *tt, p_type[STRSIZE];
+	struct dkwedge_info *dkw;
+
+	num = get_dkwedges(&dkw, pm_cur->diskdev);
+	if (dkw != NULL) {
+		for (i = 0; i < num && i < MAX_WEDGES; i++)
+			run_program(RUN_SILENT, "dkctl %s delwedge %s",
+				pm_cur->diskdev, dkw[i].dkw_devname);
+		free (dkw);
+	}
+
+	if (collect(T_OUTPUT, &textbuf, "gpt show -u %s 2>/dev/null", pm_cur->diskdev) < 1)
+		return -1;
+
+	(void)strtok(textbuf, "\n"); /* ignore first line */
+	while ((t = strtok(NULL, "\n")) != NULL) {
+		i = 0; p_start = -1; p_size = -1; p_num = -1; strcpy(p_type, ""); /* init */
+		while ((tt = strsep(&t, " \t")) != NULL) {
+			if (strlen(tt) < 1)
+				continue;
+			if (i == 0)
+				p_start = atoi(tt);
+			if (i == 1)
+				p_size = atoi(tt);
+			if (i == 2)
+				p_num = atoi(tt);
+			if (i > 2 || (i == 2 && p_num == 0))
+				if (
+					strcmp(tt, "GPT") &&
+					strcmp(tt, "part") &&
+					strcmp(tt, "-")
+					)
+						strncat(p_type, tt, STRSIZE);
+			i++;
+		}
+		if (p_start < 1 || p_size < 1)
+			continue;
+		else if (! strcmp(p_type, "Pritable"))
+			pm_cur->ptstart = p_start + p_size;
+		else if (! strcmp(p_type, "Sectable"))
+			pm_cur->ptsize = p_start - pm_cur->ptstart - 1;
+		else if (p_num < 1 && strlen(p_type) > 0)
+			/* Utilitary entry (PMBR, etc) */
+			continue;
+		else if (p_num < 1) {
+			/* Free space */
+			continue;
+		} else {
+			/* Usual partition */
+			lp[p_num].pi_size = p_size;
+			lp[p_num].pi_offset = p_start;
+			lp[p_num].pi_fstype = get_fsid_by_gptuuid(p_type);
+		}
+	}
+	free(textbuf);
+
+	return 0;
+}
+
+static int
+is_gpt(const char *dev)
+{
+	return ! run_program(RUN_SILENT | RUN_ERROR_OK,
+		"sh -c 'gpt show %s |grep -e Pri\\ GPT\\ table'", dev);
+}
diff --git a/distrib/utils/sysinst/install.c b/distrib/utils/sysinst/install.c
index d00a8e9..7e6a440 100644
--- a/distrib/utils/sysinst/install.c
+++ b/distrib/utils/sysinst/install.c
@@ -45,71 +45,73 @@
 void
 do_install(void)
 {
+	int find_disks_ret;
+	int retcode = 0;
+	partman_go = -1;
 
+#ifndef DEBUG
 	msg_display(MSG_installusure);
 	process_menu(MENU_noyes, NULL);
 	if (!yesno)
 		return;
+#endif
 
 	get_ramsize();
 
-	if (find_disks(msg_string(MSG_install)) < 0)
+	/* Create and mount partitions */
+	find_disks_ret = find_disks(msg_string(MSG_install));
+	if (partman_go == 1) {
+		if (partman() < 0) {
+			msg_display(MSG_abort);
+			process_menu(MENU_ok, NULL);
+			return;
+		}
+	} else if (find_disks_ret < 0)
 		return;
-	clear();
-	refresh();
-
-	if (check_swap(diskdev, 0) > 0) {
-		msg_display(MSG_swapactive);
-		process_menu(MENU_ok, NULL);
-		if (check_swap(diskdev, 1) < 0) {
-			msg_display(MSG_swapdelfailed);
+	else {
+	/* Classical partitioning wizard */
+		partman_go = 0;
+		clear();
+		refresh();
+
+		if (check_swap(pm->diskdev, 0) > 0) {
+			msg_display(MSG_swapactive);
 			process_menu(MENU_ok, NULL);
-			if (!debug)
-				return;
+			if (check_swap(pm->diskdev, 1) < 0) {
+				msg_display(MSG_swapdelfailed);
+				process_menu(MENU_ok, NULL);
+				if (!debug)
+					return;
+			}
 		}
-	}
-
-	process_menu(MENU_distset, NULL);
 
-	if (!md_get_info()) {
-		msg_display(MSG_abort);
-		process_menu(MENU_ok, NULL);
-		return;
-	}
+		if (!md_get_info() || md_make_bsd_partitions() == 0) {
+			msg_display(MSG_abort);
+			process_menu(MENU_ok, NULL);
+			return;
+		}
 
-	if (md_make_bsd_partitions() == 0) {
-		msg_display(MSG_abort);
-		process_menu(MENU_ok, NULL);
-		return;
+		/* Last chance ... do you really want to do this? */
+		clear();
+		refresh();
+		msg_display(MSG_lastchance, pm->diskdev);
+		process_menu(MENU_noyes, NULL);
+		if (!yesno)
+			return;
+
+		if (md_pre_disklabel() != 0 ||
+			write_disklabel() != 0 ||
+			md_post_disklabel() != 0 ||
+			make_filesystems() ||
+			make_fstab() != 0 ||
+			md_post_newfs() != 0)
+			return;
 	}
 
-	/* Last chance ... do you really want to do this? */
-	clear();
-	refresh();
-	msg_display(MSG_lastchance, diskdev);
-	process_menu(MENU_noyes, NULL);
-	if (!yesno)
-		return;
-
-	if (md_pre_disklabel() != 0)
-		return;
-
-	if (write_disklabel() != 0)
-		return;
-
-	if (md_post_disklabel() != 0)
-		return;
-
-	if (make_filesystems())
-		return;
-
-	if (make_fstab() != 0)
-		return;
-
-	if (md_post_newfs() != 0)
-		return;
-
 	/* Unpack the distribution. */
+	process_menu(MENU_distset, &retcode);
+	if (retcode == 0)
+		return;
 	if (get_and_unpack_sets(0, MSG_disksetupdone,
 	    MSG_extractcomplete, MSG_abortinst) != 0)
 		return;
diff --git a/distrib/utils/sysinst/label.c b/distrib/utils/sysinst/label.c
index f6d96ae..f7f7506 100644
--- a/distrib/utils/sysinst/label.c
+++ b/distrib/utils/sysinst/label.c
@@ -141,6 +141,17 @@ checklabel(partinfo *lp, int nparts, int rawpart, int bsdpart,
 	return (0);
 }
 
+int
+checkoverlap(partinfo *lp, int nparts, int rawpart, int bsdpart)
+{
+	int i, j;
+	if (checklabel(lp, nparts, rawpart, bsdpart, &i, &j)) {
+		msg_display(MSG_partitions_overlap,'a'+i,'a'+j);
+		return 1;
+	}
+	return 0;
+}
+
 static int
 check_one_root(partinfo *lp, int nparts)
 {
@@ -161,7 +172,7 @@ check_one_root(partinfo *lp, int nparts)
 			return 0;
 		foundroot = 1;
 		/* Save partition number, a few things need to know it */
-		rootpart = part;
+		pm->rootpart = part;
 	}
 	return foundroot;
 }
@@ -193,7 +204,7 @@ edit_fs_size(menudesc *m, void *arg)
 
 	size = getpartsize(p->pi_offset, p->pi_size);
 	if (size == ~0u)
-		size = dlsize - p->pi_offset;
+		size = pm->dlsize - p->pi_offset;
 	p->pi_size = size;
 	if (size == 0) {
 		p->pi_offset = 0;
@@ -343,7 +354,7 @@ static void set_ptn_header(menudesc *m, void *arg);
 static void set_ptn_label(menudesc *m, int opt, void *arg);
 int all_fstype_menu = -1;
 
-static int
+int
 edit_ptn(menudesc *menu, void *arg)
 {
 	static menu_ent fs_fields[] = {
@@ -398,7 +409,7 @@ edit_ptn(menudesc *menu, void *arg)
 			get_fstype, NULL, NULL, NULL, MSG_unchanged);
 	}
 
-	p = bsdlabel + menu->cursel;
+	p = pm->bsdlabel + menu->cursel;
 	p->pi_flags &= ~PIF_RESET;
 	p_save = *p;
 	for (;;) {
@@ -419,7 +430,7 @@ set_ptn_header(menudesc *m, void *arg)
 	int t;
 
 	msg_clear();
-	msg_table_add(MSG_edfspart, 'a' + (p - bsdlabel));
+	msg_table_add(MSG_edfspart, 'a' + (p - pm->bsdlabel));
 
 	/* Determine which of the properties can be changed */
 	for (i = PTN_MENU_START; i <= PTN_MENU_MOUNTPT; i++) {
@@ -461,10 +472,10 @@ set_ptn_header(menudesc *m, void *arg)
 static void
 disp_sector_count(menudesc *m, msg fmt, uint s)
 {
-	uint ms = MEG / sectorsize;
+	uint ms = MEG / pm->sectorsize;
 
 	wprintw(m->mw, msg_string(fmt),
-		s / ms, s / dlcylsize, s % dlcylsize ? '*' : ' ', s );
+		s / ms, s / pm->dlcylsize, s % pm->dlcylsize ? '*' : ' ', s );
 }
 
 static void
@@ -575,7 +586,7 @@ set_label_texts(menudesc *menu, void *arg)
 			m->opt_flags = OPT_IGNORE;
 		} else {
 			m->opt_flags = 0;
-			if (bsdlabel[ptn].pi_fstype == FS_UNUSED)
+			if (pm->bsdlabel[ptn].pi_fstype == FS_UNUSED)
 				continue;
 		}
 		show_unused_ptn = ptn + 2;
@@ -629,24 +640,19 @@ edit_and_check_label(partinfo *lp, int nparts, int rawpart, int bsdpart)
 		return 1;
 
 	pi.flags = 0;
-	current_cylsize = dlcylsize;
+	pm->current_cylsize = pm->dlcylsize;
 
 	for (;;) {
-		int i, j;
-
 		/* first give the user the option to edit the label... */
 		process_menu(menu_no, &pi);
 
 		/* User thinks the label is OK. */
 		/* check we have a single root fs */
-		if (check_one_root(lp, nparts) == 0)
+		if (check_one_root(lp, nparts) == 0 && partman_go == 0)
 			msg_display(MSG_must_be_one_root);
 		else 
 			/* Check for overlaps */
-			if (checklabel(lp, nparts, rawpart, bsdpart, &i, &j))
-				/* partitions overlap */
-				msg_display(MSG_partitions_overlap,'a'+i,'a'+j);
-			else
+			if (checkoverlap(lp, nparts, rawpart, bsdpart) == 0)
 				return 1;
 
 		/*XXX ???*/
@@ -686,7 +692,7 @@ incorelabel(const char *dkname, partinfo *lp)
 	 * than d_diskname.  Who knows why, but pull the value back here.
 	 */
 	if (lab.d_typename[0] != 0 && strcmp(lab.d_typename, "unknown") != 0)
-		strlcpy(bsddiskname, lab.d_typename, sizeof bsddiskname);
+		strlcpy(pm->bsddiskname, lab.d_typename, sizeof pm->bsddiskname);
 
 	fd = opendisk(dkname, O_RDONLY, buf, sizeof buf, 0);
 	pp = &lab.d_partitions[0];
@@ -806,10 +812,10 @@ getpartoff(uint32_t defpartstart)
 		if (isize[1] == '\0' && isize[0] >= 'a' &&
 		    isize[0] <= maxpartc) {
 			partn = isize[0] - 'a';
-			i = bsdlabel[partn].pi_size + bsdlabel[partn].pi_offset;
+			i = pm->bsdlabel[partn].pi_size + pm->bsdlabel[partn].pi_offset;
 			localsizemult = 1;
 		} else if (atoi(isize) == -1) {
-			i = ptstart;
+			i = pm->ptstart;
 			localsizemult = 1;
 		} else {
 			if (atofsb(isize, &i, &localsizemult)) {
@@ -818,13 +824,13 @@ getpartoff(uint32_t defpartstart)
 			}
 		}
 		/* round to cylinder size if localsizemult != 1 */
-		i = NUMSEC(i/localsizemult, localsizemult, dlcylsize);
+		i = NUMSEC(i/localsizemult, localsizemult, pm->dlcylsize);
 		/* Adjust to start of slice if needed */
-		if ((i < ptstart && (ptstart - i) < localsizemult) ||
-		    (i > ptstart && (i - ptstart) < localsizemult)) {
-			i = ptstart;
+		if ((i < pm->ptstart && (pm->ptstart - i) < localsizemult) ||
+		    (i > pm->ptstart && (i - pm->ptstart) < localsizemult)) {
+			i = pm->ptstart;
 		}
-		if (i <= dlsize)
+		if (i <= pm->dlsize)
 			break;
 		errmsg = msg_string(MSG_startoutsidedisk);
 	}
@@ -839,7 +845,7 @@ getpartsize(uint32_t partstart, uint32_t defpartsize)
 	char dsize[20], isize[20], maxpartc;
 	const char *errmsg = "\n";
 	uint32_t i, partend, localsizemult;
-	uint32_t fsptend = ptstart + ptsize;
+	uint32_t fsptend = pm->ptstart + pm->ptsize;
 	int partn;
 
 	maxpartc = 'a' + getmaxpartitions() - 1;
@@ -853,7 +859,7 @@ getpartsize(uint32_t partstart, uint32_t defpartsize)
 		if (isize[1] == '\0' && isize[0] >= 'a' &&
 		    isize[0] <= maxpartc) {
 			partn = isize[0] - 'a';
-			i = bsdlabel[partn].pi_offset - partstart;
+			i = pm->bsdlabel[partn].pi_offset - partstart;
 			localsizemult = 1;
 		} else if (atoi(isize) == -1) {
 			i = fsptend - partstart;
@@ -869,17 +875,17 @@ getpartsize(uint32_t partstart, uint32_t defpartsize)
 		 * is not 1 sector
 		 */
 		partend = NUMSEC((partstart + i) / localsizemult,
-		    localsizemult, dlcylsize);
+		    localsizemult, pm->dlcylsize);
 		/* Align to end-of-disk or end-of-slice if close enough */
-		if (partend > (dlsize - localsizemult)
-		    && partend < (dlsize + localsizemult))
-			partend = dlsize;
+		if (partend > (pm->dlsize - localsizemult)
+		    && partend < (pm->dlsize + localsizemult))
+			partend = pm->dlsize;
 		if (partend > (fsptend - localsizemult)
 		    && partend < (fsptend + localsizemult))
 			partend = fsptend;
 		/* sanity checks */
-		if (partend > dlsize) {
-			partend = dlsize;
+		if (partend > pm->dlsize) {
+			partend = pm->dlsize;
 			msg_prompt_win(MSG_endoutsidedisk, -1, 13, 70, 6,
 			    NULL, isize, 1,
 			    (partend - partstart) / sizemult, multname);
@@ -922,15 +928,15 @@ atofsb(const char *str, uint32_t *p_val, uint32_t *localsizemult)
 		}
 		if (str[i] == 'G' || str[i] == 'g') {
 			val *= 1024;
-			*localsizemult = MEG / sectorsize;
+			*localsizemult = MEG / pm->sectorsize;
 			break;
 		}
 		if (str[i] == 'M' || str[i] == 'm') {
-			*localsizemult = MEG / sectorsize;
+			*localsizemult = MEG / pm->sectorsize;
 			break;
 		}
 		if (str[i] == 'c') {
-			*localsizemult = dlcylsize;
+			*localsizemult = pm->dlcylsize;
 			break;
 		}
 		if (str[i] == 's') {
diff --git a/distrib/utils/sysinst/main.c b/distrib/utils/sysinst/main.c
index 65b50d0..d808a86 100644
--- a/distrib/utils/sysinst/main.c
+++ b/distrib/utils/sysinst/main.c
@@ -67,8 +67,17 @@ FILE *script;			/* script file */
 extern int log_flip(void);
 #endif
 
+/* Definion for colors */
+
+struct {
+	unsigned int bg;
+	unsigned int fg;
+} clr_arg;
+
 /* String defaults and stuff for processing the -f file argument. */
 
+static char bsddiskname[DISKNAME_SIZE]; /* default name for fist selected disk */
+
 struct f_arg {
 	const char *name;
 	const char *dflt;
@@ -119,24 +128,35 @@ static void
 init(void)
 {
 	const struct f_arg *arg;
-
+	
 	sizemult = 1;
-	disktype = "unknown";
+	multname = msg_string(MSG_secname);
 	tmp_ramdisk_size = 0;
-	doessf = "";
 	clean_xfer_dir = 0;
 	mnt2_mounted = 0;
 	fd_type = "msdos";
+	layoutkind = LY_SETNEW;
+
+	pm_head = (struct pm_head_t) SLIST_HEAD_INITIALIZER(pm_head);
+	SLIST_INIT(&pm_head);
+	pm_new = malloc (sizeof (pm_devs_t));
+	memset(pm_new, 0, sizeof *pm_new);
 
 	for (arg = fflagopts; arg->name != NULL; arg++)
 		strlcpy(arg->var, arg->dflt, arg->size);
+	strlcpy(pm_new->bsddiskname, bsddiskname, sizeof pm_new->bsddiskname);
 	pkg.xfer_type = pkgsrc.xfer_type = "http";
+	
+	clr_arg.bg=COLOR_BLUE;
+	clr_arg.fg=COLOR_WHITE;
+#ifdef DEBUG
+	clr_arg.bg=COLOR_RED;
+#endif
 }
 
 int
 main(int argc, char **argv)
 {
-	WINDOW *win;
 	int ch;
 
 	init();
@@ -151,7 +171,7 @@ main(int argc, char **argv)
 	}
 
 	/* argv processing */
-	while ((ch = getopt(argc, argv, "Dr:f:")) != -1)
+	while ((ch = getopt(argc, argv, "Dr:f:C:p")) != -1)
 		switch(ch) {
 		case 'D':	/* set to get past certain errors in testing */
 			debug = 1;
@@ -164,6 +184,14 @@ main(int argc, char **argv)
 			/* Definition file to read. */
 			process_f_flag(optarg);
 			break;
+		case 'C':
+			/* Define colors */
+			sscanf(optarg, "%u:%u", &clr_arg.bg, &clr_arg.fg);
+			break;
+		case 'p':
+			/* Partition tool */
+			partman_go = 1;
+			break;
 		case '?':
 		default:
 			usage();
@@ -181,21 +209,17 @@ main(int argc, char **argv)
 	 * Put 'messages' in a window that has a one-character border
 	 * on the real screen.
 	 */
-	win = newwin(getmaxy(stdscr) - 2, getmaxx(stdscr) - 2, 1, 1);
-	if (win == NULL) {
+	mainwin = newwin(getmaxy(stdscr) - 2, getmaxx(stdscr) - 2, 1, 1);
+	if (mainwin == NULL) {
 		(void)fprintf(stderr,
 			 "sysinst: screen too small\n");
 		exit(1);
 	}
 	if (has_colors()) {
-		/*
-		 * XXX This color trick should be done so much better,
-		 * but is it worth it?
-		 */
-		wbkgd(win, COLOR_PAIR(1));
-		wattrset(win, COLOR_PAIR(1));
+		start_color();
+		do_coloring(clr_arg.fg,clr_arg.bg);
 	}
-	msg_window(win);
+	msg_window(mainwin);
 
 	/* Watch for signals and clean up */
 	(void)atexit(cleanup);
@@ -214,7 +238,10 @@ main(int argc, char **argv)
 	get_kb_encoding();
 
 	/* Menu processing */
-	process_menu(MENU_netbsd, NULL);
+	if (partman_go)
+		partman();
+	else
+		process_menu(MENU_netbsd, NULL);
 
 	exit_cleanly = 1;
 	return 0;
@@ -331,6 +358,13 @@ select_language(void)
 void
 toplevel(void)
 {
+	/*
+	 * Undo any stateful side-effects of previous menu choices.
+	 * XXX must be idempotent, since we get run each time the main
+	 *     menu is displayed.
+	 */
+	chdir(getenv("HOME"));
+	unwind_mounts();
 
 	/* Display banner message in (english, francais, deutsch..) */
 	msg_display(MSG_hello);
@@ -338,14 +372,6 @@ toplevel(void)
 	if (md_may_remove_boot_medium())
 		msg_display_add(MSG_md_may_remove_boot_medium);
 	msg_display_add(MSG_thanks);
-
-	/*
-	 * Undo any stateful side-effects of previous menu choices.
-	 * XXX must be idempotent, since we get run each time the main
-	 *     menu is displayed.
-	 */
-	unwind_mounts();
-	/* ... */
 }
 
 
@@ -473,6 +499,7 @@ process_f_flag(char *f_name)
 			break;
 		}
 	}
+	strlcpy(pm_new->bsddiskname, bsddiskname, sizeof pm_new->bsddiskname);
 
 	fclose(fp);
 }
diff --git a/distrib/utils/sysinst/mbr.c b/distrib/utils/sysinst/mbr.c
index 40202d9..d93ef25 100644
--- a/distrib/utils/sysinst/mbr.c
+++ b/distrib/utils/sysinst/mbr.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: mbr.c,v 1.90 2012/04/07 03:08:33 tsutsui Exp $ */
+/*	$NetBSD: mbr.c,v 1.91 2012/05/26 05:09:59 tsutsui Exp $ */
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -196,8 +196,8 @@ set_bios_geom_with_mbr_guess(void)
 	int cyl, head;
 	daddr_t sec;
 
-	read_mbr(diskdev, &mbr);
-	msg_display(MSG_nobiosgeom, dlcyl, dlhead, dlsec);
+	read_mbr(pm->diskdev, &mbr);
+	msg_display(MSG_nobiosgeom, pm->dlcyl, pm->dlhead, pm->dlsec);
 	if (guess_biosgeom_from_mbr(&mbr, &cyl, &head, &sec) >= 0)
 		msg_display_add(MSG_biosguess, cyl, head, sec);
 	set_bios_geom(cyl, head, sec);
@@ -227,8 +227,8 @@ set_bios_geom(int cyl, int head, int sec)
 		bhead = atoi(res);
 	} while (bhead <= 0 || bhead > 256);
 
-	bcyl = dlsize / bsec / bhead;
-	if (dlsize != bcyl * bsec * bhead)
+	bcyl = pm->dlsize / bsec / bhead;
+	if (pm->dlsize != bcyl * bsec * bhead)
 		bcyl++;
 }
 
@@ -237,7 +237,7 @@ void
 disp_cur_geom(void)
 {
 
-	msg_display_add(MSG_realgeom, dlcyl, dlhead, dlsec);
+	msg_display_add(MSG_realgeom, pm->dlcyl, pm->dlhead, pm->dlsec);
 	msg_display_add(MSG_biosgeom, bcyl, bhead, bsec);
 }
 #endif
@@ -267,7 +267,7 @@ remove_old_partitions(uint start, int64_t size)
 	if (end == 0)
 		return;
 
-	for (p = oldlabel; p < oldlabel + nelem(oldlabel); p++) {
+	for (p = pm->oldlabel; p < pm->oldlabel + nelem(pm->oldlabel); p++) {
 		if (p->pi_offset >= end || p->pi_offset + p->pi_size <= start)
 			continue;
 		memset(p, 0, sizeof *p);
@@ -282,7 +282,7 @@ find_mbr_space(struct mbr_sector *mbrs, uint *start, uint *size, uint from, int
 	uint s, e;
 
     check_again:
-	sz = dlsize - from;
+	sz = pm->dlsize - from;
 	for (i = 0; i < MBR_PART_COUNT; i++) {
 		if (i == ignore)
 			continue;
@@ -1174,7 +1174,7 @@ set_mbr_header(menudesc *m, void *arg)
 
 	msg_display(MSG_editparttable);
 
-	msg_table_add(MSG_part_header, (unsigned long)(dlsize/sizemult),
+	msg_table_add(MSG_part_header, (unsigned long)(pm->dlsize/sizemult),
 	    multname, multname, multname, multname);
 
 	if (num_opts == 0) {
@@ -1242,12 +1242,12 @@ mbr_use_wholedisk(mbr_info_t *mbri)
 	memset(&mbri->mbrb, 0, sizeof mbri->mbrb);
 #endif
 	part[0].mbrp_type = MBR_PTYPE_NETBSD;
-	part[0].mbrp_size = dlsize - ptn_0_offset;
+	part[0].mbrp_size = pm->dlsize - ptn_0_offset;
 	part[0].mbrp_start = ptn_0_offset;
 	part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
 
-	ptstart = ptn_0_offset;
-	ptsize = dlsize - ptn_0_offset;
+	pm->ptstart = ptn_0_offset;
+	pm->ptsize = pm->dlsize - ptn_0_offset;
 	return 1;
 }
 
@@ -1271,8 +1271,13 @@ edit_mbr(mbr_info_t *mbri)
 	/* Ask full/part */
 
 	part = &mbrs->mbr_parts[0];
-	msg_display(MSG_fullpart, diskdev);
-	process_menu(MENU_fullpart, &usefull);
+	get_ptn_alignment(part);  /* update ptn_alignment */
+	if (partman_go)
+		usefull = 0;
+	else {
+		msg_display(MSG_fullpart, pm->diskdev);
+		process_menu(MENU_fullpart, &usefull);
+	}
 
 	/* DOS fdisk label checking and value setting. */
 	if (usefull) {
@@ -1309,11 +1314,11 @@ edit_mbr(mbr_info_t *mbri)
 
 	/* Default to MB, and use bios geometry for cylinder size */
 	set_sizemultname_meg();
-	current_cylsize = bhead * bsec;
+	pm->current_cylsize = bhead * bsec;
 
 	for (;;) {
-		ptstart = 0;
-		ptsize = 0;
+		pm->ptstart = 0;
+		pm->ptsize = 0;
 		process_menu(mbr_menu, mbri);
 
 		activepart = 0;
@@ -1328,8 +1333,8 @@ edit_mbr(mbr_info_t *mbri)
 					continue;
 				start = ext->sector + part->mbrp_start;
 				if (start == mbri->install) {
-					ptstart = mbri->install;
-					ptsize = part->mbrp_size;
+					pm->ptstart = mbri->install;
+					pm->ptsize = part->mbrp_size;
 				}
 				if (bsdstart != 0)
 					bsdstart = ~0;
@@ -1341,12 +1346,12 @@ edit_mbr(mbr_info_t *mbri)
 		}
 
 		/* Install in only netbsd partition if none tagged */
-		if (ptstart == 0 && bsdstart != ~0u) {
-			ptstart = bsdstart;
-			ptsize = bsdsize;
+		if (pm->ptstart == 0 && bsdstart != ~0u) {
+			pm->ptstart = bsdstart;
+			pm->ptsize = bsdsize;
 		}
 
-		if (ptstart == 0) {
+		if (pm->ptstart == 0) {
 			if (bsdstart == 0)
 				msg_display(MSG_nobsdpart);
 			else
@@ -1454,10 +1459,10 @@ read_mbr(const char *disk, mbr_info_t *mbri)
 	 * partition headers we might have to produce.
 	 */
 	if (bsec == 0)
-		bsec = dlsec;
+		bsec = pm->dlsec;
 	ptn_0_offset = bsec;
 	/* use 1MB default offset on large disks as fdisk(8) */
-	if (dlsize > 2048 * 1024 * 128)
+	if (pm->dlsize > 2048 * 1024 * 128)
 		ptn_0_offset = 2048;
 
 	memset(mbri, 0, sizeof *mbri);
@@ -1477,7 +1482,7 @@ read_mbr(const char *disk, mbr_info_t *mbri)
 
 		mbrp = &mbrs->mbr_parts[0];
 		if (ext_base == 0) {
-			get_ptn_alignment(mbrp);
+			get_ptn_alignment(mbrp);  /* get ptn_0_offset */
 		} else {
 			/* sanity check extended chain */
 			if (MBR_IS_EXTENDED(mbrp[0].mbrp_type))
@@ -1761,13 +1766,13 @@ guess_biosgeom_from_mbr(mbr_info_t *mbri, int *cyl, int *head, daddr_t *sec)
 	 * the invalid physical one.
 	 */
 
-	xcylinders = dlcyl;
-	xheads = dlhead;
-	xsectors = dlsec;
+	xcylinders = pm->dlcyl;
+	xheads = pm->dlhead;
+	xsectors = pm->dlsec;
 	if (xcylinders > MAXCYL || xheads > MAXHEAD || xsectors > MAXSECTOR) {
 		xsectors = MAXSECTOR;
 		xheads = MAXHEAD;
-		xcylinders = dlsize / (MAXSECTOR * MAXHEAD);
+		xcylinders = pm->dlsize / (MAXSECTOR * MAXHEAD);
 		if (xcylinders > MAXCYL)
 			xcylinders = MAXCYL;
 	}
@@ -1805,8 +1810,8 @@ guess_biosgeom_from_mbr(mbr_info_t *mbri, int *cyl, int *head, daddr_t *sec)
 	 * Estimate the number of cylinders.
 	 * XXX relies on get_disks having been called.
 	 */
-	xcylinders = dlsize / xheads / xsectors;
-	if (dlsize != xcylinders * xheads * xsectors)
+	xcylinders = pm->dlsize / xheads / xsectors;
+	if (pm->dlsize != xcylinders * xheads * xsectors)
 		xcylinders++;
 
 	/*
@@ -1889,7 +1894,7 @@ get_ptn_alignment(struct mbr_partition *mbrp0)
 		}
 	} else {
 		/* Use 1MB offset for large (>128GB) disks */
-		if (dlsize > 2048 * 1024 * 128)
+		if (pm->dlsize > 2048 * 1024 * 128)
 			ptn_alignment = 2048;
 			ptn_0_offset = 2048;
 	}
diff --git a/distrib/utils/sysinst/menus.mi b/distrib/utils/sysinst/menus.mi
index 3aadc30..d939153 100644
--- a/distrib/utils/sysinst/menus.mi
+++ b/distrib/utils/sysinst/menus.mi
@@ -162,10 +162,10 @@ menu netbsd, title MSG_NetBSD_VERSION_Install_System, y=-1,
 	option MSG_Reboot_the_computer, exit,
 		action (endwin) { system("/sbin/reboot -q"); };
 	option MSG_Utility_menu, sub menu utility;
-	option "Config menu", action { do_configmenu(); };
+	option MSG_Config_menu, action { do_configmenu(); };
 
 menu utility, title MSG_NetBSD_VERSION_Utilities, exit,
-		exitstring MSG_exit_utility_menu;
+		exitstring MSG_exit_menu_generic;
 	display action  { toplevel(); };
 	option MSG_Run_bin_sh,
 		action (endwin) { system("/bin/sh"); };
@@ -174,15 +174,23 @@ menu utility, title MSG_NetBSD_VERSION_Utilities, exit,
 	option MSG_Configure_network,
 		action {
 			extern int network_up;
-
 			network_up = 0;
 			config_network();
 		};
-/*	option MSG_Partition a disk; XXX add later.  */
+	option MSG_Partition_a_disk, action { partman_go = 1; partman(); };
 	option MSG_Logging_functions, action { do_logging(); };
+	option MSG_Color_scheme, sub menu colors;
 	option MSG_Halt_the_system, exit,
 		action (endwin) { system("/sbin/halt -q"); };
 
+menu colors, title MSG_Color_scheme, exit,
+		exitstring MSG_exit_menu_generic;
+	option MSG_White_on_black, action { do_coloring(COLOR_WHITE,COLOR_BLACK); };
+	option MSG_Black_on_white, action { do_coloring(COLOR_BLACK,COLOR_WHITE); };
+	option MSG_White_on_blue,  action { do_coloring(COLOR_WHITE,COLOR_BLUE); };
+	option MSG_Green_on_black, action { do_coloring(COLOR_GREEN,COLOR_BLACK); };
+
+
 menu yesno, y=-10;
 	display action { menu->title = arg ? arg : MSG_yes_or_no; };
 	option MSG_Yes, exit, action  {yesno = 1;};
@@ -198,22 +206,22 @@ menu ok, no shortcut, y=-10;
 	option MSG_Hit_enter_to_continue, exit;
 
 menu layout, sub menu, y=-1, title  MSG_Choose_your_installation;
-	option MSG_Set_Sizes, 	  exit, action { layoutkind = 1; };
-	option MSG_Use_Existing,  exit, action { layoutkind = 4; };
+	option MSG_Set_Sizes, 	  exit, action { layoutkind = LY_SETNEW; };
+	option MSG_Use_Existing,  exit, action { layoutkind = LY_USEEXIST; };
 
 menu sizechoice, sub menu, y=0, title MSG_Choose_your_size_specifier;
 	display action {
-		if (sizemult == current_cylsize)
+		if (sizemult == pm->current_cylsize)
 			menu->cursel = 1;
 		else if (sizemult == 1)
 			menu->cursel = 2;
 		};
 	option MSG_Megabytes, exit, action 
-		{ sizemult = MEG / sectorsize;
+		{ sizemult = MEG / pm->sectorsize;
 		  multname = msg_string(MSG_megname);
 		};
 	option MSG_Cylinders, exit, action 
-		{ sizemult = current_cylsize; 
+		{ sizemult = pm->current_cylsize; 
 		  multname = msg_string(MSG_cylname);
 		};
 	option MSG_Sectors, exit, action 
@@ -233,12 +241,12 @@ menu distmedium, title MSG_Select_medium, y=-5;
 	option MSG_Skip_group,exit, action { *(int *)arg = SET_SKIP_GROUP; };
 	option MSG_Abandon,   exit, action { *(int *)arg = SET_ABANDON; };
 
-menu distset, title MSG_Select_your_distribution;
+menu distset, title MSG_Select_your_distribution, exit, no default exit;
 	display action { msg_display (MSG_distset); };
-	option MSG_Full_installation, exit, action { init_set_status(0);  };
-	option MSG_Full_installation_nox, exit, action { init_set_status(SFLAG_NOX); };
-	option MSG_Minimal_installation, exit, action { init_set_status(SFLAG_MINIMAL); };
-	option MSG_Custom_installation, exit, action { init_set_status(SFLAG_MINIMAL); customise_sets(); };
+	option MSG_Full_installation, exit, action { *(int *)arg = 1; init_set_status(0);  };
+	option MSG_Full_installation_nox, exit, action { *(int *)arg = 1; init_set_status(SFLAG_NOX); };
+	option MSG_Minimal_installation, exit, action { *(int *)arg = 1; init_set_status(SFLAG_MINIMAL); };
+	option MSG_Custom_installation, exit, action { *(int *)arg = 1; init_set_status(SFLAG_MINIMAL); customise_sets(); };
 
 menu ftpsource, y=-4, x=0, w=70, no box, no clear,
 	    exitstring MSG_Get_Distribution;
@@ -281,10 +289,17 @@ menu ftpsource, y=-4, x=0, w=70, no box, no clear,
 			clean_xfer_dir ? MSG_Yes : MSG_No);},
 		action {process_menu(MENU_yesno, deconst(MSG_delete_xfer_file));
 			clean_xfer_dir = yesno; };
+	option MSG_Configure_network,
+		action {
+			extern int network_up;
+			network_up = 0;
+			config_network();
+		};
+	option MSG_exit_menu_generic, exit, action { yesno = SET_RETRY; };
 
 
 menu nfssource, y=-4, x=0, w=70, no box, no clear,
-	    exitstring MSG_Continue;
+	    exitstring MSG_Get_Distribution;
 	display action { msg_display(MSG_nfssource); };
 	option {src_legend(menu, MSG_Host, nfs_host);},
 		action { src_prompt(MSG_Host, nfs_host, sizeof nfs_host); };
@@ -294,6 +309,13 @@ menu nfssource, y=-4, x=0, w=70, no box, no clear,
 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
+	option MSG_Configure_network,
+		action {
+			extern int network_up;
+			network_up = 0;
+			config_network();
+		};
+	option MSG_exit_menu_generic, exit, action { yesno = SET_RETRY; };
 
 menu fdremount, title MSG_What_do_you_want_to_do;
 	option MSG_Try_again, exit, action { *(int *)arg = SET_CONTINUE; };
@@ -323,6 +345,7 @@ menu floppysource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 			clean_xfer_dir ? MSG_Yes : MSG_No);},
 		action {process_menu(MENU_yesno, deconst(MSG_delete_xfer_file));
 			clean_xfer_dir = yesno; };
+	option MSG_exit_menu_generic, exit, action { yesno = SET_RETRY; };
 
 menu cdromsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 	display action { msg_display(MSG_cdromsource); };
@@ -332,6 +355,7 @@ menu cdromsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
+	option MSG_exit_menu_generic, exit, action { yesno = SET_RETRY; };
 
 menu localfssource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 	display action { msg_display(MSG_localfssource); };
@@ -345,6 +369,7 @@ menu localfssource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, sizeof set_dir_bin); };
 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
 		action { src_prompt(MSG_Set_dir_src, set_dir_src, sizeof set_dir_src); };
+	option MSG_exit_menu_generic, exit, action { yesno = SET_RETRY; };
 
 menu localdirsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 	display action { msg_display(MSG_localdir); };
@@ -354,6 +379,7 @@ menu localdirsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
 		action { src_prompt(MSG_Set_dir_bin, set_dir_bin, 60); };
 	option {src_legend(menu, MSG_Set_dir_src, set_dir_src);},
 		action { src_prompt(MSG_Set_dir_src, set_dir_src, 60); };
+	option MSG_exit_menu_generic, exit, action { yesno = SET_RETRY; };
 
 menu namesrv6, title MSG_Select_IPv6_DNS_server;
 	option "google-public-dns-a.google.com", exit, action
@@ -422,6 +448,17 @@ menu binpkg, y=-4, x=0, w=70, no box, no clear,
 			setenv("http_proxy", pkg.proxy, 1);
 		  }
 		};
+	option {src_legend(menu, "Additional packages", (char*)arg); }, /*TODO*/
+		action { src_prompt("Additional packages", (char*)arg,
+			 sizeof(char) * STRSIZE); };
+	option MSG_Configure_network,
+		action {
+			extern int network_up;
+			network_up = 0;
+			config_network();
+			mnt_net_config();
+		};
+	option MSG_quit_install, exit, action { yesno = SET_SKIP; };
 
 menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
 	    exit, exitstring MSG_Install_pkgsrc;
@@ -461,4 +498,144 @@ menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
 			clean_xfer_dir ? MSG_Yes : MSG_No);},
 		action {process_menu(MENU_yesno, deconst(MSG_delete_xfer_file));
 			clean_xfer_dir = yesno; };
-	option MSG_quit_pkgsrc, exit, action { yesno = 0;};
+	option MSG_Configure_network,
+		action {
+			extern int network_up;
+			network_up = 0;
+			config_network();
+		};
+	option MSG_quit_install, exit, action { yesno = SET_SKIP; };
+
+
+menu pmdiskentry, x=50, y=5, exit, default exit;
+	option MSG_editbsdpart, exit, action { pm_make_bsd_partitions(pm); };
+	option MSG_editmbr,		exit, action { md_get_info();
+											md_pre_disklabel();
+											memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);};
+	option MSG_switchgpt,	exit, action { if (pm_gpt_convert(pm) == 0)
+												pm_partusage(pm, -1, 1); };
+	option MSG_renamedisk,	exit, action { pm->unsaved = 1; pm_rename(pm); };
+	option MSG_fmtasraid,	exit, action { pm->unsaved = 1;
+											pm_partusage(pm, -1, 1);
+											layoutkind = LY_NEWRAID;
+											md_make_bsd_partitions();};
+	option MSG_fmtaslvm,	exit, action { pm->unsaved = 1;
+											pm_partusage(pm, -1, 1);
+											layoutkind = LY_NEWLVM;
+											md_make_bsd_partitions(); };
+	option MSG_encrypt,		exit, action { pm->unsaved = 1;
+											pm_partusage(pm, -1, 1);
+											layoutkind = LY_NEWCGD;
+											md_make_bsd_partitions();
+											pm_cgd_edit(0, &(part_entry_t)
+												{.dev_ptr = pm, .dev_num = PART_E}
+											); };
+	option MSG_setbootable,	exit, action { pm->unsaved = 1;
+											pm->bootable = !pm->bootable; };
+	option MSG_erase,		next menu shred_modes;
+	option MSG_undo,		exit, action { label_read(); pm->unsaved = 0;
+											pm_partusage(pm, -1, 1); };
+	option MSG_unconfig,	exit, action { if (pm_unconfigure(pm) == 0)
+												pm_partusage(pm, -1, 1); };
+
+menu pmpartentry, x=50, y=5, exit, default exit;
+	option MSG_edit,		exit, action { 
+									pm->unsaved = 1;
+									int tpfs = pm->bsdlabel[*(int*)arg].pi_fstype;
+									int tplvm = pm->bsdlabel[*(int*)arg].lvmpv;
+									pm_editpart(*(int*)arg);
+									if (tpfs != pm->bsdlabel[*(int*)arg].pi_fstype ||
+										tplvm != pm->bsdlabel[*(int*)arg].lvmpv)
+										/* Oops, partition type changed */
+										pm_partusage(pm, *(int*)arg, 1);
+								};
+	option MSG_fmtasraid,	exit, action {
+									if (pm->gpt || pm->isspecial) {
+										process_menu(MENU_ok, deconst(MSG_notsupported));
+										return -1;
+									}
+									pm->unsaved = 1;
+									pm_partusage(pm, *(int*)arg, 1);
+									pm_setfstype(pm, *(int*)arg, FS_RAID);
+								};
+	option MSG_fmtaslvm,	exit, action {
+									if (pm->gpt || pm->isspecial) {
+										process_menu(MENU_ok, deconst(MSG_notsupported));
+										return -1;
+									}
+									pm->unsaved = 1;
+									pm_partusage(pm, *(int*)arg, 1);
+									pm_setfstype(pm, *(int*)arg, FS_BSDFFS);
+								    pm->bsdlabel[*(int*)arg].lvmpv = 1;
+								};
+	option MSG_encrypt,		exit, action {
+									if (pm->gpt || pm->isspecial) {
+										process_menu(MENU_ok, deconst(MSG_notsupported));
+										return -1;
+									}
+									pm->unsaved = 1;
+									pm_partusage(pm, *(int*)arg, 1);
+									pm_setfstype(pm, *(int*)arg, FS_CGD);
+									pm_cgd_edit(0,
+										&(part_entry_t){.dev_ptr = pm,
+														.dev_num = *(int*)arg});
+								};
+	option MSG_erase,		next menu shred_modes;
+	option MSG_doumount,	exit, action { pm_umount(pm, *(int*)arg); };
+	option MSG_Delete_partition,	exit, action {
+									pm->unsaved = 1;
+									pm_partusage(pm, *(int*)arg, 1);
+									if (pm->isspecial)
+										pm_unconfigure(pm);
+									else
+										pm->bsdlabel[*(int*)arg].pi_fstype = FS_UNUSED;
+									};
+
+menu pmgptentry, x=50, y=8, exit, default exit;
+	option MSG_editbsdpart, exit, action { pm_make_bsd_partitions(pm); };
+	option MSG_switchmbr,	exit, action { if (pm_gpt_convert(pm) == 0)
+												pm_partusage(pm, -1, 1); };
+	option MSG_setbootable,	exit, action { pm->unsaved = 1;
+												pm->bootable = !pm->bootable; };
+	option MSG_erase,		next menu shred_modes;
+	option MSG_undo,		exit, action { label_read(); pm->unsaved = 0;
+											pm_partusage(pm, -1, 1); };
+	option MSG_unconfig,	exit, action { if (pm_unconfigure(pm) == 0)
+												pm_partusage(pm, -1, 1); };
+
+menu shred_modes, x=50, y=5, exit, default exit;
+	option MSG_fillzeros,	exit,
+							action { pm_shred(pm, *(int*)arg, SHRED_ZEROS); };
+	option MSG_fillrandom,	exit,
+							action { pm_shred(pm, *(int*)arg, SHRED_RANDOM); };
+	option MSG_fillcrypto,	exit,
+							action { pm_shred(pm, *(int*)arg, SHRED_CRYPTO); };
+
+menu raidlevel;
+	option MSG_raid0, exit, action { *(int *)arg = 0; };
+	option MSG_raid1, exit, action { *(int *)arg = 1; };
+	option MSG_raid4, exit, action { *(int *)arg = 4; };
+	option MSG_raid5, exit, action { *(int *)arg = 5; };
+
+menu cgd_enctype;
+	option "aes-cbc",			exit, action { *(const char**)arg = "aes-cbc"; };
+	option "3des-cbc",			exit, action { *(const char**)arg = "3des-cbc"; };
+	option "blowfish-cbc",		exit, action { *(const char**)arg = "blowfish-cbc"; };
+
+menu cgd_ivtype;
+	option "encblkno1",			exit, action { *(const char**)arg = "encblkno1"; };
+	option "encblkno8",			exit, action { *(const char**)arg = "encblkno8"; };
+
+menu cgd_keygentype;
+	option "pkcs5_pbkdf2/sha1",	exit, action { *(const char**)arg = "pkcs5_pbkdf2/sha1"; };
+	option "pkcs5_pbkdf2",		exit, action { *(const char**)arg = "pkcs5_pbkdf2"; };
+	option "storedkey",			exit, action { *(const char**)arg = "storedkey"; };
+	option "randomkey",			exit, action { *(const char**)arg = "randomkey"; };
+	option "urandomkey",		exit, action { *(const char**)arg = "urandomkey"; };
+	option "shell_cmd",			exit, action { *(const char**)arg = "shell_cmd"; };
+
+menu cgd_verifytype;
+	option "none",				exit, action { *(const char**)arg = "none"; };
+	option "disklabel",			exit, action { *(const char**)arg = "disklabel"; };
+	option "ffs",				exit, action { *(const char**)arg = "ffs"; };
+	option "re-enter",			exit, action { *(const char**)arg = "re-enter"; };
diff --git a/distrib/utils/sysinst/msg.mi.de b/distrib/utils/sysinst/msg.mi.de
index 25be022..603e40c 100644
--- a/distrib/utils/sysinst/msg.mi.de
+++ b/distrib/utils/sysinst/msg.mi.de
@@ -35,7 +35,7 @@
 /* MI Message catalog -- German, machine independent */
 
 message usage
-{Aufruf: sysinst [-r Release] [-f Definitionsdatei]
+{Aufruf: sysinst [-r Release] [-f Definitionsdatei]  [-C bg:fg]
 }
 
 /*
@@ -514,19 +514,11 @@ message nonet
 Zurück zum vorigen Menü.
 }
 
-message netup
-{Die folgenden Netzwerkadapter sind verfügbar: %s 
-Hat einer davon Zugriff auf die benötigten Server?}
-
 message asknetdev
-{NetBSD hat folgende Netzwerkadapter gefunden: %s
-\nWelchen möchten Sie benutzen?}
+{NetBSD hat einige Netzwerkadapter gefunden. Welchen möchten Sie benutzen?}
 
-message badnet
-{Sie haben keinen der angezeigten Netzwerkadapter ausgewählt. Bitte versuchen
-Sie es erneut. 
-NetBSD hat folgende Netzwerkadapter gefunden: %s
-\nWelchen möchten Sie benutzen?}
+message netdevs
+{Verfügbare schnittstellen}
 
 message netinfo
 {Um das Netzwerk nutzen zu können, benötigen wir folgende Angaben:
@@ -600,11 +592,6 @@ message slattach {
 Flags für slattach
 }
 
-message netagain
-{Bitte geben Sie die Informationen über Ihr Netzwerk erneut an. Diese werden
-auch als Vorgabe beibehalten.
-
-}
 
 message wait_network
 {
@@ -951,8 +938,9 @@ message Install_NetBSD_to_hard_disk {NetBSD auf die Festplatte installieren}
 message Upgrade_NetBSD_on_a_hard_disk {Aktualisierung einer bestehenden NetBSD-Installation}
 message Re_install_sets_or_install_additional_sets {Erneute Installation oder zusätzliche Pakete installieren}
 message Reboot_the_computer {Computer neu starten}
+message Config_menu {Konfiguration Menü}
 message Utility_menu {Extras}
-message exit_utility_menu {Zurück zum Hauptmenü}
+message exit_menu_generic {Zurück}
 message NetBSD_VERSION_Utilities {NetBSD-@@VERSION@@ Extras}
 message Run_bin_sh {Ausführen von /bin/sh}
 message Set_timezone {Setzen der Zeitzone}
@@ -1006,6 +994,11 @@ message other {andere }
 message Perform_IPv6_autoconfiguration {IPv6 automatisch konfigurieren?}
 message Perform_DHCP_autoconfiguration {Konfiguration per DHCP ermitteln?}
 message Root_shell {Root-Shell}
+message Color_scheme {Farbschema}
+message White_on_black {Weiß auf schwarz}
+message Black_on_white {Schwarz auf weiß}
+message White_on_blue {Weiß auf Blau}
+message Green_on_black {Grün auf schwarz}
 
 .if AOUT2ELF
 message aoutfail
@@ -1073,6 +1066,10 @@ message enable_sshd {sshd aktivieren}
 message enable_ntpd {ntpd aktivieren}
 message run_ntpdate {ntpdate beim Starten ausführen}
 message enable_mdnsd {mdnsd aktivieren}
+message enable_xdm {xdm aktivieren}
+message enable_cgd {cgd aktivieren}
+message enable_lvm {lvm aktivieren}
+message enable_raid {raidframe aktivieren}
 message configmenu {Zusätzliche Einstellungen konfigurieren.}
 message doneconfig {Konfiguration abgeschlossen.}
 message Install_pkgin {pkgin installieren und Datenbank initialisieren}
@@ -1095,8 +1092,153 @@ message get_pkgsrc {pkgsrc zur Installation von Quellpaketen herunterladen und
 installieren}
 message retry_pkgsrc_network {Netzwerkkonfiguration fehlgeschlagen. Noch einmal 
 versuchen?}
-message quit_pkgsrc {Ohne Installation von pkgsrc beenden.}
+message quit_install {Ohne Installation von pkgsrc beenden.} /*TODO*/
 message pkgin_failed 
 {Die Installation von pkgin ist fehlgeschlagen, evtl. weil keine Binärpakete 
 vorhanden sind. Bitte den Pfad der Pakete überprüfen und noch einmal versuchen.}
 message failed {Fehlgeschlagen}
+
+
+message notsupported {Operation wird nicht unterstützt!}
+message askfsmountadv {Mountpoint oder 'raid' oder 'cgd' oder 'lvm'?}
+message partman {Erweiterte Partitionierung}
+message editbsdpart {Bearbeiten BSD-Partitionen}
+message editmbr {Bearbeiten und speichern MBR}
+message switchgpt {Wechseln Sie zu GPT}
+message switchmbr {Wechseln Sie zu MBR}
+message renamedisk {Stellen Sie Festplatten-Namen}
+message fmtasraid {Format als RAID}
+message fmtaslvm {Format als LVM-PV}
+message encrypt {Verschlüsseln}
+message setbootable {Boot-Flag}
+message erase {Safe Erase}
+message undo {Rückgängigmachen von Änderungen}
+message unconfig {Dekonfigurieren}
+message edit {Bearbeiten}
+message doumount {Force-umount}
+message fillzeros {Füllen von Nullen}
+message fillrandom {Füllen von zufälligen Daten}
+message fillcrypto {Füllen von Crypto-Daten}
+message raid0 {0 - Keine Parität, nur einfache Striping.}
+message raid1 {1 - Mirroring. Die Parität ist der Spiegel.}
+message raid4 {4 - Striping mit Parität auf die letzte Komponente gespeichert.}
+message raid5 {5 - Striping mit Parität an den alle Komponenten.}
+
+message fremove {ENTFERNEN}
+message remove {Entfernen}
+message add {Hinzufügen}
+message auto {auto}
+
+message removepartswarn {Diese entfernen Sie alle Partitionen auf der Festplatte. Wollen Sie fortsetzen?}
+message saveprompt {Speichern Sie die Änderungen vor dem Abschluss?}
+message cantsave {Änderungen können nicht gespeichert werden.}
+message noroot {Kein Root-Partition definiert ist, kann nicht fortgesetzt werden \n}
+message wannaunblock {Das Gerät ist blockiert. Wollen Sie zwingen sie zu entsperren und weiter?}
+message wannatry {Wollen Sie probieren?}
+message create_cgd {Erstellen kryptographische Volumen (CGD)}
+message create_cnd {Erstellen Sie virtuelle Disk-Image (VND)}
+message create_vg {Erstellen Volume-Gruppe (LVM VG)}
+message create_lv {      Erstellen logischer Volumen}
+message create_raid {Erstellen Software-RAID}
+message updpmlist {Aktualisieren Sie Geräte-Liste}
+message savepm {Speichern Sie die Änderungen}
+message pmblocked {GESPERRT}
+message pmunchanged {NICHTS}
+message pmsetboot {BOOTEN}
+message pmused {BENUTZT}
+message pmmounted {(montiert)}
+message pmunused {(unbenutzt)}
+message pmgptdisk {Festplatte mit GPT}
+
+message finishpm {Partitionierung beenden}
+message limitcount {Grenze für die Anzahl der Geräte erreicht wurde!}
+message invaliddev {Ungültige Gerät!}
+message avdisks {Verfügbare Festplatten:}
+message nofreedev {Kann nicht zugewiesen werden Geräteknoten!}
+message partman_header
+{Partition Manager. Alle Festplatten, Partitionen usw. und dort angezeigt.
+Auf den ersten MBR-Partitionen machen, dann machen BSD-Label.
+Wenn Sie RAID verwenden, LVM oder CGD, gehen Sie folgendermaßen vor:
+1) Erstellen BSD-Partitionen mit Typ benötigt; 2) Erstellen Sie RAID /
+LVM VG / CGD mit diesen Partitionen; 3) Speichern Sie es;
+4) Erstellen Sie Partitionen für RAID / CGD oder Logical Volumes für LVM.}
+
+message raid_menufmt {   raid%d (ebene %1d) on %-34s %11uM}
+message raid_err_menufmt {   LEER RAID!}
+message raid_disks_fmt {Festplatten: %27s}
+message raid_spares_fmt {Ersatzbedarf: %26s}
+message raid_level_fmt {RAID ebene:       %22d}
+message raid_numrow_fmt {numRow:           %22d}
+message raid_numcol_fmt {numCol:           %22d}
+message raid_numspare_fmt {numSpare:         %22d}
+message raid_sectpersu_fmt {sectPerSU:        %22d}
+message raid_superpar_fmt {SUsPerParityUnit: %22d}
+message raid_superrec_fmt {SUsPerReconUnit:  %22d}
+message raid_nomultidim {Mehrdimensionale Arrays werden nicht unterstützt!}
+message raid_numrow_ask {numRow?}
+message raid_numcol_ask {numCol?}
+message raid_numspare_ask {numSpare?}
+message raid_sectpersu_ask {sectPerSU?}
+message raid_superpar_ask {SUsPerParityUnit?}
+message raid_superrec_ask {SUsPerReconUnit?}
+message raid_disks {Festplatten im RAID:}
+message vnd_err_menufmt {   PATH nicht definiert!}
+message vnd_assgn_menufmt {   vnd%1d auf %-50s ASSIGN}
+message vnd_menufmt {   vnd%1d auf %-44s %11uM}
+message vnd_path_fmt {Dateipfad: %29s}
+message vnd_assgn_fmt {Weisen Sie existieren Bild: %12s}
+message vnd_size_fmt {Größe:           %22sM}
+message vnd_ro_fmt {Nur lesen:        %22s}
+message vnd_geom_fmt {Stellen Sie Geometrie von Hand: %8s}
+message vnd_bps_fmt {Byte pro Sektor:      %18s}
+message vnd_spt_fmt {Sektoren pro Spur:    %18s}
+message vnd_tpc_fmt {Spuren pro Zylinder:  %18s}
+message vnd_cyl_fmt {Zylinder:         %22s}
+message vnd_path_ask {Dateipfad?}
+message vnd_size_ask {Größe (MB)?}
+message vnd_bps_ask {Byte pro Sektor?}
+message vnd_spt_ask {Sektoren pro Spur?}
+message vnd_tpc_ask {Spuren pro Zylinder?}
+message vnd_cyl_ask {Zylinder?}
+message cgd_err_menufmt {   DISK NICHT DEFINIERT!}
+message cgd_menufmt {   cgd%1d %-48s %11uM}
+message cgd_dev_fmt {Grundgerät:     %24s}
+message cgd_enc_fmt {Mausklick und:  %24s}
+message cgd_key_fmt {Schlüsselgröße: %24d}
+message cgd_iv_fmt {IV-Algorithmus: %24s}
+message cgd_keygen_fmt {Schlüsselgenerierung: %18s}
+message cgd_verif_fmt {Verification Methode: %18s}
+message lvm_disks {Festplatten im VG:}
+message lvm_menufmt {   %-44s %20sM}
+message lvm_err_menufmt {   VG LEER!}
+message lvm_disks_fmt {PV's: %34s}
+message lvm_name_fmt {Name: %34s}
+message lvm_maxlv_fmt {MaxLogicalVolumes:  %20s}
+message lvm_maxpv_fmt {MaxPhysicalVolumes: %20s}
+message lvm_extsiz_fmt {PhysicalExtentSize: %20s}
+message lvm_name_ask {Name?}
+message lvm_maxlv_ask {MaxLogicalVolumes?}
+message lvm_maxpv_ask {MaxPhysicalVolumes?}
+message lvm_extsiz_ask {PhysicalExtentSize (MB)?}
+message lvmlv_menufmt {      Logische Volumen%-35s% 11uM}
+message lvmlv_name_fmt {Name: %34s}
+message lvmlv_size_fmt {Größe: %32dM}
+message lvmlv_ro_fmt {Nur lesen:  %27s}
+message lvmlv_cont_fmt {Zusammenhängend: %23s}
+message lvmlv_extnum_fmt {LogicalExtentsNumber: %18s}
+message lvmlv_minor_fmt {Minor-Nummer: %26s}
+message lvmlv_mirrors_fmt {Mirrors: %27d}
+message lvmlv_regsiz_fmt {MirrorLogRegionSize: %18s}
+message lvmlv_pers_fmt {Persistent Minor-Nummer: %14s}
+message lvmlv_readahsect_fmt {ReadAheadSectors: %18s}
+message lvmlv_stripes_fmt {Stripes: %27s}
+message lvmlv_stripesiz_fmt {StripeSize: %27s}
+message lvmlv_zero_fmt {Nullsetzen der ersten KB:% 13s}
+message lvmlv_name_ask {Name?}
+message lvmlv_size_ask {Größe (MB)?}
+message lvmlv_extnum_ask {LogicalExtentsNumber?}
+message lvmlv_minor_ask {Minor-Nummer?}
+message lvmlv_mirrors_ask {Spiegel?}
+message lvmlv_regsiz_ask {MirrorLogRegionSize?}
+message lvmlv_readahsect_ask {ReadAheadSectors?}
+message lvmlv_stripes_ask {Stripes?}
diff --git a/distrib/utils/sysinst/msg.mi.en b/distrib/utils/sysinst/msg.mi.en
index f43ee38..8c6c623 100644
--- a/distrib/utils/sysinst/msg.mi.en
+++ b/distrib/utils/sysinst/msg.mi.en
@@ -35,7 +35,7 @@
 /* MI Message catalog -- english, machine independent */
 
 message usage
-{usage: sysinst [-r release] [-f definition-file]
+{usage: sysinst [-r release] [-f definition-file] [-C bg:fg]
 }
 
 message sysinst_message_language
@@ -496,18 +496,11 @@ message nonet
 returned to the previous menu.
 }
 
-message netup
-{The following network interfaces are active: %s
-Does one of them connect to the required server?}
-
 message asknetdev
-{I have found the following network interfaces: %s
-\nWhich device shall I use?}
+{I have found some network interfaces. Which device shall I use?}
 
-message badnet
-{You did not choose one of the listed network devices.  Please try again.
-The following network devices are available: %s
-\nWhich device shall I use?}
+message netdevs
+{Available interfaces}
 
 message netinfo
 {To be able to use the network, we need answers to the following:
@@ -576,12 +569,6 @@ IPv6 Nameserver:	%s
 message netok_ok
 {Are they OK?}
 
-message netagain
-{Please reenter the information about your network.  Your last answers
-will be your default.
-
-}
-
 message wait_network
 {
 Waiting while network interface comes up.
@@ -891,8 +878,9 @@ message Install_NetBSD_to_hard_disk {Install NetBSD to hard disk}
 message Upgrade_NetBSD_on_a_hard_disk {Upgrade NetBSD on a hard disk}
 message Re_install_sets_or_install_additional_sets {Re-install sets or install additional sets}
 message Reboot_the_computer {Reboot the computer}
+message Config_menu {Config menu}
 message Utility_menu {Utility menu}
-message exit_utility_menu {Back to main menu}
+message exit_menu_generic {Exit}
 message NetBSD_VERSION_Utilities {NetBSD-@@VERSION@@ Utilities}
 message Run_bin_sh {Run /bin/sh}
 message Set_timezone {Set timezone}
@@ -946,6 +934,11 @@ message other {other }
 message Perform_IPv6_autoconfiguration {Perform IPv6 autoconfiguration?}
 message Perform_DHCP_autoconfiguration {Perform DHCP autoconfiguration?}
 message Root_shell {Root shell}
+message Color_scheme {Color scheme}
+message White_on_black {White on black}
+message Black_on_white {Black on white}
+message White_on_blue {White on blue}
+message Green_on_black {Green on black}
 
 .if AOUT2ELF
 message aoutfail
@@ -1000,11 +993,15 @@ message abandoned {Abandoned}
 message empty {***EMPTY***}
 message timezone {Timezone}
 message change_rootpw {Change root password}
-message enable_binpkg {Enable installation of binary packages}
+message enable_binpkg {Fetch and install pkgin packages management tool}
 message enable_sshd {Enable sshd}
 message enable_ntpd {Enable ntpd}
 message run_ntpdate {Run ntpdate at boot}
 message enable_mdnsd {Enable mdnsd}
+message enable_xdm {Enable xdm}
+message enable_cgd {Enable cgd}
+message enable_lvm {Enable lvm}
+message enable_raid {Enable raidframe}
 message configmenu {Configure the additional items as needed.}
 message doneconfig {Finished configuring}
 message Install_pkgin {Install pkgin and update package summary}
@@ -1022,11 +1019,157 @@ The following are the host, directory, user, and password that
 will be used.  If "user" is "ftp", then the password is not needed.
 
 }
+message quit_install {Quit without installing this component}
 message Pkgsrc_dir {pkgsrc directory}
 message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
 message retry_pkgsrc_network {Network configuration failed.  Retry?}
-message quit_pkgsrc {Quit without installing pkgsrc}
 message pkgin_failed
 {Installation of pkgin failed, possibly because no binary packages
 exist.  Please check the package path and try again.}
 message failed {Failed}
+
+
+message notsupported {Operation not supported!}
+message askfsmountadv {Mountpoint or 'raid' or 'cgd' or 'lvm'?}
+message partman {Extended partitioning}
+message editbsdpart {Edit BSD partitions}
+message editmbr {Edit and save MBR}
+message switchgpt {Switch to GPT}
+message switchmbr {Switch to MBR}
+message renamedisk {Set disk name}
+message fmtasraid {Format as RAID}
+message fmtaslvm {Format as LVM PV}
+message encrypt {Encrypt}
+message setbootable {Bootable flag}
+message erase {Safe erase}
+message undo {Undo changes}
+message unconfig {Unconfigure}
+message edit {Edit}
+message doumount {Force umount}
+message fillzeros {Fill by zeros}
+message fillrandom {Fill by random data}
+message fillcrypto {Fill by crypto data}
+message raid0 {0 - No parity, only simple striping.}
+message raid1 {1 - Mirroring.  The parity is the mirror.}
+message raid4 {4 - Striping with parity stored on the last component.}
+message raid5 {5 - Striping with parity at the all components.}
+
+message fremove {REMOVE}
+message remove {Remove}
+message add {Add}
+message auto {auto}
+
+message removepartswarn {This remove all partitions on disk. Do you want to continue?}
+message saveprompt {Save changes before finishing?}
+message cantsave {Changes cannot be saved.}
+message noroot {No root partition defined, cannot continue\n}
+message wannaunblock {
+Device is blocked. It's editing may cause problems.
+Do you want to force unblock it and continue?}
+message wannatry {Do you want to try?}
+message create_cgd {Create cryptographic volume (CGD)}
+message create_cnd {Create virtual disk image (VND)}
+message create_vg {Create volume group (LVM VG)}
+message create_lv {      Create logical volume}
+message create_raid {Create software RAID}
+message updpmlist {Update devices list}
+message savepm {Save changes}
+message pmblocked {BLOCKED}
+message pmunchanged {UNCHANGED}
+message pmsetboot {BOOT}
+message pmused {USED}
+message pmmounted {(mounted)}
+message pmunused {(unused)}
+message pmgptdisk {GPT-labeled disk}
+
+message finishpm {Finish partitioning}
+message limitcount {Limit for the devices count was reached!}
+message invaliddev {Invalid device!}
+message avdisks {Available disks:}
+message nofreedev {Cannot allocate device node!}
+message partman_header
+{Partition manager. All disks, partitions and etc. displayed there.
+At first make MBR partitions, then make BSD label. If you want to use RAID,
+LVM or CGD, follow these steps: 1) Create BSD partitions with needed type;
+2) Create RAID/LVM VG/CGD using these partitions; 3) Save it;
+4) Create partitions for RAID/CGD or Logical Volumes for LVM.}
+
+message raid_menufmt {   raid%d (level %1d) on %-34s %11uM}
+message raid_err_menufmt {   EMPTY RAID!}
+message raid_disks_fmt {Disks: %33s}
+message raid_spares_fmt {Spares: %32s}
+message raid_level_fmt {RAID level:       %22d}
+message raid_numrow_fmt {numRow:           %22d}
+message raid_numcol_fmt {numCol:           %22d}
+message raid_numspare_fmt {numSpare:         %22d}
+message raid_sectpersu_fmt {sectPerSU:        %22d}
+message raid_superpar_fmt {SUsPerParityUnit: %22d}
+message raid_superrec_fmt {SUsPerReconUnit:  %22d}
+message raid_nomultidim {Multi-dimensional arrays are NOT supported!}
+message raid_numrow_ask {numRow?}
+message raid_numcol_ask {numCol?}
+message raid_numspare_ask {numSpare?}
+message raid_sectpersu_ask {sectPerSU?}
+message raid_superpar_ask {SUsPerParityUnit?}
+message raid_superrec_ask {SUsPerReconUnit?}
+message raid_disks {Disks in RAID:}
+message vnd_err_menufmt {   PATH NOT DEFINED!}
+message vnd_assgn_menufmt {   vnd%1d on %-51s ASSIGN}
+message vnd_menufmt {   vnd%1d on %-45s %11uM}
+message vnd_path_fmt {File path: %29s}
+message vnd_assgn_fmt {Assign exist image: %20s}
+message vnd_size_fmt {Size:            %22sM}
+message vnd_ro_fmt {Read-only:        %22s}
+message vnd_geom_fmt {Set geometry by hand: %18s}
+message vnd_bps_fmt {Bytes per Sector:     %18s}
+message vnd_spt_fmt {Sectors per Track:    %18s}
+message vnd_tpc_fmt {Tracks per Cylinder:  %18s}
+message vnd_cyl_fmt {Cylinders:        %22s}
+message vnd_path_ask {File path?}
+message vnd_size_ask {Size (MB)?}
+message vnd_bps_ask {Bytes per Sector?}
+message vnd_spt_ask {Sectors per Track?}
+message vnd_tpc_ask {Tracks per Cylinder?}
+message vnd_cyl_ask {Cylinders?}
+message cgd_err_menufmt {   DISK NOT DEFINED!}
+message cgd_menufmt {   cgd%1d %-48s %11uM}
+message cgd_dev_fmt {Base device:    %24s}
+message cgd_enc_fmt {Encyption:      %24s}
+message cgd_key_fmt {Key size:       %24d}
+message cgd_iv_fmt {IV algorithm:   %24s}
+message cgd_keygen_fmt {Key generation: %24s}
+message cgd_verif_fmt {Verification method:   %17s}
+message lvm_disks {Disks in VG:}
+message lvm_menufmt {   %-44s %20sM}
+message lvm_err_menufmt {   EMPTY VG!}
+message lvm_disks_fmt {PV's: %34s}
+message lvm_name_fmt {Name: %34s}
+message lvm_maxlv_fmt {MaxLogicalVolumes:  %20s}
+message lvm_maxpv_fmt {MaxPhysicalVolumes: %20s}
+message lvm_extsiz_fmt {PhysicalExtentSize: %20s}
+message lvm_name_ask {Name?}
+message lvm_maxlv_ask {MaxLogicalVolumes?}
+message lvm_maxpv_ask {MaxPhysicalVolumes?}
+message lvm_extsiz_ask {PhysicalExtentSize (MB)?}
+message lvmlv_menufmt {      Logical volume %-35s %11uM}
+message lvmlv_name_fmt {Name: %34s}
+message lvmlv_size_fmt {Size: %33dM}
+message lvmlv_ro_fmt {Read-only:   %27s}
+message lvmlv_cont_fmt {Contiguous:  %27s}
+message lvmlv_extnum_fmt {LogicalExtentsNumber: %18s}
+message lvmlv_minor_fmt {Minor number: %26s}
+message lvmlv_mirrors_fmt {Mirrors:     %27d}
+message lvmlv_regsiz_fmt {MirrorLogRegionSize:  %18s}
+message lvmlv_pers_fmt {Persistent minor number:  %14s}
+message lvmlv_readahsect_fmt {ReadAheadSectors:     %18s}
+message lvmlv_stripes_fmt {Stripes:     %27s}
+message lvmlv_stripesiz_fmt {StripeSize:  %27s}
+message lvmlv_zero_fmt {Zeroing of the first KB:   %13s}
+message lvmlv_name_ask {Name?}
+message lvmlv_size_ask {Size (MB)?}
+message lvmlv_extnum_ask {LogicalExtentsNumber?}
+message lvmlv_minor_ask {Minor number?}
+message lvmlv_mirrors_ask {Mirrors?}
+message lvmlv_regsiz_ask {MirrorLogRegionSize?}
+message lvmlv_readahsect_ask {ReadAheadSectors?}
+message lvmlv_stripes_ask {Stripes?}
diff --git a/distrib/utils/sysinst/msg.mi.es b/distrib/utils/sysinst/msg.mi.es
index 4b7b51b..339e385 100644
--- a/distrib/utils/sysinst/msg.mi.es
+++ b/distrib/utils/sysinst/msg.mi.es
@@ -35,7 +35,7 @@
 /* MI Message catalog -- spanish, machine independent */
 
 message usage
-{uso: sysinst [-r versión] [-f fichero-definición]
+{uso: sysinst [-r versión] [-f fichero-definición] [-C bg:fg]
 }
 
 /*
@@ -509,19 +509,11 @@ message nonet
 Se le devolverá al menú anterior.
 }
 
-message netup
-{Las siguientes interfaces están activas: %s
-¿Conecta alguna de ellas al servidor requerido?}
-
 message asknetdev
-{Se han encontrado las siguientes interfaces de red: %s
-\n¿Cuál se debería usar?}
+{Se han encontrado las siguientes interfaces de red. ¿Cuál se debería usar?}
 
-message badnet
-{No ha seleccionado ninguna interfaz de las listadas.  Por favor, vuelva a
-intentarlo.
-Están disponibles las siguientes interfaces de red: %s
-\n¿Cuál debería usar?}
+message netdevs
+{Interfaces disponibles}
 
 message netinfo
 {Para poder usar la red, necesita responder lo siguiente:
@@ -590,12 +582,6 @@ Serv de nombres IPv6:	%s
 message netok_ok
 {¿Son correctos?}
 
-message netagain
-{Por favor, vuelva a introducir la información sobre su red.  Sus últimas
-respuestas serán las predeterminadas.
-
-}
-
 message wait_network
 {
 Espere mientras las interfaces de red se levantan.
@@ -916,8 +902,9 @@ message Install_NetBSD_to_hard_disk {Instalar NetBSD en el disco duro}
 message Upgrade_NetBSD_on_a_hard_disk {Actualizar NetBSD en un disco duro}
 message Re_install_sets_or_install_additional_sets {Reinstalar conjuntos o instalar conjuntos adicionales}
 message Reboot_the_computer {Reiniciar la computadora}
+message Config_menu {Menú de configuración}
 message Utility_menu {Menú de utilidades}
-message exit_utility_menu {Exit}
+message exit_menu_generic {atrás}
 message NetBSD_VERSION_Utilities {Utilidades de NetBSD-@@VERSION@@}
 message Run_bin_sh {Ejecutar /bin/sh}
 message Set_timezone {Establecer la zona horaria}
@@ -971,6 +958,11 @@ message other {otro }
 message Perform_IPv6_autoconfiguration {¿Realizar autoconfiguración IPv6?}
 message Perform_DHCP_autoconfiguration {¿Realizar autoconfiguración DHCP ?}
 message Root_shell {Shell de root}
+message Color_scheme {Combinación de colores}
+message White_on_black {Blanco sobre negro}
+message Black_on_white {Negro sobre blanco}
+message White_on_blue {Blanco sobre azul}
+message Green_on_black {Verde sobre negro}
 
 .if AOUT2ELF
 message aoutfail
@@ -1040,10 +1032,14 @@ message empty {***EMPTY***}
 message timezone {Timezone}
 message change_rootpw {Change root password}
 message enable_binpkg {Enable installation of binary packages}
-message enable_sshd {Enable sshd}
-message enable_ntpd {Enable ntpd}
+message enable_sshd {Activar sshd}
+message enable_ntpd {Activar ntpd}
 message run_ntpdate {Run ntpdate at boot}
-message enable_mdnsd {Enable mdnsd}
+message enable_mdnsd {Activar mdnsd}
+message enable_xdm {Activar xdm}
+message enable_cgd {Activar cgd}
+message enable_lvm {Activar lvm}
+message enable_raid {Activar raidframe}
 message configmenu {Configure the additional items as needed.}
 message doneconfig {Finished configuring}
 message Install_pkgin {Install pkgin and update package summary}
@@ -1064,7 +1060,152 @@ will be used.  If "user" is "ftp", then the password is not needed.
 message Pkgsrc_dir {pkgsrc directory}
 message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
 message retry_pkgsrc_network {Network configuration failed.  Retry?}
-message quit_pkgsrc {Quit without installing pkgsrc}
+message quit_install {Quit without installing pkgsrc} /*TODO*/
 message pkgin_failed 
 {Installation of pkgin failed, possibly because no binary packages  exist.  Please check the package path and try again.}
 message failed {Failed}
+
+
+message notsupported {Operación no admitida!}
+message askfsmountadv {Punto de montaje o 'raid' o 'CGD' o 'lvm'?}
+message partman {Partición extendida}
+message editbsdpart {Editar particiones BSD}
+message editmbr {Editar y guardar MBR}
+message switchgpt {Cambiar a GPT}
+message switchmbr {Cambiar a MBR}
+message renamedisk {Establece el nombre del disco}
+message fmtasraid {Formato como RAID}
+message fmtaslvm {Formato como LVM PV}
+message encrypt {Cifrar}
+message setbootable {La bandera de arranque}
+message erase {Borrado seguro}
+message undo {Deshacer los cambios}
+message unconfig {Desconfigurar}
+message edit {Editar}
+message doumount {Fuerza umount}
+message fillzeros {Llenar con ceros}
+message fillrandom {Llene los datos al azar}
+message fillcrypto {Rellene los datos de cifrado}
+message raid0 {0 - Sin paridad, creación de bandas sólo es simple.}
+message raid1 {1 - Creación de reflejos. La paridad es el espejo.}
+message raid4 {4 - Striping con paridad almacenada en el último componente. component.}
+message raid5 {5 - Striping con paridad en los componentes de todos. components.}
+
+message fremove {QUITAR}
+message remove {Quitar}
+message add {Añadir}
+message auto {auto}
+
+message removepartswarn {Esta eliminar todas las particiones en el disco. ¿Desea continuar? want to continue?}
+message saveprompt {Guarde los cambios antes de terminar?}
+message cantsave {Los cambios no se pueden guardar.}
+message noroot {No hay una partición raíz definida, no puede continuar \n}
+message wannaunblock {El dispositivo está bloqueado. ¿Quiere forzar a desbloquear y continuar? unblock it and continue?}
+message wannatry {¿Quieres probar?}
+message create_cgd {Crear cifrado de volumen (CGD)}
+message create_cnd {Crear imagen de disco virtual (VND)}
+message create_vg {Crear grupo de volúmenes (LVM VG)}
+message create_lv {      Crear volúmenes lógicos}
+message create_raid {Crear RAID por software}
+message updpmlist {Actualizar lista de dispositivos}
+message savepm {Guardar los cambios}
+message pmblocked {BLOQUEADO}
+message pmunchanged {SIN USO}
+message pmsetboot {ARRANCAR}
+message pmused {UTILIZA}
+message pmmounted {(montado)}
+message pmunused {(sin usar)}
+message pmgptdisk {Disco con GPT}
+
+message finishpm {Finalizar el particionado}
+message limitcount {Límite para el número de dispositivos se llegó!}
+message invaliddev {No válido dispositivo!}
+message avdisks {Discos disponibles:}
+message nofreedev {No se puede asignar nodo de dispositivo!}
+message partman_header
+{Partition Manager. Todos los discos, particiones y etc muestra allí.
+Al principio, las particiones MBR hacen, a continuación, hacer etiquetas BSD.
+Si desea utilizar RAID, LVM o CGD, siga estos pasos:
+1) Crear particiones BSD con el tipo necesario;
+2) Crear RAID / LVM VG / CGD el uso de estas particiones; 3) Guárdalo;
+4) Crear particiones de volúmenes RAID / CGD o lógico de LVM.}
+
+message raid_menufmt {   raid%d (nivel %1d) en %-34s %11uM}
+message raid_err_menufmt {   RAID VACIO!}
+message raid_disks_fmt {Discos: %32s}
+message raid_spares_fmt {Piezas de recambio: %20s}
+message raid_level_fmt {RAID de nivel:    %22d}
+message raid_numrow_fmt {numRow:           %22d}
+message raid_numcol_fmt {numCol:           %22d}
+message raid_numspare_fmt {numSpare:         %22d}
+message raid_sectpersu_fmt {sectPerSU:        %22d}
+message raid_superpar_fmt {SUsPerParityUnit: %22d}
+message raid_superrec_fmt {SUsPerReconUnit:  %22d}
+message raid_nomultidim {Matrices multidimensionales no son compatibles!}
+message raid_numrow_ask {numRow?}
+message raid_numcol_ask {numCol?}
+message raid_numspare_ask {numSpare?}
+message raid_sectpersu_ask {sectPerSU?}
+message raid_superpar_ask {SUsPerParityUnit?}
+message raid_superrec_ask {SUsPerReconUnit?}
+message raid_disks {Los discos en RAID:}
+message vnd_err_menufmt {   CAMINO NO DEFINIDO!}
+message vnd_assgn_menufmt {   vnd%1d en %-51s ASSIGN}
+message vnd_menufmt {   vnd%1d en %-45s %11uM}
+message vnd_path_fmt {Ruta del archivo: %22s}
+message vnd_assgn_fmt {Asignar existe la imagen: %14s}
+message vnd_size_fmt {Tamaño:          %22sM}
+message vnd_ro_fmt {Sólo lectura:     %22s}
+message vnd_geom_fmt {Establecer la geometría de la mano: %4s}
+message vnd_bps_fmt {Bytes por sector:     %18s}
+message vnd_spt_fmt {Sectores por pista:   %18s}
+message vnd_tpc_fmt {Pistas por cilindro:  %18s}
+message vnd_cyl_fmt {Cilindros:        %22s}
+message vnd_path_ask {Ruta de acceso?}
+message vnd_size_ask {Tamaño (MB)?}
+message vnd_bps_ask {Bytes por sector?}
+message vnd_spt_ask {Sectores por pista?}
+message vnd_tpc_ask {Pistas por cilindro?}
+message vnd_cyl_ask {Cilindros}
+message cgd_err_menufmt {   DISCO NO SE DEFINE!}
+message cgd_menufmt {   cgd%1d %-48s %11uM}
+message cgd_dev_fmt {Dispositivo de base: %19s}
+message cgd_enc_fmt {Encriptación:        %19s}
+message cgd_key_fmt {Tamaño de la clave:  %19d}
+message cgd_iv_fmt {Algoritmo IV:        %19s}
+message cgd_keygen_fmt {La generación de claves: %15s}
+message cgd_verif_fmt {Método de verificación:  %15s}
+message lvm_disks {Discos en VG:}
+message lvm_menufmt {   %-44s %20sM}
+message lvm_err_menufmt {   VACIAR VG!}
+message lvm_disks_fmt {PV's: %34s}
+message lvm_name_fmt {Nombre: %32s}
+message lvm_maxlv_fmt {MaxLogicalVolumes:  %20s}
+message lvm_maxpv_fmt {MaxPhysicalVolumes: %20s}
+message lvm_extsiz_fmt {PhysicalExtentSize: %20s}
+message lvm_name_ask {Nombre?}
+message lvm_maxlv_ask {MaxLogicalVolumes?}
+message lvm_maxpv_ask {MaxPhysicalVolumes?}
+message lvm_extsiz_ask {PhysicalExtentSize (MB)?}
+message lvmlv_menufmt {      El volumen lógico %-33s% 11uM}
+message lvmlv_name_fmt {Nombre: %32s}
+message lvmlv_size_fmt {Tamaño: %31dM}
+message lvmlv_ro_fmt {Sólo lectura:  %25s}
+message lvmlv_cont_fmt {Contigua:      %25s}
+message lvmlv_extnum_fmt {LogicalExtentsNumber: %18s}
+message lvmlv_minor_fmt {Menor número:  %25s}
+message lvmlv_mirrors_fmt {Espejos:       %25d}
+message lvmlv_regsiz_fmt {MirrorLogRegionSize:  %18s}
+message lvmlv_pers_fmt {Número de persistente menor: %11s}
+message lvmlv_readahsect_fmt {ReadAheadSectors:     %18s}
+message lvmlv_stripes_fmt {Rayas:         %25s}
+message lvmlv_stripesiz_fmt {Stripesize:    %25s}
+message lvmlv_zero_fmt {Puesta a cero de la primera KB: %8s}
+message lvmlv_name_ask {Nombre?}
+message lvmlv_size_ask {Tamaño (MB)?}
+message lvmlv_extnum_ask {LogicalExtentsNumber?}
+message lvmlv_minor_ask {Número menor de edad?}
+message lvmlv_mirrors_ask {Espejos?}
+message lvmlv_regsiz_ask {MirrorLogRegionSize?}
+message lvmlv_readahsect_ask {ReadAheadSectors?}
+message lvmlv_stripes_ask {Rayas?}
diff --git a/distrib/utils/sysinst/msg.mi.fr b/distrib/utils/sysinst/msg.mi.fr
index 2e00429..b4d2c12 100644
--- a/distrib/utils/sysinst/msg.mi.fr
+++ b/distrib/utils/sysinst/msg.mi.fr
@@ -35,7 +35,7 @@
 /* MI Message catalog -- french, machine independent */
 
 message usage
-{utilisation : sysinst [-r version] [-f fichier de définition]
+{utilisation : sysinst [-r version] [-f fichier de définition] [-C bg:fg]
 }
 
 /*
@@ -517,21 +517,13 @@ message nonet
 Retour au menu précédent.
 }
 
-message netup
-{Les interfaces réseau suivantes sont utilisables : %s
-Quelle interface souhaitez-vous utiliser ?
-}
-
 message asknetdev
-{Les interfaces suivantes sont utilisables : %s
+{Les interfaces suivantes sont utilisables.
 Quelle interface doit être utilisée ?
 }
 
-message badnet
-{Vous n'avez pas choisi une interface réseau dans la liste.
-Veuillez essayer à nouveau.
-Les interfaces réseau suivantes sont utilisables : %s
-\nQuel est votre choix ?}
+message netdevs
+{Interfaces disponibles}
 
 message netinfo
 {Veuillez répondre aux points suivants afin de pouvoir utiliser
@@ -605,11 +597,6 @@ message slattach {
 Entrez les "flags" slattach
 }
 
-message netagain
-{
-Veuillez spécifier de nouveau les paramètres réseau.
-}
-
 message wait_network
 {
 Veuillez patienter pendant la configuration de l'interface...
@@ -988,8 +975,9 @@ message Install_NetBSD_to_hard_disk {Installation de NetBSD sur disque dur}
 message Upgrade_NetBSD_on_a_hard_disk {Mise à jour de NetBSD sur disque dur}
 message Re_install_sets_or_install_additional_sets {Réinstaller ou installer de nouveaux composants}
 message Reboot_the_computer {Redémarrer l'ordinateur}
+message Config_menu {Menu config}
 message Utility_menu {Utilitaires}
-message exit_utility_menu {Quitter}
+message exit_menu_generic {Quitter}
 message NetBSD_VERSION_Utilities {Utilitaires NetBSD-@@VERSION@@}
 message Run_bin_sh {Exécuter /bin/sh}
 message Set_timezone {Configurer le fuseau horaire}
@@ -1043,6 +1031,11 @@ message other {autre }
 message Perform_IPv6_autoconfiguration {Configurer automatiquement l'IPv6 ?}
 message Perform_DHCP_autoconfiguration {Configurer automatiquement par DHCP ?}
 message Root_shell {Shell du compte "root"}
+message Color_scheme {Jeu de couleurs}
+message White_on_black {Blanc sur noir}
+message Black_on_white {Noir sur blanc}
+message White_on_blue {Blanc sur bleu}
+message Green_on_black {Vert sur noir}
 
 .if AOUT2ELF
 message aoutfail
@@ -1111,6 +1104,10 @@ message enable_sshd {Activer sshd}
 message enable_ntpd {Activer ntpd}
 message run_ntpdate {Executer ntpdate au démarrage}
 message enable_mdnsd {Activer mdnsd}
+message enable_xdm {Activer xdm}
+message enable_cgd {Activer cgd}
+message enable_lvm {Activer lvm}
+message enable_raid {Activer raidframe}
 message configmenu {Configurer les items suivants si nécéssaire.}
 message doneconfig {Configuration terminée}
 message Install_pkgin {Installer pkgin et mettre à jour le sommaire des paquetages}
@@ -1134,8 +1131,153 @@ message Pkgsrc_dir {R
 message get_pkgsrc
 {Obtenir et extraire pkgsrc afin de compiler des paquetages à partir des sources}
 message retry_pkgsrc_network {La configuration du réseau a échoué. Réessayer ?}
-message quit_pkgsrc {Quitter sans installer pkgsrc}
+message quit_install {Quitter sans installer pkgsrc} /*TODO*/
 message pkgin_failed 
 {L'installation de pkgin a échoué, peut-être parce que son paquetage binaire
 n'existe pas.  Vérifiez le chemin et essayez à nouveau.}
 message failed {Échoué}
+
+
+message notsupported {Le fonctionnement n'est pas pris en charge!}
+message askfsmountadv {Point de montage ou de 'raid' ou 'cgd' ou 'lvm'?}
+message partman {Partitionnement étendue}
+message editbsdpart {Modifier les partitions BSD}
+message editmbr {Modifiez et enregistrez MBR}
+message switchgpt {Mettre à GPT}
+message switchmbr {Basculer vers MBR}
+message renamedisk {Définir le nom du disque}
+message fmtasraid {Format en RAID}
+message fmtaslvm {Format de LVM PV}
+message encrypt {Crypter}
+message setbootable {Drapeau d'amorçage}
+message erase {Fonction d'effacement sécurisé}
+message undo {Annuler les changements}
+message unconfig {Annulation de la configuration}
+message edit {Éditer}
+message doumount {Groupe umount}
+message fillzeros {Remplir de zéros}
+message fillrandom {Remplissez par des données aléatoires}
+message fillcrypto {Remplissez par crypto données}
+message raid0 {0 - Pas de parité, l'entrelacement seulement simple.}
+message raid1 {1 - Mirroring. La parité est le miroir.}
+message raid4 {4 - Entrelacement avec parité stockées sur le dernier composant. component.}
+message raid5 {5 - Entrelacement avec parité à tous les composants. components.}
+
+message fremove {ENLEVER}
+message remove {Supprimer}
+message add {Ajouter}
+message auto {auto}
+
+message removepartswarn {Cette supprimer toutes les partitions sur le disque. Voulez-vous continuer? want to continue?}
+message saveprompt {Enregistrer les modifications avant de terminer?}
+message cantsave {Aucune modification ne peut être sauvé.}
+message noroot {Aucune partition racine défini, ne peut pas continuer \n continue\n}
+message wannaunblock {L'appareil est bloqué. Voulez-vous forcer le débloquer et continuer? unblock it and continue?}
+message wannatry {Voulez-vous essayer?}
+message create_cgd {Le volume cryptographique Créer (CGD)}
+message create_cnd {Créer une image de disque virtuel (VND)}
+message create_vg {Créer un groupe de volumes LVM (VG)}
+message create_lv {      Créer un volume logique}
+message create_raid {Créer un RAID logiciel}
+message updpmlist {Mettre à jour la liste des dispositifs}
+message savepm {Enregistrer les modifications}
+message pmblocked {BLOQUE}
+message pmunchanged {INCHANGÉ}
+message pmsetboot {BOOT}
+message pmused {UTILISÉ}
+message pmmounted {(monté)}
+message pmunused {(non utilisé)}
+message pmgptdisk {Disque avec GPT}
+
+message finishpm {Terminer le partitionnement}
+message limitcount {Limite pour le nombre de dispositifs a été atteint!}
+message invaliddev {Blancs appareil!}
+message avdisks {Disques disponibles:}
+message nofreedev {Impossible d'allouer noeud de périphérique!}
+message partman_header
+{Gestionnaire de partition. Tous les disques, les partitions et etc affiché.
+Dans un premier temps partitions MBR faire, puis faire étiquette BSD.
+Si vous souhaitez utiliser RAID, LVM ou DMC, procédez comme suit:
+1) Créer les partitions BSD de type de besoin; 2) Créer un système RAID /
+LVM VG / DMC utilisation de ces partitions; 3) la sauver;
+4) Créer des partitions pour les volumes RAID / DMC ou logique par LVM.}
+
+message raid_menufmt {   raid%d (niveau %1d) sur %-32s %11uM}
+message raid_err_menufmt {   RAID VIDE!}
+message raid_disks_fmt {Disques: %31s}
+message raid_spares_fmt {Pièces de rechange: %20s}
+message raid_level_fmt {Niveau RAID:      %22d}
+message raid_numrow_fmt {numRow:           %22d}
+message raid_numcol_fmt {numCol:           %22d}
+message raid_numspare_fmt {numSpare:         %22d}
+message raid_sectpersu_fmt {sectPerSU:        %22d}
+message raid_superpar_fmt {SUsPerParityUnit: %22d}
+message raid_superrec_fmt {SUsPerReconUnit:  %22d}
+message raid_nomultidim {Tableaux multi-dimensionnels sont pas pris en charge!}
+message raid_numrow_ask {numRow?}
+message raid_numcol_ask {numCol?}
+message raid_numspare_ask {numSpare?}
+message raid_sectpersu_ask {sectPerSU?}
+message raid_superpar_ask {SUsPerParityUnit?}
+message raid_superrec_ask {SUsPerReconUnit?}
+message raid_disks {Disques en RAID:}
+message vnd_err_menufmt {   PATH NOT DEFINED!}
+message vnd_assgn_menufmt {   vnd%1d sur %-50s ASSIGN}
+message vnd_menufmt {   vnd%1d sur %-44s %11uM}
+message vnd_path_fmt {Chemin du fichier: %20s}
+message vnd_assgn_fmt {Attribuer existent image: %14s}
+message vnd_size_fmt {Taille:            %20sM}
+message vnd_ro_fmt {Read-only:          %20s}
+message vnd_geom_fmt {Définir la géométrie à la main: %8s}
+message vnd_bps_fmt {Octets par secteur: %20s}
+message vnd_spt_fmt {Secteurs par piste: %20s}
+message vnd_tpc_fmt {Pistes par cylindre: %19s}
+message vnd_cyl_fmt {Cylindres:          %20s}
+message vnd_path_ask {Chemin du fichier?}
+message vnd_size_ask {Taille (MB)?}
+message vnd_bps_ask {Octets par secteur?}
+message vnd_spt_ask {Secteurs par piste?}
+message vnd_tpc_ask {Pistes par cylindre?}
+message vnd_cyl_ask {Cylindres}
+message cgd_err_menufmt {   DISQUE NON DEFINI!}
+message cgd_menufmt {   cgd%1d %-48s %11uM}
+message cgd_dev_fmt {Dispositif de base: %20s}
+message cgd_enc_fmt {Chiffrage:          %20s}
+message cgd_key_fmt {Taille de la clé:   %20d}
+message cgd_iv_fmt {Algorithme IV:      %20s}
+message cgd_keygen_fmt {La génération des clés: %16s}
+message cgd_verif_fmt {Méthode de vérification: %15s}
+message lvm_disks {Disques à VG:}
+message lvm_menufmt {   %-44s %20sM}
+message lvm_err_menufmt {   VIDER VG!}
+message lvm_disks_fmt {PV's: %34s}
+message lvm_name_fmt {Nom: %35s}
+message lvm_maxlv_fmt {MaxLogicalVolumes:  %20s}
+message lvm_maxpv_fmt {MaxPhysicalVolumes: %20s}
+message lvm_extsiz_fmt {PhysicalExtentSize: %20s}
+message lvm_name_ask {Nom?}
+message lvm_maxlv_ask {MaxLogicalVolumes?}
+message lvm_maxpv_ask {MaxPhysicalVolumes?}
+message lvm_extsiz_ask {PhysicalExtentSize (MB)?}
+message lvmlv_menufmt {      Logique volume %-35s %11uM}
+message lvmlv_name_fmt {Nom: %35s}
+message lvmlv_size_fmt {Taille:   %29dM}
+message lvmlv_ro_fmt {Read-only: %29s}
+message lvmlv_cont_fmt {Contiguë:  %29s}
+message lvmlv_extnum_fmt {LogicalExtentsNumber: %18s}
+message lvmlv_minor_fmt {Nombre mineur: %25s}
+message lvmlv_mirrors_fmt {Miroirs:   %29d}
+message lvmlv_regsiz_fmt {MirrorLogRegionSize:  %18s}
+message lvmlv_pers_fmt {Persistante numéro mineur: %13s}
+message lvmlv_readahsect_fmt {ReadAheadSectors: %22s}
+message lvmlv_stripes_fmt {Rayures:    %28s}
+message lvmlv_stripesiz_fmt {Stripesize: %28s}
+message lvmlv_zero_fmt {Remise à zéro de la KB d'abord: %8s}
+message lvmlv_name_ask {Nom?}
+message lvmlv_size_ask {Taille (MB)?}
+message lvmlv_extnum_ask {LogicalExtentsNumber?}
+message lvmlv_minor_ask {Numéro mineur?}
+message lvmlv_mirrors_ask {Miroirs?}
+message lvmlv_regsiz_ask {MirrorLogRegionSize?}
+message lvmlv_readahsect_ask {ReadAheadSectors?}
+message lvmlv_stripes_ask {Stripes?}
diff --git a/distrib/utils/sysinst/msg.mi.pl b/distrib/utils/sysinst/msg.mi.pl
index 55b54af..6b74d96 100644
--- a/distrib/utils/sysinst/msg.mi.pl
+++ b/distrib/utils/sysinst/msg.mi.pl
@@ -37,7 +37,7 @@
 /* MI Message catalog -- polish, machine independent */
 
 message usage
-{uzycie: sysinst [-r wersja] [-f plik-definicji]
+{uzycie: sysinst [-r wersja] [-f plik-definicji] [-C bg:fg]
 }
 
 /*
@@ -491,18 +491,11 @@ message nonet
 Zostaniesz przeniesiony do glownego menu.
 }
 
-message netup
-{Nastepujace interfejsy sieciowe sa aktywne: %s
-Czy ktorys z nich jest podlaczony do serwera?}
-
 message asknetdev
-{Znalazlem nastepujace interfejsy sieciowe : %s
-\nKtorego urzadzenia mam uzyc?}
+{Znalazlem kilka interfejsy sieciowe. Ktorego urzadzenia mam uzyc?}
 
-message badnet
-{Nie wybrales zadnego z podanych urzadzen sieciowych. Sprobuj jeszcze raz.
-Nastepujace urzadzenie sieciowe sa dostepne: %s
-\nKtorego urzadzenia mam uzyc?}
+message netdevs
+{Dost?pne interfejsy}
 
 message netinfo
 {Aby mozna bylo uzywac sieci, potrzebujemy odpowiedzi na ponizsze pytania:
@@ -575,12 +568,6 @@ message slattach {
 Podaja parametry dla polecenia 'slattach'
 }
 
-message netagain
-{Wprowadz jeszcze raz informacje o twojej sieci. Twoje ostatnie odpowiedzi
-beda domyslnymi wartosciami.
-
-}
-
 message wait_network
 {
 Poczekaj, az interfejs sieciowy zostanie uaktywniony.
@@ -885,8 +872,9 @@ message Install_NetBSD_to_hard_disk {Zainstaluj NetBSD na twardym dysku}
 message Upgrade_NetBSD_on_a_hard_disk {Zaktualizuj NetBSD na twardym dysku}
 message Re_install_sets_or_install_additional_sets {Przeinstaluj albo zainstaluj dodatkowe pakiety}
 message Reboot_the_computer {Zrestartuj komputer}
+message Config_menu {Menu konfiguracji}
 message Utility_menu {Menu Narzedziowe}
-message exit_utility_menu {Exit}
+message exit_menu_generic {Nazad}
 message NetBSD_VERSION_Utilities {Narzedzia NetBSD-@@VERSION@@}
 message Run_bin_sh {Uruchom /bin/sh}
 message Set_timezone {Ustaw strefe czasowa}
@@ -940,6 +928,11 @@ message other {inny  }
 message Perform_IPv6_autoconfiguration {Wykonac autokonfiguracje IPv6?}
 message Perform_DHCP_autoconfiguration {Wykonac autkonfiguracje DHCP?}
 message Root_shell {Powloka root'a}
+message Color_scheme {Kolorystyka}
+message White_on_black {Bia³y na czarnym}
+message Black_on_white {Czarno na bia³ym}
+message White_on_blue {Bia³y na niebieskim}
+message Green_on_black {Zielony na czarnym}
 
 .if AOUT2ELF
 message aoutfail
@@ -995,10 +988,14 @@ message empty {***EMPTY***}
 message timezone {Timezone}
 message change_rootpw {Change root password}
 message enable_binpkg {Enable installation of binary packages}
-message enable_sshd {Enable sshd}
-message enable_ntpd {Enable ntpd}
+message enable_sshd {Umo¿liwiaæ sshd}
+message enable_ntpd {Umo¿liwiaæ ntpd}
 message run_ntpdate {Run ntpdate at boot}
 message enable_mdnsd {Enable mdnsd}
+message enable_xdm {Umo¿liwiaæ XDM}
+message enable_cgd {Umo¿liwiaæ CGD}
+message enable_lvm {Umo¿liwiaæ LVM}
+message enable_raid {Umo¿liwiaæ RAIDframe}
 message configmenu {Configure the additional items as needed.}
 message doneconfig {Finished configuring}
 message Install_pkgin {Install pkgin and update package summary}
@@ -1019,7 +1016,151 @@ will be used.  If "user" is "ftp", then the password is not needed.
 message Pkgsrc_dir {pkgsrc directory}
 message get_pkgsrc {Fetch and unpack pkgsrc for building from source}
 message retry_pkgsrc_network {Network configuration failed.  Retry?}
-message quit_pkgsrc {Quit without installing pkgsrc}
+message quit_install {Quit without installing pkgsrc} /*TODO*/
 message pkgin_failed 
 {Installation of pkgin failed, possibly because no binary packages  exist.  Please check the package path and try again.}
 message failed {Failed}
+
+message notsupported {Operacja nie jest obs³ugiwana!}
+message askfsmountadv {Montowania lub "raid" lub "cgd" lub "lvm"?}
+message partman {Partycje rozszerzone}
+message editbsdpart {Edytuj partycje BSD}
+message editmbr {Edytowaæ i zapisywaæ MBR}
+message switchgpt {Prze³±cz na GPT}
+message switchmbr {Prze³±cz na MBR}
+message renamedisk {Ustaw nazwê dysku}
+message fmtasraid {Format jak RAID}
+message fmtaslvm {Format jak LVM PV}
+message encrypt {Szyfrowanie}
+message setbootable {Bootable flaga}
+message erase {Bezpieczne kasowanie}
+message undo {Cofanie zmian}
+message unconfig {Zdekonfigurowanie}
+message edit {Edytuj}
+message doumount {Si³a umount}
+message fillzeros {Wype³nij zerami}
+message fillrandom {Wype³nij losowymi danymi}
+message fillcrypto {Wype³nij przez crypto danych}
+message raid0 {0 - brak parzysto¶ci, tylko proste rozk³adanie.}
+message raid1 {1 - Mirroring. Parytet jest lustro.}
+message raid4 {4 - Malowanie z parytetu przechowywanych w ostatniej czê¶ci.}
+message raid5 {5 - Malowanie z parytetu w tych wszystkich elementów.}
+
+message fremove {USUÑ}
+message remove {Usun±æ}
+message add {Dodaæ}
+message auto {auto}
+
+message removepartswarn {To usun±æ wszystkie partycje na dysku. Czy chcesz kontynuowaæ?}
+message saveprompt {Zapisz zmiany przed zakoñczeniem?}
+message cantsave {Zmiany nie mog± byæ zbawieni.}
+message noroot {No partycja zdefiniowana, nie mo¿e kontynuowaæ \n}
+message wannaunblock {Urz±dzenie jest zablokowane. Czy chcesz, aby zmusiæ go odblokowaæ i kontynuowaæ?}
+message wannatry {Czy chcesz spróbowaæ?}
+message create_cgd {Utwórz wolumen kryptograficznych (CGD)}
+message create_cnd {Utwórz wirtualnego obraz dysku (VND)}
+message create_vg {Utwórz grupê woluminów (LVM VG)}
+message create_lv {      Utwórz wolumin logiczny}
+message create_raid {Utwórz oprogramowania RAID}
+message updpmlist {Aktualizuj listê urz±dzeñ}
+message savepm {Zapisz zmiany}
+message pmblocked {ZABLOK.}
+message pmunchanged {BEZ ZMIAN}
+message pmsetboot {BOOT}
+message pmused {U¯YWANE}
+message pmmounted {(zamontowany)}
+message pmunused {(nieu¿ywany)}
+message pmgptdisk {Dysku z GPT}
+
+message finishpm {Zakoñcz partycjonowanie}
+message limitcount {Limit liczby urz±dzeñ zosta³ osi±gniêty!}
+message invaliddev {Nieprawid³owy urz±dzenie!}
+message avdisks {Dostêpne dysków:}
+message nofreedev {Nie mo¿na przydzieliæ wêze³!}
+message partman_header
+{Partition Manager. Wszystkie dyski, partycje oraz itp. tam wy¶wietlane.
+Pocz±tkowo sprawiaj± partycji MBR, a nastêpnie dokonaæ BSD etykietê.
+Je¶li chcesz korzystaæ z RAID, LVM lub CGD, wykonaj nastêpuj±ce kroki:
+1) Tworzenie partycji BSD z potrzebnego typu;
+2) Utwórz RAID / LVM VG / CGD korzystania z tych partycji; 3) Zapisz go;
+4) Tworzenie partycji dla RAID / CGD lub Logical Volumes dla LVM.}
+
+message raid_menufmt {   raid%d (level %1d) on %-34s %11uM}
+message raid_err_menufmt {   EMPTY RAID!}
+message raid_disks_fmt {Dyski: %33s}
+message raid_spares_fmt {Czê¶ci zamienne: %23s}
+message raid_level_fmt {Poziom RAID:     %23d}
+message raid_numrow_fmt {numRow:          %23d}
+message raid_numcol_fmt {numCol:          %23d}
+message raid_numspare_fmt {numSpare:        %23d}
+message raid_sectpersu_fmt {sectPerSU:        %22d}
+message raid_superpar_fmt {SUsPerParityUnit: %22d}
+message raid_superrec_fmt {SUsPerReconUnit:  %22d}
+message raid_nomultidim {Tablice wielowymiarowe nie s± obs³ugiwane!}
+message raid_numrow_ask {numRow?}
+message raid_numcol_ask {numCol?}
+message raid_numspare_ask {numSpare?}
+message raid_sectpersu_ask {sectPerSU?}
+message raid_superpar_ask {SUsPerParityUnit?}
+message raid_superrec_ask {SUsPerReconUnit?}
+message raid_disks {Dyski w RAID:}
+message vnd_err_menufmt {   ¦CIE¯KA NIE ZDEFINIOWANE!}
+message vnd_assgn_menufmt {   vnd%1d na %-51s ASSIGN}
+message vnd_menufmt {   vnd%1d na %-45s %11uM}
+message vnd_path_fmt {¦cie¿ka: %31s}
+message vnd_assgn_fmt {Przypisywanie istnieæ obraz: %11s}
+message vnd_size_fmt {Rozmiar: %30sM}
+message vnd_ro_fmt {Tylko do odczytu:   %20s}
+message vnd_geom_fmt {Ustaw geometriê rêcznie: %15s}
+message vnd_bps_fmt {Bajtów na sektorów: %20s}
+message vnd_spt_fmt {Sektory na ¶cie¿ki: %20s}
+message vnd_tpc_fmt {Utwory na cylinder: %20s}
+message vnd_cyl_fmt {Si³owniki:          %20s}
+message vnd_path_ask {File Path?}
+message vnd_size_ask {Rozmiar (MB)?}
+message vnd_bps_ask {Bajtów na sektor?}
+message vnd_spt_ask {Sektory na ¶cie¿kê?}
+message vnd_tpc_ask {Utwory na cylinder?}
+message vnd_cyl_ask {Cylindry}
+message cgd_err_menufmt {   DISK NIE ZDEFINIOWANE!}
+message cgd_menufmt {   cgd%1d %-48s %11uM}
+message cgd_dev_fmt {Urz±dzenie podstawy: %19s}
+message cgd_enc_fmt {Encyption:           %19s}
+message cgd_key_fmt {Rozmiar klucza:      %19d}
+message cgd_iv_fmt {Algorytm IV: %27s}
+message cgd_keygen_fmt {Generowanie kluczy: %20s}
+message cgd_verif_fmt {Metoda weryfikacji: %20s}
+message lvm_disks {Dyski w VG:}
+message lvm_menufmt {   %-44s %20sM}
+message lvm_err_menufmt {   EMPTY VG!}
+message lvm_disks_fmt {PV's: %34s}
+message lvm_name_fmt {Nazwa: %33s}
+message lvm_maxlv_fmt {MaxLogicalVolumes:  %20s}
+message lvm_maxpv_fmt {MaxPhysicalVolumes: %20s}
+message lvm_extsiz_fmt {PhysicalExtentSize: %20s}
+message lvm_name_ask {Nazwa?}
+message lvm_maxlv_ask {MaxLogicalVolumes?}
+message lvm_maxpv_ask {MaxPhysicalVolumes?}
+message lvm_extsiz_ask {PhysicalExtentSize (MB)?}
+message lvmlv_menufmt {      Wolumin logiczny%-34s %11uM}
+message lvmlv_name_fmt {Nazwa: %33s}
+message lvmlv_size_fmt {Rozmiar: %30dM}
+message lvmlv_ro_fmt {Read-only:       %23s}
+message lvmlv_cont_fmt {S±siaduj±cy:     %23s}
+message lvmlv_extnum_fmt {LogicalExtentsNumber: %18s}
+message lvmlv_minor_fmt {Mniejsza liczba: %23s}
+message lvmlv_mirrors_fmt {Mirrors:     %27d}
+message lvmlv_regsiz_fmt {MirrorLogRegionSize:  %18s}
+message lvmlv_pers_fmt {Trwa³e drobne numer:  %18s}
+message lvmlv_readahsect_fmt {ReadAheadSectors ceny: %17s}
+message lvmlv_stripes_fmt {Stripes:     %27s}
+message lvmlv_stripesiz_fmt {StripeSize:  %27s}
+message lvmlv_zero_fmt {Zerowanie pierwszej KB: %16s}
+message lvmlv_name_ask {Nazwa?}
+message lvmlv_size_ask {Rozmiar (MB)?}
+message lvmlv_extnum_ask {LogicalExtentsNumber?}
+message lvmlv_minor_ask {Mniejsza liczba?}
+message lvmlv_mirrors_ask {Mirrors?}
+message lvmlv_regsiz_ask {MirrorLogRegionSize?}
+message lvmlv_readahsect_ask {ReadAheadSectors?}
+message lvmlv_stripes_ask {Stripes?}
diff --git a/distrib/utils/sysinst/net.c b/distrib/utils/sysinst/net.c
index 160c904..96a9ffb 100644
--- a/distrib/utils/sysinst/net.c
+++ b/distrib/utils/sysinst/net.c
@@ -64,8 +64,12 @@
 
 int network_up = 0;
 /* Access to network information */
-static char *net_devices;
-static char *net_up;
+#define MAX_NETS 15
+struct net_desc {
+	char if_dev[STRSIZE];
+	char name[STRSIZE]; // TODO
+};
+
 static char net_dev[STRSIZE];
 static char net_domain[STRSIZE];
 static char net_host[STRSIZE];
@@ -200,7 +204,6 @@ url_encode(char *dst, const char *src, const char *ep,
 	return dst;
 }
 
-
 static const char *ignored_if_names[] = {
 	"eon",			/* netiso */
 	"gre",			/* net */
@@ -208,6 +211,7 @@ static const char *ignored_if_names[] = {
 	"gif",			/* netinet6 */
 	"faith",		/* netinet6 */
 	"lo",			/* net */
+	"lo0",			/* net */
 #if 0
 	"mdecap",		/* netinet -- never in IF list (?) XXX */
 #endif
@@ -222,24 +226,19 @@ static const char *ignored_if_names[] = {
 	NULL,
 };
 
-static void
-get_ifconfig_info(void)
+static int
+get_ifconfig_info(struct net_desc *devs)
 {
-	char *textbuf;
-	char *t, *nt;
+	char *buf_in;
+	char *buf_tmp;
 	const char **ignore;
+	char *buf;
+	char *tmp;
 	int textsize;
-	ulong fl;
-	char *cp;
-
-	free(net_devices);
-	net_devices = NULL;
-	free(net_up);
-	net_up = NULL;
+	int i;
 
 	/* Get ifconfig information */
-
-	textsize = collect(T_OUTPUT, &textbuf, "/sbin/ifconfig -a 2>/dev/null");
+	textsize = collect(T_OUTPUT, &buf_in, "/sbin/ifconfig -l 2>/dev/null");
 	if (textsize < 0) {
 		if (logfp)
 			(void)fprintf(logfp,
@@ -248,52 +247,31 @@ get_ifconfig_info(void)
 		exit(1);
 	}
 
-	for (t = textbuf; t != NULL && *t != 0; t = nt) {
-		/* find entry for next interface */
-		for (nt = t; (nt = strchr(nt, '\n')); ) {
-			if (*++nt != '\t')
-				break;
-		}
-		if (memcmp(t, "lo0:", 4) == 0)
-			/* completely ignore loopback interface */
-			continue;
-		cp = strchr(t, '=');
-		if (cp == NULL)
-			break;
-		/* get interface flags */
-		fl = strtoul(cp + 1, &cp, 16);
-		if (*cp != '<')
-			break;
+	buf = malloc (STRSIZE * sizeof(char));
+	for (i = 0, buf_tmp = buf_in; strlen(buf_tmp) > 0 && buf_tmp < buf_in +
+	     strlen(buf_in);) {
+		tmp = stpncpy(buf, buf_tmp, strcspn(buf_tmp," \n"));
+		*tmp='\0';
+		buf_tmp += (strcspn(buf_tmp, " \n") + 1) * sizeof(char);
 
+		/* Skip ignored interfaces */
 		for (ignore = ignored_if_names; *ignore != NULL; ignore++) {
 			size_t len = strlen(*ignore);
-			if (strncmp(t, *ignore, len) == 0 &&
-			    isdigit((unsigned char)t[len]))
+			if (strncmp(buf, *ignore, len) == 0 &&
+			    isdigit((unsigned char)buf[len]))
 				break;
 		}
 		if (*ignore != NULL)
 			continue;
 
-		if (fl & IFF_UP) {
-			/* This interface might be connected to the server */
-			cp = strchr(t, ':');
-			if (cp == NULL)
-				break;
-			asprintf(&cp, "%s%.*s ",
-			    net_up ? net_up : "", (int)(cp - t), t);
-			free(net_up);
-			net_up = cp;
-		}
-
-		cp = strchr(t, ':');
-		if (cp == NULL)
-			break;
-		asprintf(&cp, "%s%.*s ",
-		    net_devices ? net_devices : "", (int)(cp - t), t);
-		free(net_devices);
-		net_devices = cp;
+		strncpy (devs[i].if_dev, buf, STRSIZE);
+		i++;
 	}
-	free(textbuf);
+	strcpy(devs[i].if_dev, "\0");
+
+	free(buf);
+	free(buf_in);
+	return i;
 }
 
 static int
@@ -539,9 +517,6 @@ handle_license(const char *dev)
 int
 config_network(void)
 {
-	char *tp;
-	char *defname;
-	const char *prompt;
 	char *textbuf;
 	int  octet0;
 	int  dhcp_config;
@@ -551,8 +526,13 @@ config_network(void)
  	char **ap, *slcmd[10], *in_buf;
  	char buffer[STRSIZE];
  	struct statvfs sb;
+	struct net_desc net_devs[MAX_NETS];
+	menu_ent net_menu[5];
+	int menu_no;
+	int num_devs;
+	int selected_net;
 
-	int l;
+	int i;
 	char dhcp_host[STRSIZE];
 #ifdef INET6
 	int v6config = 1;
@@ -564,43 +544,38 @@ config_network(void)
 	if (network_up)
 		return (1);
 
-	get_ifconfig_info();
-
-	if (net_up != NULL) {
-		/* XXX: some retry loops come here... */
-		/* active interfaces found */
-		msg_display(MSG_netup, net_up);
-		process_menu(MENU_yesno, NULL);
-		if (!yesno)
-			return 0;
-	}
+	num_devs = get_ifconfig_info(net_devs);
 
-	if (net_devices == NULL) {
+	if (num_devs < 1) {
 		/* No network interfaces found! */
 		msg_display(MSG_nonet);
 		process_menu(MENU_ok, NULL);
 		return (-1);
 	}
-	network_up = 1;
 
-again:
-	tp = strchr(net_devices, ' ');
-	asprintf(&defname, "%.*s", (int)(tp - net_devices), net_devices);
-	for (prompt = MSG_asknetdev;; prompt = MSG_badnet) {
-		msg_prompt(prompt, defname, net_dev, sizeof net_dev - 1,
-		    net_devices);
-		l = strlen(net_dev);
-		net_dev[l] = ' ';
-		net_dev[l + 1] = 0;
-		tp = strstr(net_devices, net_dev);
-		if (tp == NULL)
-			continue;
-		if (tp != net_devices && tp[-1] != ' ')
-			continue;
-		net_dev[l] = 0;
-		break;
+	for (i = 0; i < num_devs; i++) {
+		net_menu[i].opt_name = net_devs[i].if_dev;
+		net_menu[i].opt_menu = OPT_NOMENU;
+		net_menu[i].opt_flags = OPT_EXIT;
+		net_menu[i].opt_action = set_menu_select;
 	}
-	free(defname);
+again:
+	selected_net = -1;
+	menu_no = new_menu(MSG_netdevs,
+		net_menu, num_devs, -1, 4, 0, 0,
+		MC_SCROLL,
+		NULL, NULL, NULL, NULL, NULL);
+	msg_display(MSG_asknetdev, "");
+	process_menu(menu_no, &selected_net);
+	free_menu(menu_no);
+	
+	if (selected_net == -1)
+	    return 0;
+
+	network_up = 1;
+
+	strncpy(net_dev, net_devs[selected_net].if_dev, STRSIZE);
+
 	if (!handle_license(net_dev))
 		goto done;
 
@@ -802,8 +777,7 @@ again:
 #endif
 done:
 	process_menu(MENU_yesno, deconst(MSG_netok_ok));
-	if (!yesno)
-		msg_display(MSG_netagain);
+
 	if (!yesno)
 		goto again;
 
@@ -1028,40 +1002,18 @@ do_ftp_fetch(const char *set_name, struct ftpinfo *f)
 	return rval ? SET_RETRY : SET_OK;
 }
 
-static int
-do_config_network(void)
-{
-	int ret;
-
-	while ((ret = config_network()) <= 0) {
-		if (ret < 0)
-			return (-1);
-		msg_display(MSG_netnotup);
-		process_menu(MENU_yesno, NULL);
-		if (!yesno) {
-			msg_display(MSG_netnotup_continueanyway);
-			process_menu(MENU_yesno, NULL);
-			if (!yesno)
-				return -1;
-			network_up = 1;
-			break;
-		}
-	}
-	return 0;
-}
+
+// XXX: check MSG_netnotup_continueanyway and MSG_netnotup
 
 int
 get_pkgsrc(void)
 {
-	if (!network_up)
-		if (do_config_network() != 0)
-			return SET_RETRY;
-
-	yesno = 1;
+	yesno = -1;
 	process_menu(MENU_pkgsrc, NULL);
 	
-	if (yesno == 0)
+	if (yesno == SET_SKIP)
 		return SET_SKIP;
+
 	fetch_fn = pkgsrc_fetch;
 	snprintf(ext_dir_pkgsrc, sizeof ext_dir_pkgsrc, "%s/%s",
 	    target_prefix(), xfer_dir + (*xfer_dir == '/'));
@@ -1072,11 +1024,11 @@ get_pkgsrc(void)
 int
 get_via_ftp(const char *xfer_type)
 {
-
-	if (do_config_network() != 0)
-		return SET_RETRY;
-
+	yesno = -1;
 	process_menu(MENU_ftpsource, deconst(xfer_type));
+	
+	if (yesno == SET_RETRY)
+		return SET_RETRY;
 
 	/* We'll fetch each file just before installing it */
 	fetch_fn = ftp_fetch;
@@ -1094,9 +1046,6 @@ get_via_nfs(void)
 {
 	struct statvfs sb;
 
-	if (do_config_network() != 0)
-		return SET_RETRY;
-
 	/* If root is on NFS and we have sets, skip this step. */
 	if (statvfs(set_dir_bin, &sb) == 0 &&
 	    strcmp(sb.f_fstypename, "nfs") == 0) {
@@ -1106,7 +1055,11 @@ get_via_nfs(void)
 	}
 
 	/* Get server and filepath */
+	yesno = -1;
 	process_menu(MENU_nfssource, NULL);
+	
+	if (yesno == SET_RETRY)
+		return SET_RETRY;
 
 	/* Mount it */
 	if (run_program(0, "/sbin/mount -r -o -2,-i,-r=1024 -t nfs %s:%s /mnt2",
diff --git a/distrib/utils/sysinst/partman.c b/distrib/utils/sysinst/partman.c
new file mode 100644
index 0000000..5d51743
--- /dev/null
+++ b/distrib/utils/sysinst/partman.c
@@ -0,0 +1,2767 @@
+/*	$NetBSD: partman.c,v 0.000 0000/00/00 00:00:00 uzixls Exp $ */
+
+/*
+ * Copyright 2012 Eugene Lozovoy
+ * 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.
+ * 3. The name of Eugene Lozovoy may not be used to endorse
+ *    or promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``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 PIERMONT INFORMATION SYSTEMS INC. 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.
+ *
+ */
+
+/* partman.c - extended partitioning */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <util.h>
+
+#include "defs.h"
+#include "msg_defs.h"
+#include "menu_defs.h"
+
+/* XXX: replace all MAX_ defince with depeding on kernel settings vars */
+#define MAX_ENTRIES 96
+
+#define MAX_RAID 8
+#define MAX_IN_RAID 48
+typedef struct raids_t {
+	int enabled;
+	int blocked;
+	int node;
+	char pm_name[MAX_IN_RAID][SSTRSIZE];
+	int pm_part[MAX_IN_RAID];
+	int pm_is_spare[MAX_IN_RAID];
+	int numRow, numCol, numSpare;
+	int sectPerSU, SUsPerParityUnit, SUsPerReconUnit, raid_level;
+	uint total_size;
+	pm_devs_t *pm[MAX_IN_RAID];
+} raids_t;
+raids_t raids[MAX_RAID];
+
+#define MAX_VND 4
+typedef struct vnds_t {
+	int enabled;
+	int blocked;
+	int node;
+	char filepath[STRSIZE];
+	int size;
+	int readonly;
+	int is_exist;
+	int manual_geom;
+	int secsize, nsectors, ntracks, ncylinders;
+	int pm_part;    /* Used only for */
+	pm_devs_t *pm;  /* reffering device */
+} vnds_t;
+vnds_t vnds[MAX_VND];
+
+#define MAX_CGD 4
+typedef struct cgds_t {
+	int enabled;
+	int blocked;
+	int node;
+	pm_devs_t *pm;
+	char pm_name[SSTRSIZE];
+	int pm_part;
+	const char *keygen_type;
+	const char *verify_type;
+	const char *enc_type;
+	const char *iv_type;
+	int key_size;
+} cgds_t;
+cgds_t cgds[MAX_CGD];
+
+#define MAX_LVM_VG 16
+#define MAX_LVM_PV 255
+#define MAX_LVM_LV 255
+typedef struct pv_t {
+	pm_devs_t *pm;
+	char pm_name[SSTRSIZE];
+	int pm_part;
+	int metadatasize;
+	int metadatacopies;
+	int labelsector;
+	int setphysicalvolumesize;
+} pv_t;
+typedef struct lv_t {
+	int blocked;
+	int size;
+	char name[SSTRSIZE];
+	int readonly;
+	int contiguous;
+	char extents[SSTRSIZE];
+	int minor;
+	int mirrors;
+	int regionsize;
+	int persistent;
+	int readahead;
+	int stripes;
+	int stripesize;
+	int zero;
+} lv_t;
+typedef struct lvms_t {
+	int enabled;
+	int blocked;
+	char name[SSTRSIZE];
+	int maxlogicalvolumes;
+	int maxphysicalvolumes;
+	int physicalextentsize;
+	uint total_size;
+	pv_t pv[MAX_LVM_PV];
+	lv_t lv[MAX_LVM_LV];
+} lvms_t;
+lvms_t lvms[MAX_LVM_VG];
+
+typedef struct structinfo_t {
+	int max;
+	uint entry_size;
+	uint parent_size;
+	void *entry_first;
+	void *entry_enabled;
+	void *entry_blocked;
+	void *entry_node;
+} structinfo_t;
+structinfo_t raids_t_info, vnds_t_info, cgds_t_info, lvms_t_info, lv_t_info;
+
+typedef struct pm_upddevlist_adv_t {
+	const char *create_msg;
+	int pe_type;
+	structinfo_t *s;
+	int sub_num;
+	struct pm_upddevlist_adv_t *sub;
+} pm_upddevlist_adv_t;
+
+#define MAX_MNTS 48
+struct {
+    char dev[STRSIZE];
+    const char *mnt_opts, *on;
+} mnts[MAX_MNTS];
+
+int cursel; /* Number of selected main menu entrie */
+int changed; /* flag indicating that we have unsaved changes */
+int raid_curspare; /* XXX: replace by true way */
+
+enum { /* RAIDframe menu enum */
+	PMR_MENU_DEVS, PMR_MENU_DEVSSPARE, PMR_MENU_RAIDLEVEL, PMR_MENU_NUMROW,
+	PMR_MENU_NUMCOL, PMR_MENU_NUMSPARE,	PMR_MENU_SECTPERSU,	PMR_MENU_SUSPERPARITYUNIT,
+	PMR_MENU_SUSPERRECONUNIT, PMR_MENU_REMOVE, PMR_MENU_END
+};
+
+enum { /* VND menu enum */
+	PMV_MENU_FILEPATH, PMV_MENU_EXIST, PMV_MENU_SIZE, PMV_MENU_RO, PMV_MENU_MGEOM,
+	PMV_MENU_SECSIZE, PMV_MENU_NSECTORS, PMV_MENU_NTRACKS, PMV_MENU_NCYLINDERS,
+	PMV_MENU_REMOVE, PMV_MENU_END
+};
+
+enum { /* CGD menu enum */
+	PMC_MENU_DEV, PMC_MENU_ENCTYPE, PMC_MENU_KEYSIZE, PMC_MENU_IVTYPE,
+	PMC_MENU_KEYGENTYPE, PMC_MENU_VERIFYTYPE, PMC_MENU_REMOVE, PMC_MENU_END
+};
+
+enum { /* LVM menu enum */
+	PML_MENU_PV, PML_MENU_NAME, PML_MENU_MAXLOGICALVOLUMES,
+	PML_MENU_MAXPHYSICALVOLUMES, PML_MENU_PHYSICALEXTENTSIZE, 
+	PML_MENU_REMOVE, PML_MENU_END
+};
+
+enum { /* LVM submenu (logical volumes) enum */
+	PMLV_MENU_NAME, PMLV_MENU_SIZE, PMLV_MENU_READONLY, PMLV_MENU_CONTIGUOUS,
+	PMLV_MENU_EXTENTS, PMLV_MENU_MINOR, PMLV_MENU_PERSISTENT,
+	PMLV_MENU_MIRRORS, PMLV_MENU_REGIONSIZE, PMLV_MENU_READAHEAD,
+	PMLV_MENU_STRIPES, PMLV_MENU_STRIPESIZE, PMLV_MENU_ZERO, 
+	PMLV_MENU_REMOVE, PMLV_MENU_END
+};
+
+part_entry_t pm_dev_list(int);
+static int pm_raid_disk_add(menudesc *, void *);
+static int pm_raid_disk_del(menudesc *, void *);
+static int pm_cgd_disk_set(cgds_t *, part_entry_t *);
+static int pm_mount(pm_devs_t *, int);
+static int pm_upddevlist(menudesc *, void *);
+static void pm_select(pm_devs_t *);
+
+/* Universal menu for RAID/VND/CGD/LVM entry edit */
+static int
+pm_edit(int menu_entries_count, void (*menu_fmt)(menudesc *, int, void *),
+	int (*action)(menudesc *, void *), int (*check_fun)(void *),
+	void (*entry_init)(void *, void *),	void *entry_init_arg,
+	void *dev_ptr, int dev_ptr_delta, structinfo_t *s)
+{
+	int i, ok = 0;
+
+	if (dev_ptr == NULL) {
+		/* We should create new device */
+		for (i = 0; i < s->max && !ok; i++)
+			if (*(int*)((char*)s->entry_enabled + dev_ptr_delta + s->entry_size * i) == 0) {
+				dev_ptr = (char*)s->entry_first + dev_ptr_delta + s->entry_size * i;
+				entry_init(dev_ptr, entry_init_arg);
+				ok = 1;
+			}
+		if (!ok) {
+			/* We do not have free device slots */
+			process_menu(MENU_ok, deconst(MSG_limitcount));
+			return -1;
+		}
+	}
+
+	menu_ent menu_entries[menu_entries_count];
+	for (i = 0; i < menu_entries_count - 1; i++)
+		menu_entries[i] = (menu_ent) {NULL, OPT_NOMENU, 0, action};
+	menu_entries[i] = (menu_ent) {MSG_fremove, OPT_NOMENU, OPT_EXIT, action};
+
+	int menu_no = -1;
+	menu_no = new_menu(NULL, menu_entries, menu_entries_count,
+		-1, -1, 0, 40, MC_NOCLEAR | MC_SCROLL,
+		NULL, menu_fmt, NULL, NULL, MSG_DONE);
+	
+	process_menu(menu_no, dev_ptr);
+	free_menu(menu_no);
+
+	return check_fun(dev_ptr);
+}
+
+static void
+pm_getdevstring(char *buf, int len, pm_devs_t *pm_cur, int num)
+{
+	int i;
+
+	if (pm_cur->isspecial)
+		snprintf(buf, len, "%s", pm_cur->diskdev);
+	else if (num + 'a' < 'a' || num + 'a' > 'a' + MAXPARTITIONS)
+		snprintf(buf, len, "%sd", pm_cur->diskdev);
+	else if (pm_cur->gpt) {
+		for (i = 0; i < MAX_WEDGES; i++)
+			if (wedges[i].pm == pm_cur &&
+				wedges[i].ptn == num)
+				snprintf(buf, len, "dk%d", i); // XXX: xxx
+	} else
+		snprintf(buf, len, "%s%c", pm_cur->diskdev, num + 'a');
+
+	return;
+}
+
+/* Show filtered partitions menu */
+part_entry_t
+pm_dev_list(int type)
+{
+	int dev_num = -1, num_devs = 0;
+	int i, ok;
+	int menu_no;
+	menu_ent menu_entries[MAX_DISKS*MAXPARTITIONS];
+	part_entry_t disk_entries[MAX_DISKS*MAXPARTITIONS];
+	pm_devs_t *pm_i;
+
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		for (i = 0; i < MAXPARTITIONS; i++) {
+			ok = 0;
+			switch (type) {
+				case PM_RAID_T:
+					if (pm_i->bsdlabel[i].pi_fstype == FS_RAID)
+						ok = 1;
+					break;
+				case PM_CGD_T:
+					if (pm_i->bsdlabel[i].pi_fstype == FS_CGD)
+						ok = 1;
+					break;
+				case PM_LVM_T:
+					if (pm_i->bsdlabel[i].lvmpv)
+						ok = 1;
+					break;
+			}
+			if (ok && pm_partusage(pm_i, i, 0) == 0) {
+				disk_entries[num_devs].dev_ptr = pm_i;
+				disk_entries[num_devs].dev_num = i;
+				pm_getdevstring(disk_entries[num_devs].fullname, SSTRSIZE, pm_i, i);
+
+				menu_entries[num_devs] = (struct menu_ent) {
+					.opt_name = disk_entries[num_devs].fullname,
+					.opt_action = set_menu_select,
+					.opt_menu = OPT_NOMENU,
+					.opt_flags = OPT_EXIT,
+				};
+				num_devs++;
+			}
+		}
+
+	menu_no = new_menu(MSG_avdisks,
+		menu_entries, num_devs, -1, -1, (num_devs+1<3)?3:num_devs+1, 13,
+		MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, NULL);
+	if (menu_no == -1)
+		return (part_entry_t) { .retvalue = -1, };
+	process_menu(menu_no, &dev_num);
+	free_menu(menu_no);
+
+	if (dev_num < 0 || dev_num >= num_devs)
+		return (part_entry_t) { .retvalue = -1, };
+
+	disk_entries[dev_num].retvalue = dev_num;
+	return disk_entries[dev_num];
+}
+
+/* Get unused raid*, cgd* or vnd* device */
+static int
+pm_manage_getfreenode(void *node, const char *d, structinfo_t *s)
+{
+	int i, ii, ok;
+	char buf[SSTRSIZE];
+	pm_devs_t *pm_i;
+
+	*(int*)node = -1;
+	for (i = 0; i < s->max; i++) {
+		ok = 1;
+		/* Check that node is not already reserved */
+		for (ii = 0; ii < s->max; ii++)
+			if (*(int*)((char*)s->entry_node + s->entry_size * ii) == i) {
+				ok = 0;
+				break;
+			}
+		if (! ok)
+			continue;
+		/* Check that node is not in the device list */
+		snprintf(buf, SSTRSIZE, "%s%d", d, i);
+		SLIST_FOREACH(pm_i, &pm_head, l)
+			if (! strcmp(pm_i->diskdev, buf)) {
+				ok = 0;
+				break;
+			}
+		if (ok) {
+			*(int*)node = i;
+			return i;
+		}
+	}
+	process_menu(MENU_ok, deconst(MSG_nofreedev));
+	return -1;
+}
+
+/***
+RAIDs
+***/
+
+static void
+pm_raid_menufmt(menudesc *m, int opt, void *arg)
+{
+	int i, ok = 0;
+	char buf[STRSIZE]; buf[0] = '\0';
+	raids_t *dev_ptr = ((part_entry_t *)arg)[opt].dev_ptr;
+
+	if (dev_ptr->enabled == 0)
+		return;
+	for (i = 0; i < MAX_IN_RAID; i++)
+		if (dev_ptr->pm[i] != NULL) {
+			strncat(buf, dev_ptr->pm_name[i], STRSIZE);
+			strncat(buf, " ", STRSIZE);
+			ok = 1;
+		}
+	if (ok)
+		wprintw(m->mw, msg_string(MSG_raid_menufmt), dev_ptr->node,
+			dev_ptr->raid_level, buf, dev_ptr->total_size);
+	else
+		wprintw(m->mw, "%s", msg_string(MSG_raid_err_menufmt));
+	return;
+}
+
+static void
+pm_raid_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	int i;
+	char buf[STRSIZE]; buf[0] = '\0';
+	raids_t *dev_ptr = arg;
+
+	switch (opt) {
+		case PMR_MENU_DEVS:
+			for (i = 0; i < MAX_IN_RAID; i++)
+				if (dev_ptr->pm[i] != NULL && dev_ptr->pm_is_spare[i] == 0)
+					snprintf(buf, STRSIZE, "%s %s", buf, dev_ptr->pm_name[i]);
+			wprintw(m->mw, msg_string(MSG_raid_disks_fmt), buf);
+			break;
+		case PMR_MENU_DEVSSPARE:
+			for (i = 0; i < MAX_IN_RAID; i++)
+				if (dev_ptr->pm[i] != NULL && dev_ptr->pm_is_spare[i] != 0)
+					snprintf(buf, STRSIZE, "%s %s", buf, dev_ptr->pm_name[i]);
+			wprintw(m->mw, msg_string(MSG_raid_spares_fmt), buf);
+			break;
+		case PMR_MENU_RAIDLEVEL:
+			wprintw(m->mw, msg_string(MSG_raid_level_fmt), dev_ptr->raid_level);
+			break;
+		case PMR_MENU_NUMROW:
+			wprintw(m->mw, msg_string(MSG_raid_numrow_fmt), dev_ptr->numRow);
+			break;
+		case PMR_MENU_NUMCOL:
+			wprintw(m->mw, msg_string(MSG_raid_numcol_fmt), dev_ptr->numCol);
+			break;
+		case PMR_MENU_NUMSPARE:
+			wprintw(m->mw, msg_string(MSG_raid_numspare_fmt), dev_ptr->numSpare);
+			break;
+		case PMR_MENU_SECTPERSU:
+			wprintw(m->mw, msg_string(MSG_raid_sectpersu_fmt), dev_ptr->sectPerSU);
+			break;
+		case PMR_MENU_SUSPERPARITYUNIT:
+			wprintw(m->mw, msg_string(MSG_raid_superpar_fmt), dev_ptr->SUsPerParityUnit);
+			break;
+		case PMR_MENU_SUSPERRECONUNIT:
+			wprintw(m->mw, msg_string(MSG_raid_superrec_fmt), dev_ptr->SUsPerReconUnit);
+			break;
+	}
+	return;
+}
+
+static int
+pm_raid_set_value(menudesc *m, void *arg)
+{
+	int retvalue = -1;
+	int *out_var = NULL;
+	char buf[SSTRSIZE];
+	const char *msg_to_show = NULL;
+	raids_t *dev_ptr = arg;
+
+	static menu_ent menuent_disk_adddel[] = {
+	    {MSG_add, OPT_NOMENU, OPT_EXIT, pm_raid_disk_add}, 
+	    {MSG_remove, OPT_NOMENU, OPT_EXIT, pm_raid_disk_del}
+	};
+	static int menu_disk_adddel = -1;
+	if (menu_disk_adddel == -1) {
+		menu_disk_adddel = new_menu(NULL, menuent_disk_adddel, nelem(menuent_disk_adddel),
+			-1, -1, 0, 10, MC_NOCLEAR, NULL, NULL, NULL, NULL, NULL);
+	}
+	
+	switch (m->cursel) {
+		case PMR_MENU_DEVS:
+			raid_curspare = 0;
+			process_menu(menu_disk_adddel, dev_ptr);
+			return 0;
+		case PMR_MENU_DEVSSPARE:
+			raid_curspare = 1;
+			process_menu(menu_disk_adddel, dev_ptr);
+			return 0;
+		case PMR_MENU_RAIDLEVEL:
+			process_menu(MENU_raidlevel, &retvalue);
+			if (retvalue >= 0)
+				dev_ptr->raid_level = retvalue;
+			return 0;
+		case PMR_MENU_NUMROW:
+			process_menu(MENU_ok, deconst(MSG_raid_nomultidim));
+			return 0;
+			msg_to_show = MSG_raid_numrow_ask;
+			out_var = &(dev_ptr->numRow);
+			break;
+		case PMR_MENU_NUMCOL:
+			msg_to_show = MSG_raid_numcol_ask;
+			out_var = &(dev_ptr->numCol);
+			break;
+		case PMR_MENU_NUMSPARE:
+			msg_to_show = MSG_raid_numspare_ask;
+			out_var = &(dev_ptr->numSpare);
+			break;
+		case PMR_MENU_SECTPERSU:
+			msg_to_show = MSG_raid_sectpersu_ask;
+			out_var = &(dev_ptr->sectPerSU);
+			break;
+		case PMR_MENU_SUSPERPARITYUNIT:
+			msg_to_show = MSG_raid_superpar_ask;
+			out_var = &(dev_ptr->SUsPerParityUnit);
+			break;
+		case PMR_MENU_SUSPERRECONUNIT:
+			msg_to_show = MSG_raid_superrec_ask;
+			out_var = &(dev_ptr->SUsPerReconUnit);
+			break;
+		case PMR_MENU_REMOVE:
+			dev_ptr->enabled = 0;
+			return 0;
+	}
+	if (out_var == NULL || msg_to_show == NULL)
+		return -1;
+	snprintf(buf, SSTRSIZE, "%d", *out_var);
+	msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE);
+	if (atoi(buf) >= 0)
+		*out_var = atoi(buf);
+	return 0;
+}
+
+static void
+pm_raid_init(void *arg, void *none)
+{
+	raids_t *dev_ptr = arg;
+	memset(dev_ptr, 0, sizeof(*dev_ptr));
+	*dev_ptr = (struct raids_t) {
+		.enabled = 1,
+		.blocked = 0,
+		.sectPerSU = 32,
+		.SUsPerParityUnit = 1,
+		.SUsPerReconUnit = 1,
+	};
+	return;
+}
+
+static int
+pm_raid_check(void *arg)
+{
+	int i, dev_num = 0, min_size = 0, cur_size = 0;
+	raids_t *dev_ptr = arg;
+
+	if (dev_ptr->blocked)
+		return 0;
+	for (i = 0; i < MAX_IN_RAID; i++)
+		if (dev_ptr->pm[i] != NULL) {
+			cur_size = dev_ptr->pm[i]->bsdlabel[dev_ptr->pm_part[i]].pi_size /
+						(MEG / dev_ptr->pm[i]->sectorsize);
+			if (cur_size < min_size || dev_num == 0)
+				min_size = cur_size;
+			if (!dev_ptr->pm_is_spare[i])
+				dev_num++;
+		}
+	/* Calculate summ of available space */
+	if (dev_num > 0) {
+		switch (dev_ptr->raid_level) {
+			case 0:
+				dev_ptr->total_size = min_size * dev_num;
+				break;
+			case 1:
+				dev_ptr->total_size = min_size;
+				break;
+			case 4:
+			case 5:
+				dev_ptr->total_size = min_size * (dev_num - 1);
+				break;
+		}
+		pm_manage_getfreenode(&(dev_ptr->node), "raid", &raids_t_info);
+		if (dev_ptr->node < 0)
+			dev_ptr->enabled = 0;
+	}
+	else
+		dev_ptr->enabled = 0;
+	return dev_ptr->enabled;
+}
+
+static int
+pm_raid_disk_add(menudesc *m, void *arg)
+{
+	int i;
+	raids_t *dev_ptr = arg;
+	part_entry_t disk_entrie = pm_dev_list(PM_RAID_T);
+	if (disk_entrie.retvalue < 0)
+		return disk_entrie.retvalue;
+
+	for (i = 0; i < MAX_IN_RAID; i++)
+		if (dev_ptr->pm[i] == NULL) {
+			dev_ptr->pm[i] = disk_entrie.dev_ptr;
+			dev_ptr->pm_part[i] = disk_entrie.dev_num;
+			dev_ptr->pm_is_spare[i] = raid_curspare;
+			strlcpy(dev_ptr->pm_name[i], disk_entrie.fullname, SSTRSIZE);
+			if (raid_curspare)
+				dev_ptr->numSpare++;
+			else
+				dev_ptr->numCol++;
+			dev_ptr->numRow = 1;
+			break;
+		}
+	return 0;
+}
+
+static int
+pm_raid_disk_del(menudesc *m, void *arg)
+{
+	int retvalue = -1, num_devs = 0;
+	int i, pm_cur;
+	int menu_no;
+	raids_t *dev_ptr = arg;
+	menu_ent menu_entries[MAX_IN_RAID];
+	part_entry_t submenu_args[MAX_IN_RAID];
+
+	for (i = 0; i < MAX_IN_RAID; i++) {
+		if (dev_ptr->pm[i] == NULL ||
+			dev_ptr->pm_is_spare[i] != raid_curspare)
+			continue;
+		menu_entries[num_devs] = (struct menu_ent) {
+			.opt_name = dev_ptr->pm_name[i],
+			.opt_action = set_menu_select,
+			.opt_menu = OPT_NOMENU,
+			.opt_flags = OPT_EXIT,
+		};
+		submenu_args[num_devs].dev_num = i;
+		num_devs++;
+	}
+
+	menu_no = new_menu(MSG_raid_disks,
+		menu_entries, num_devs, -1, -1, (num_devs+1<3)?3:num_devs+1, 13,
+		MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, NULL);
+	if (menu_no == -1)
+		return -1;
+	process_menu(menu_no, &retvalue);
+	free_menu(menu_no);
+
+	if (retvalue < 0 || retvalue >= num_devs)
+		return -1;
+
+	pm_cur = submenu_args[retvalue].dev_num;
+
+	if (dev_ptr->pm_is_spare[pm_cur])
+		dev_ptr->numSpare--;
+	else
+		dev_ptr->numCol--;
+	dev_ptr->numRow = (dev_ptr->numCol)?1:0;
+	dev_ptr->pm[pm_cur] = NULL;
+
+	return 0;
+}
+
+static int
+pm_raid_commit(void)
+{
+	int i, ii;
+	FILE *f;
+	char f_name[STRSIZE];
+
+	for (i = 0; i < MAX_RAID; i++) {
+		if (! pm_raid_check(&raids[i]))
+			continue;
+
+		/* Generating configure file for our raid */
+		snprintf(f_name, SSTRSIZE, "/tmp/raid.%d.conf", raids[i].node);
+		f = fopen(f_name, "w");
+		if (f == NULL) {
+			endwin();
+			(void)fprintf(stderr, "Could not open %s for writing\n", f_name);
+			if (logfp)
+				(void)fprintf(logfp, "Could not open %s for writing\n", f_name);
+			return 1;
+		}
+		scripting_fprintf(NULL, "cat <<EOF >%s\n", f_name);
+		scripting_fprintf(f, "START array\n%d %d %d\n", raids[i].numRow,
+							raids[i].numCol, raids[i].numSpare);
+
+		scripting_fprintf(f, "\nSTART disks\n");
+		for (ii = 0; ii < MAX_IN_RAID; ii++)
+			if (raids[i].pm[ii] != NULL && raids[i].pm_is_spare[ii] == 0) {
+				scripting_fprintf(f,  "/dev/%s\n", raids[i].pm_name[ii]);
+			}
+
+		scripting_fprintf(f, "\nSTART spare\n");
+		for (ii = 0; ii < MAX_IN_RAID; ii++)
+			if (raids[i].pm[ii] != NULL && raids[i].pm_is_spare[ii] != 0) {
+				scripting_fprintf(f,  "/dev/%s\n", raids[i].pm_name[ii]);
+			}
+
+		scripting_fprintf(f, "\nSTART layout\n%d %d %d %d\n", raids[i].sectPerSU,
+						raids[i].SUsPerParityUnit, raids[i].SUsPerReconUnit,
+						raids[i].raid_level);
+
+		scripting_fprintf(f, "\nSTART queue\nfifo 100\n\n");
+		scripting_fprintf(NULL, "EOF\n");
+		fclose (f);
+		fflush(NULL);
+
+		/* Raid initialization */
+		if (
+			run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -C %s raid%d",
+							f_name, raids[i].node) == 0 &&
+			run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -I %d raid%d",
+							rand(), raids[i].node) == 0 &&
+			run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -vi raid%d",
+							raids[i].node) == 0 &&
+			run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -v -A yes raid%d",
+							raids[i].node) == 0
+			) {
+			raids[i].blocked = 1; /* RAID creation done, remove it from list to 
+									 prevent it's repeated reinitialization */
+			for (ii = 0; ii < MAX_IN_RAID; ii++)
+				if (raids[i].pm[ii] != NULL)
+					raids[i].pm[ii]->blocked++;
+		}
+	}
+	return 0;
+}
+
+/***
+VND
+***/
+
+static void
+pm_vnd_menufmt(menudesc *m, int opt, void *arg)
+{
+	vnds_t *dev_ptr = ((part_entry_t *)arg)[opt].dev_ptr;
+
+	if (dev_ptr->enabled == 0)
+		return;
+	if (strlen(dev_ptr->filepath) < 1)
+		wprintw(m->mw, "%s", msg_string(MSG_vnd_err_menufmt));
+	else if (dev_ptr->is_exist)
+		wprintw(m->mw, msg_string(MSG_vnd_assgn_menufmt),
+			dev_ptr->node, dev_ptr->filepath);
+	else 
+		wprintw(m->mw, msg_string(MSG_vnd_menufmt),
+			dev_ptr->node, dev_ptr->filepath, dev_ptr->size);
+	return;
+}
+
+static void
+pm_vnd_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	vnds_t *dev_ptr = arg;
+	char buf[SSTRSIZE];
+	strcpy(buf, "-");
+
+	switch (opt) {
+		case PMV_MENU_FILEPATH:
+			wprintw(m->mw, msg_string(MSG_vnd_path_fmt), dev_ptr->filepath);
+			break;
+		case PMV_MENU_EXIST:
+			wprintw(m->mw, msg_string(MSG_vnd_assgn_fmt),
+				dev_ptr->is_exist? msg_string(MSG_Yes) : msg_string(MSG_No));
+			break;
+		case PMV_MENU_SIZE:
+			if (!dev_ptr->is_exist)
+				snprintf(buf, SSTRSIZE, "%d", dev_ptr->size);
+			wprintw(m->mw, msg_string(MSG_vnd_size_fmt), buf);
+			break;
+		case PMV_MENU_RO:
+			wprintw(m->mw, msg_string(MSG_vnd_ro_fmt),
+				dev_ptr->readonly? msg_string(MSG_Yes) : msg_string(MSG_No));
+			break;
+		case PMV_MENU_MGEOM:
+			if (!dev_ptr->is_exist)
+				snprintf(buf, SSTRSIZE, "%s",
+					dev_ptr->manual_geom? msg_string(MSG_Yes) : msg_string(MSG_No));
+			wprintw(m->mw, msg_string(MSG_vnd_geom_fmt), buf);
+			break;
+		case PMV_MENU_SECSIZE:
+			if (dev_ptr->manual_geom && !dev_ptr->is_exist)
+				snprintf(buf, SSTRSIZE, "%d", dev_ptr->secsize);
+			wprintw(m->mw, msg_string(MSG_vnd_bps_fmt), buf);
+			break;
+		case PMV_MENU_NSECTORS:
+			if (dev_ptr->manual_geom && !dev_ptr->is_exist)
+				snprintf(buf, SSTRSIZE, "%d", dev_ptr->nsectors);
+			wprintw(m->mw, msg_string(MSG_vnd_spt_fmt), buf);
+			break;
+		case PMV_MENU_NTRACKS:
+			if (dev_ptr->manual_geom && !dev_ptr->is_exist)
+				snprintf(buf, SSTRSIZE, "%d", dev_ptr->ntracks);
+			wprintw(m->mw, msg_string(MSG_vnd_tpc_fmt), buf);
+			break;
+		case PMV_MENU_NCYLINDERS:
+			if (dev_ptr->manual_geom && !dev_ptr->is_exist)
+				snprintf(buf, SSTRSIZE, "%d", dev_ptr->ncylinders);
+			wprintw(m->mw, msg_string(MSG_vnd_cyl_fmt), buf);
+			break;
+	}
+	return;
+}
+
+static int
+pm_vnd_set_value(menudesc *m, void *arg)
+{
+	vnds_t *dev_ptr = arg;
+	char buf[STRSIZE];
+	const char *msg_to_show = NULL;
+	int *out_var = NULL;
+	
+	switch (m->cursel) {
+		case PMV_MENU_FILEPATH:
+			msg_prompt_win(MSG_vnd_path_ask, -1, 18, 0, 0, dev_ptr->filepath,
+				dev_ptr->filepath, STRSIZE);
+			if (dev_ptr->filepath[0] != '/') {
+				strlcpy(buf, dev_ptr->filepath, MOUNTLEN);
+				snprintf(dev_ptr->filepath, MOUNTLEN, "/%s", buf);
+			}
+			if (dev_ptr->filepath[strlen(dev_ptr->filepath) - 1] == '/')
+				dev_ptr->filepath[strlen(dev_ptr->filepath) - 1] = '\0';
+			return 0;
+		case PMV_MENU_EXIST:
+			dev_ptr->is_exist = !dev_ptr->is_exist;
+			return 0;
+		case PMV_MENU_SIZE:
+			if (dev_ptr->is_exist)
+				return 0;
+			msg_to_show = MSG_vnd_size_ask;
+			out_var = &(dev_ptr->size);
+			break;
+		case PMV_MENU_RO:
+			dev_ptr->readonly = !dev_ptr->readonly;
+			return 0;
+		case PMV_MENU_MGEOM:
+			if (dev_ptr->is_exist)
+				return 0;
+			dev_ptr->manual_geom = !dev_ptr->manual_geom;
+			return 0;
+		case PMV_MENU_SECSIZE:
+			if (!dev_ptr->manual_geom || dev_ptr->is_exist)
+				return 0;
+			msg_to_show = MSG_vnd_bps_ask;
+			out_var = &(dev_ptr->secsize);
+			break;
+		case PMV_MENU_NSECTORS:
+			if (!dev_ptr->manual_geom || dev_ptr->is_exist)
+				return 0;
+			msg_to_show = MSG_vnd_spt_ask;
+			out_var = &(dev_ptr->nsectors);
+			break;
+		case PMV_MENU_NTRACKS:
+			if (!dev_ptr->manual_geom || dev_ptr->is_exist)
+				return 0;
+			msg_to_show = MSG_vnd_tpc_ask;
+			out_var = &(dev_ptr->ntracks);
+			break;
+		case PMV_MENU_NCYLINDERS:
+			if (!dev_ptr->manual_geom || dev_ptr->is_exist)
+				return 0;
+			msg_to_show = MSG_vnd_cyl_ask;
+			out_var = &(dev_ptr->ncylinders);
+			break;
+		case PMV_MENU_REMOVE:
+			dev_ptr->enabled = 0;
+			return 0;
+	}
+	if (out_var == NULL || msg_to_show == NULL)
+		return -1;
+	snprintf(buf, SSTRSIZE, "%d", *out_var);
+	msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE);
+	if (atoi(buf) >= 0)
+		*out_var = atoi(buf);
+	return 0;
+}
+
+static void
+pm_vnd_init(void *arg, void *none)
+{
+	vnds_t *dev_ptr = arg;
+	memset(dev_ptr, 0, sizeof(*dev_ptr));
+	*dev_ptr = (struct vnds_t) {
+		.enabled = 1,
+		.blocked = 0,
+		.filepath[0] = '\0',
+		.is_exist = 0,
+		.size = 1024,
+		.readonly = 0,
+		.manual_geom = 0,
+		.secsize = 512,
+		.nsectors = 18,
+		.ntracks = 2,
+		.ncylinders = 80
+	};
+	return;
+}
+
+static int
+pm_vnd_check(void *arg)
+{
+	vnds_t *dev_ptr = arg;
+
+	if (dev_ptr->blocked)
+		return 0;
+	if (strlen(dev_ptr->filepath) < 1 ||
+			dev_ptr->size < 1)
+		dev_ptr->enabled = 0;
+	else {
+		pm_manage_getfreenode(&(dev_ptr->node), "vnd", &vnds_t_info);
+		if (dev_ptr->node < 0)
+			dev_ptr->enabled = 0;
+	}
+	return dev_ptr->enabled;
+}
+
+/* XXX: vnconfig always return 0? */
+static int
+pm_vnd_commit(void)
+{
+	int i, ii, error, part_suit = -1;
+	char r_o[3], buf[MOUNTLEN+3], resultpath[STRSIZE]; 
+	pm_devs_t *pm_i, *pm_suit = NULL;
+
+	for (i = 0; i < MAX_VND; i++) {
+		error = 0;
+		if (! pm_vnd_check(&vnds[i]))
+			continue;
+
+		/* Trying to assign target device */
+		SLIST_FOREACH(pm_i, &pm_head, l)
+			for (ii = 0; ii < 6; ii++) {
+				strcpy(buf, pm_i->bsdlabel[ii].pi_mount);
+				if (buf[strlen(buf)-1] != '/')
+					sprintf(buf,"%s/", buf);
+				printf("%s\n",buf);
+				if (strstr(vnds[i].filepath, buf) == vnds[i].filepath)
+					if (part_suit < 0 || pm_suit == NULL ||
+						strlen(buf) > strlen(pm_suit->bsdlabel[part_suit].pi_mount)) {
+						part_suit = ii;
+						pm_suit = pm_i;
+					}
+			}
+		if (part_suit < 0 || pm_suit == NULL || 
+			pm_suit->bsdlabel[part_suit].mnt_opts == NULL ||
+			! (pm_suit->bsdlabel[part_suit].pi_flags & PIF_MOUNT))
+			continue;
+		
+		/* Mounting assigned partition and try to get real file path*/
+		if (pm_mount(pm_suit, part_suit) != 0)
+			continue;
+		snprintf(resultpath, STRSIZE, "%s/%s",
+			pm_suit->bsdlabel[part_suit].mounted,
+			&(vnds[i].filepath[strlen(pm_suit->bsdlabel[part_suit].pi_mount)]));
+
+		strcpy(r_o, vnds[i].readonly?"-r":"");
+		/* If this is a new image */
+		if (!vnds[i].is_exist) {
+			run_program(RUN_DISPLAY | RUN_PROGRESS, "mkdir -p %s ", dirname(resultpath));
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+						"dd if=/dev/zero of=%s bs=1m count=%d progress=100 msgfmt=human",
+						resultpath, vnds[i].size);
+		}
+		if (error)
+			continue;
+		/* If this is a new image with manual geometry */
+		if (!vnds[i].is_exist && vnds[i].manual_geom)
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+						"vnconfig %s vnd%d %s %d %d %d %d", r_o, vnds[i].node,
+						resultpath, vnds[i].secsize, vnds[i].nsectors,
+						vnds[i].ntracks, vnds[i].ncylinders);
+		/* If this is a existent image or image without manual geometry */
+		else
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS, "vnconfig %s vnd%d %s",
+						r_o, vnds[i].node, resultpath);
+
+		if (! error) {
+			vnds[i].blocked = 1;
+			vnds[i].pm_part = part_suit;
+			vnds[i].pm = pm_suit;
+			vnds[i].pm->blocked++;
+		}
+	}
+	return 0;
+}
+
+/***
+CGD
+***/
+
+static void
+pm_cgd_menufmt(menudesc *m, int opt, void *arg)
+{
+	cgds_t *dev_ptr = ((part_entry_t *)arg)[opt].dev_ptr;
+	char desc[STRSIZE];
+
+	if (dev_ptr->enabled == 0)
+		return;
+	if (dev_ptr->pm == NULL)
+		wprintw(m->mw, "%s", msg_string(MSG_cgd_err_menufmt));
+	else {
+		snprintf(desc, STRSIZE, "(%s-%d) on %s", dev_ptr->enc_type,
+			dev_ptr->key_size, dev_ptr->pm_name);
+		wprintw(m->mw, msg_string(MSG_cgd_menufmt), dev_ptr->node, desc,
+			dev_ptr->pm->bsdlabel[dev_ptr->pm_part].pi_size /
+							(MEG / dev_ptr->pm->sectorsize));
+	}
+	return;
+}
+
+static void
+pm_cgd_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	cgds_t *dev_ptr = arg;
+	switch (opt) {
+		case PMC_MENU_DEV:
+			wprintw(m->mw, msg_string(MSG_cgd_dev_fmt), dev_ptr->pm_name);
+			break;
+		case PMC_MENU_ENCTYPE:
+			wprintw(m->mw, msg_string(MSG_cgd_enc_fmt), dev_ptr->enc_type);
+			break;
+		case PMC_MENU_KEYSIZE:
+			wprintw(m->mw, msg_string(MSG_cgd_key_fmt), dev_ptr->key_size);
+			break;
+		case PMC_MENU_IVTYPE:
+			wprintw(m->mw, msg_string(MSG_cgd_iv_fmt), dev_ptr->iv_type);
+			break;
+		case PMC_MENU_KEYGENTYPE:
+			wprintw(m->mw, msg_string(MSG_cgd_keygen_fmt), dev_ptr->keygen_type);
+			break;
+		case PMC_MENU_VERIFYTYPE:
+			wprintw(m->mw, msg_string(MSG_cgd_verif_fmt), dev_ptr->verify_type);
+			break;
+	}
+	return;
+}
+
+static int
+pm_cgd_set_value(menudesc *m, void *arg)
+{
+	char *retstring;
+	cgds_t *dev_ptr = arg;
+
+	switch (m->cursel) {
+		case PMC_MENU_DEV:
+			pm_cgd_disk_set(dev_ptr, NULL);
+			return 0;
+		case PMC_MENU_ENCTYPE:
+			process_menu(MENU_cgd_enctype, &retstring);
+			dev_ptr->enc_type = retstring;
+			if (! strcmp(retstring, "blowfish-cbc"))
+				dev_ptr->key_size = 128;
+			if (! strcmp(retstring, "3des-cbc"))
+				dev_ptr->key_size = 192;
+			return 0;
+		case PMC_MENU_KEYSIZE:
+			if (! strcmp(dev_ptr->enc_type, "aes-cbc"))
+				dev_ptr->key_size +=
+					(dev_ptr->key_size < 256)? 64 : -128;
+			if (! strcmp(dev_ptr->enc_type, "blowfish-cbc"))
+				dev_ptr->key_size = 128;
+			if (! strcmp(dev_ptr->enc_type, "3des-cbc"))
+				dev_ptr->key_size = 192;
+			return 0;
+		case PMC_MENU_IVTYPE:
+			process_menu(MENU_cgd_ivtype, &retstring);
+			dev_ptr->iv_type = retstring;
+			return 0;
+		case PMC_MENU_KEYGENTYPE:
+			process_menu(MENU_cgd_keygentype, &retstring);
+			dev_ptr->keygen_type = retstring;
+			return 0;
+		case PMC_MENU_VERIFYTYPE:
+			process_menu(MENU_cgd_verifytype, &retstring);
+			dev_ptr->verify_type = retstring;
+			return 0;
+		case PMC_MENU_REMOVE:
+			dev_ptr->enabled = 0;
+			return 0;
+	}
+	return -1;
+}
+
+static void
+pm_cgd_init(void *arg1, void *arg2)
+{
+	cgds_t *dev_ptr = arg1;
+	part_entry_t *disk_entrie = arg2;
+
+	memset(dev_ptr, 0, sizeof(*dev_ptr));
+	*dev_ptr = (struct cgds_t) {
+		.enabled = 1,
+		.blocked = 0,
+		.pm = NULL,
+		.pm_name[0] = '\0',
+		.pm_part = 0,
+		.keygen_type = "pkcs5_pbkdf2/sha1",
+		.verify_type = "disklabel",
+		.enc_type = "aes-cbc",
+		.iv_type = "encblkno1",
+		.key_size = 192,
+	};
+	if (disk_entrie != NULL) {
+		pm_getdevstring(disk_entrie->fullname, SSTRSIZE,
+			disk_entrie->dev_ptr, disk_entrie->dev_num);
+		pm_cgd_disk_set(dev_ptr, disk_entrie);
+	}
+	return;
+}
+
+static int
+pm_cgd_check(void *arg)
+{
+	cgds_t *dev_ptr = arg;
+
+	if (dev_ptr->blocked)
+		return 0;
+	if (dev_ptr->pm == NULL)
+		dev_ptr->enabled = 0;
+	else
+		pm_manage_getfreenode(&(dev_ptr->node), "cgd", &cgds_t_info);
+		if (dev_ptr->node < 0)
+			dev_ptr->enabled = 0;
+	return dev_ptr->enabled;
+}
+
+static int
+pm_cgd_disk_set(cgds_t *dev_ptr, part_entry_t *disk_entrie)
+{
+	int alloc_disk_entrie = 0;
+	if (disk_entrie == NULL) {
+		alloc_disk_entrie = 1;
+		disk_entrie = malloc (sizeof(part_entry_t));
+		if (disk_entrie == NULL)
+			return -2;
+		*disk_entrie = pm_dev_list(PM_CGD_T);
+		if (disk_entrie->retvalue < 0) {
+			free(disk_entrie);
+			return -1;
+		}
+	}
+	dev_ptr->pm = disk_entrie->dev_ptr;
+	dev_ptr->pm_part = disk_entrie->dev_num;
+	strlcpy(dev_ptr->pm_name, disk_entrie->fullname, SSTRSIZE);
+
+	if (alloc_disk_entrie)
+		free(disk_entrie);
+	return 0;
+}
+
+int
+pm_cgd_edit(void *dev_ptr, part_entry_t *disk_entrie)
+{
+	if (disk_entrie != NULL)
+		dev_ptr = NULL;
+	return pm_edit(PMC_MENU_END, pm_cgd_edit_menufmt,
+		pm_cgd_set_value, pm_cgd_check, pm_cgd_init,
+		disk_entrie, dev_ptr, 0, &cgds_t_info);
+}
+
+static int
+pm_cgd_commit(void)
+{
+	int i, error = 0;
+	for (i = 0; i < MAX_CGD; i++) {
+		if (! pm_cgd_check(&cgds[i]))
+			continue;
+		if (run_program(RUN_DISPLAY | RUN_PROGRESS,
+			"cgdconfig -g -i %s -k %s -o /tmp/cgd.%d.conf %s %d",
+			cgds[i].iv_type, cgds[i].keygen_type, cgds[i].node,
+			cgds[i].enc_type, cgds[i].key_size) != 0) {
+			error++;
+			continue;
+		}
+		if (run_program(RUN_DISPLAY | RUN_PROGRESS,
+			"cgdconfig -V re-enter cgd%d /dev/%s /tmp/cgd.%d.conf",
+			cgds[i].node, cgds[i].pm_name, cgds[i].node) != 0) {
+			error++;
+			continue;
+		}
+		cgds[i].pm->blocked++;
+		cgds[i].blocked = 1;
+	}
+	return error;
+}
+
+/***
+LVM
+***/
+
+/* Add lvm logical volumes to pm list */
+/* XXX: rewrite */
+static int
+pm_lvm_find(void)
+{
+	int i, ii, already_found;
+	char dev[STRSIZE];
+	pm_devs_t *pm_i;
+
+	for (i = 0; i < MAX_LVM_VG; i++) {
+		if (! lvms[i].blocked)
+			continue;
+		for (ii = 0; ii < MAX_LVM_LV; ii++) {
+			if (! lvms[i].lv[ii].blocked || lvms[i].lv[ii].size < 1)
+				continue;
+			snprintf(dev, STRSIZE, "%s/%s", lvms[i].name, lvms[i].lv[ii].name);
+			already_found = 0;
+			SLIST_FOREACH(pm_i, &pm_head, l)
+				if (!already_found && strcmp(pm_i->diskdev, dev) == 0) {
+					pm_i->found = 1;
+					already_found = 1;
+				}
+			if (already_found)
+				/* We already added this device, skipping */
+				continue;
+			pm_new->found = 1;
+			pm_new->isspecial = 1;
+			pm_new->refdev = &lvms[i].lv[ii];
+			pm_new->sectorsize = 1;
+			pm_new->dlcylsize = MEG;
+			pm_new->bsdlabel[0].pi_size = MEG * lvms[i].lv[ii].size;
+			strlcpy(pm_new->diskdev, dev, SSTRSIZE);
+			strlcpy(pm_new->diskdev_descr, dev, STRSIZE);
+
+			if (SLIST_EMPTY(&pm_head))
+				 SLIST_INSERT_HEAD(&pm_head, pm_new, l);
+			else
+				 SLIST_INSERT_AFTER(pm_i, pm_new, l);
+			pm_new = malloc(sizeof (pm_devs_t));
+			memset(pm_new, 0, sizeof *pm_new);
+		}
+	}
+	return 0;
+}
+
+static int
+pm_lvm_disk_add(menudesc *m, void *arg)
+{
+	int i;
+	lvms_t *dev_ptr = arg;
+	part_entry_t disk_entrie = pm_dev_list(PM_LVM_T);
+	if (disk_entrie.retvalue < 0)
+		return disk_entrie.retvalue;
+
+	for (i = 0; i < MAX_LVM_PV; i++)
+		if (dev_ptr->pv[i].pm == NULL) {
+			dev_ptr->pv[i].pm = disk_entrie.dev_ptr;
+			dev_ptr->pv[i].pm_part = disk_entrie.dev_num;
+			strlcpy(dev_ptr->pv[i].pm_name, disk_entrie.fullname, SSTRSIZE);
+			break;
+		}
+	return 0;
+}
+
+static int
+pm_lvm_disk_del(menudesc *m, void *arg)
+{
+	int i, retvalue = -1, num_devs = 0;
+	int menu_no;
+	lvms_t *dev_ptr = arg;
+	menu_ent menu_entries[MAX_LVM_PV];
+	part_entry_t submenu_args[MAX_LVM_PV];
+
+	for (i = 0; i < MAX_LVM_PV; i++) {
+		if (dev_ptr->pv[i].pm == NULL)
+			continue;
+		menu_entries[num_devs] = (struct menu_ent) {
+			.opt_name = dev_ptr->pv[i].pm_name,
+			.opt_action = set_menu_select,
+			.opt_menu = OPT_NOMENU,
+			.opt_flags = OPT_EXIT,
+		};
+		submenu_args[num_devs].dev_num = i;
+		num_devs++;
+	}
+
+	menu_no = new_menu(MSG_lvm_disks,
+		menu_entries, num_devs, -1, -1, (num_devs+1<3)?3:num_devs+1, 13,
+		MC_SCROLL | MC_NOCLEAR, NULL, NULL, NULL, NULL, NULL);
+	if (menu_no == -1)
+		return -1;
+	process_menu(menu_no, &retvalue);
+	free_menu(menu_no);
+
+	if (retvalue < 0 || retvalue >= num_devs)
+		return -1;
+
+	dev_ptr->pv[submenu_args[retvalue].dev_num].pm = NULL;
+
+	return 0;
+}
+
+static void
+pm_lvm_menufmt(menudesc *m, int opt, void *arg)
+{
+	int i, ok = 0, used_size = 0;
+	char buf1[STRSIZE]; buf1[0] = '\0';
+	char buf2[STRSIZE]; buf2[0] = '\0';
+	lvms_t *dev_ptr = ((part_entry_t *)arg)[opt].dev_ptr;
+
+	if (dev_ptr->enabled == 0)
+		return;
+	snprintf(buf1, STRSIZE, "VG '%s' on ", dev_ptr->name);
+	for (i = 0; i < MAX_LVM_PV; i++)
+		if (dev_ptr->pv[i].pm != NULL) {
+			strncat(buf1, dev_ptr->pv[i].pm_name, STRSIZE);
+			strncat(buf1, " ", STRSIZE);
+			ok = 1;
+		}
+	for (i = 0; i < MAX_LVM_LV; i++)
+		used_size += dev_ptr->lv[i].size;
+	if (ok) {
+		snprintf(buf2, STRSIZE, "%d/%u",
+			dev_ptr->total_size - used_size, dev_ptr->total_size);
+		wprintw(m->mw, msg_string(MSG_lvm_menufmt), buf1, buf2);
+	} else
+		wprintw(m->mw, "%s", msg_string(MSG_lvm_err_menufmt));
+	return;
+}
+
+static void
+pm_lvm_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	int i;
+	char buf[STRSIZE];
+	lvms_t *dev_ptr = arg;
+	strlcpy(buf, msg_string(MSG_auto), STRSIZE);
+
+	switch (opt) {
+		case PML_MENU_PV:
+			buf[0] = '\0';
+			for (i = 0; i < MAX_LVM_PV; i++)
+				if (dev_ptr->pv[i].pm != NULL)
+					snprintf(buf, STRSIZE, "%s %s", buf, dev_ptr->pv[i].pm_name);
+			wprintw(m->mw, msg_string(MSG_lvm_disks_fmt), buf);
+			break;
+		case PML_MENU_NAME:
+			wprintw(m->mw, msg_string(MSG_lvm_name_fmt), dev_ptr->name);
+			break;
+		case PML_MENU_MAXLOGICALVOLUMES:
+			if (dev_ptr->maxlogicalvolumes > 0)
+				snprintf(buf, STRSIZE, "%d", dev_ptr->maxlogicalvolumes);
+			wprintw(m->mw, msg_string(MSG_lvm_maxlv_fmt), buf);
+			break;
+		case PML_MENU_MAXPHYSICALVOLUMES:
+			if (dev_ptr->maxphysicalvolumes > 0)
+				snprintf(buf, STRSIZE, "%d", dev_ptr->maxphysicalvolumes);
+			wprintw(m->mw, msg_string(MSG_lvm_maxpv_fmt), buf);
+			break;
+		case PML_MENU_PHYSICALEXTENTSIZE:
+			if (dev_ptr->physicalextentsize > 0)
+				snprintf(buf, STRSIZE, "%dM", dev_ptr->physicalextentsize);
+			wprintw(m->mw, msg_string(MSG_lvm_extsiz_fmt), buf);
+			break;
+	}
+	return;
+}
+
+static int
+pm_lvm_set_value(menudesc *m, void *arg)
+{
+	char buf[STRSIZE];
+	const char *msg_to_show = NULL;
+	int *out_var = NULL;
+	lvms_t *dev_ptr = arg;
+
+	static menu_ent menuent_disk_adddel[] = {
+	    {MSG_add, OPT_NOMENU, OPT_EXIT, pm_lvm_disk_add}, 
+	    {MSG_remove, OPT_NOMENU, OPT_EXIT, pm_lvm_disk_del}
+	};
+	static int menu_disk_adddel = -1;
+	if (menu_disk_adddel == -1) {
+		menu_disk_adddel = new_menu(NULL, menuent_disk_adddel, nelem(menuent_disk_adddel),
+			-1, -1, 0, 10, MC_NOCLEAR, NULL, NULL, NULL, NULL, NULL);
+	}
+
+	switch (m->cursel) {
+		case PML_MENU_PV:
+			process_menu(menu_disk_adddel, arg);
+			return 0;
+		case PML_MENU_NAME:
+			msg_prompt_win(MSG_lvm_name_ask, -1, 18, 0, 0, dev_ptr->name, dev_ptr->name, SSTRSIZE);
+			return 0;
+		case PML_MENU_MAXLOGICALVOLUMES:
+			msg_to_show = MSG_lvm_maxlv_ask;
+			out_var = &(dev_ptr->maxlogicalvolumes);			
+			break;
+		case PML_MENU_MAXPHYSICALVOLUMES:
+			msg_to_show = MSG_lvm_maxpv_ask;
+			out_var = &(dev_ptr->maxphysicalvolumes);
+			break;
+		case PML_MENU_PHYSICALEXTENTSIZE:
+			msg_to_show = MSG_lvm_extsiz_ask;
+			out_var = &(dev_ptr->physicalextentsize);
+			break;
+		case PML_MENU_REMOVE:
+			dev_ptr->enabled = 0;
+			return 0;
+	}
+	if (out_var == NULL || msg_to_show == NULL)
+		return -1;
+	snprintf(buf, SSTRSIZE, "%d", *out_var);
+	msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE);
+	if (atoi(buf) >= 0)
+		*out_var = atoi(buf);
+	return 0;
+}
+
+static void
+pm_lvm_init(void *arg, void* none)
+{
+	lvms_t *dev_ptr = arg;
+
+	memset(dev_ptr, 0, sizeof *dev_ptr);
+	*dev_ptr = (struct lvms_t) {
+		.enabled = 1,
+		.blocked = 0,
+		.maxlogicalvolumes = MAX_LVM_PV,
+		.maxphysicalvolumes = MAX_LVM_LV,
+		.physicalextentsize = -1,
+	};
+	sprintf(dev_ptr->name, "vg%.2d", rand()%100);
+	return;
+}
+
+static int
+pm_lvm_check(void *arg)
+{
+	int i, ok = 0;
+	lvms_t *dev_ptr = arg;
+	dev_ptr->total_size = 0;
+
+	for (i = 0; i < MAX_LVM_PV; i++)
+		if (dev_ptr->pv[i].pm != NULL) {
+			ok = 1;
+			dev_ptr->total_size += dev_ptr->pv[i].pm->
+						bsdlabel[dev_ptr->pv[i].pm_part].pi_size /
+						(MEG / dev_ptr->pv[i].pm->sectorsize);
+		}
+	if (! ok)
+		dev_ptr->enabled = 0;
+	return dev_ptr->enabled;
+}
+
+static void
+pm_lvmlv_menufmt(menudesc *m, int opt, void *arg)
+{
+	char buf[STRSIZE];
+	lv_t *dev_ptr = ((part_entry_t *)arg)[opt].dev_ptr;
+
+	if (dev_ptr->size > 0) {
+		snprintf(buf, STRSIZE, "'%s'", dev_ptr->name);
+		wprintw(m->mw, msg_string(MSG_lvmlv_menufmt), buf, dev_ptr->size);
+	}
+	return;
+}
+
+static void
+pm_lvmlv_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+
+	lv_t *dev_ptr = arg;
+	char buf[STRSIZE];
+	strlcpy(buf, msg_string(MSG_auto), STRSIZE);
+
+	switch (opt) {
+		case PMLV_MENU_NAME:
+			wprintw(m->mw, msg_string(MSG_lvmlv_name_fmt), dev_ptr->name);
+			break;
+		case PMLV_MENU_SIZE:
+			wprintw(m->mw, msg_string(MSG_lvmlv_size_fmt), dev_ptr->size);
+			break;
+		case PMLV_MENU_READONLY:
+			wprintw(m->mw, msg_string(MSG_lvmlv_ro_fmt),
+				dev_ptr->readonly? msg_string(MSG_Yes) : msg_string(MSG_No));
+			break;
+		case PMLV_MENU_CONTIGUOUS:
+			wprintw(m->mw, msg_string(MSG_lvmlv_cont_fmt),
+				dev_ptr->contiguous? msg_string(MSG_Yes) : msg_string(MSG_No));
+			break;
+		case PMLV_MENU_EXTENTS:
+			wprintw(m->mw, msg_string(MSG_lvmlv_extnum_fmt),
+				(strlen(dev_ptr->extents) > 0)? dev_ptr->extents : msg_string(MSG_auto));
+			break;
+		case PMLV_MENU_MINOR:
+			if (dev_ptr->minor > 0)
+				snprintf(buf, STRSIZE, "%dK", dev_ptr->minor);
+			wprintw(m->mw, msg_string(MSG_lvmlv_minor_fmt), buf);
+			break;
+		case PMLV_MENU_MIRRORS:
+			wprintw(m->mw, msg_string(MSG_lvmlv_mirrors_fmt), dev_ptr->mirrors);
+			break;
+		case PMLV_MENU_REGIONSIZE:
+			if (dev_ptr->regionsize > 0)
+				snprintf(buf, STRSIZE, "%dM", dev_ptr->regionsize);
+			wprintw(m->mw, msg_string(MSG_lvmlv_regsiz_fmt), buf);
+			break;
+		case PMLV_MENU_PERSISTENT:
+			wprintw(m->mw, msg_string(MSG_lvmlv_pers_fmt),
+				dev_ptr->persistent ? msg_string(MSG_Yes) : msg_string(MSG_No));
+			break;
+		case PMLV_MENU_READAHEAD:
+			if (dev_ptr->readahead > 0)
+				snprintf(buf, STRSIZE, "%d", dev_ptr->readahead);
+			wprintw(m->mw, msg_string(MSG_lvmlv_readahsect_fmt), buf);
+			break;
+		case PMLV_MENU_STRIPES:
+			if (dev_ptr->stripes > 0)
+				snprintf(buf, STRSIZE, "%d", dev_ptr->stripes);
+			wprintw(m->mw, msg_string(MSG_lvmlv_stripes_fmt), buf);
+			break;
+		case PMLV_MENU_STRIPESIZE:
+			if (dev_ptr->stripesize > 0)
+				snprintf(buf, STRSIZE, "%dK", dev_ptr->stripesize);
+			wprintw(m->mw, msg_string(MSG_lvmlv_stripesiz_fmt), buf);
+			break;
+		case PMLV_MENU_ZERO:
+			wprintw(m->mw, msg_string(MSG_lvmlv_zero_fmt),
+				dev_ptr->zero? msg_string(MSG_Yes) : msg_string(MSG_No));
+			break;
+	}
+	return;
+}
+
+static int
+pm_lvmlv_set_value(menudesc *m, void *arg)
+{
+	char buf[STRSIZE];
+	const char *msg_to_show = NULL;
+	int *out_var = NULL;
+	lv_t *dev_ptr = arg;
+
+	switch (m->cursel) {
+		case PMLV_MENU_NAME:
+			msg_prompt_win(MSG_lvmlv_name_ask, -1, 18, 0, 0, dev_ptr->name, dev_ptr->name,
+				SSTRSIZE);
+			return 0;
+		case PMLV_MENU_SIZE:
+			msg_to_show = MSG_lvmlv_size_ask;
+			out_var = &(dev_ptr->size);
+			break;
+		case PMLV_MENU_READONLY:
+			dev_ptr->readonly = !dev_ptr->readonly;
+			return 0;
+		case PMLV_MENU_CONTIGUOUS:
+			dev_ptr->contiguous = !dev_ptr->contiguous;
+			return 0;
+		case PMLV_MENU_EXTENTS:
+			msg_prompt_win(MSG_lvmlv_extnum_ask, -1, 18, 0, 0,
+				dev_ptr->extents, dev_ptr->extents, SSTRSIZE);
+			return 0;
+		case PMLV_MENU_MINOR:
+			msg_to_show = MSG_lvmlv_minor_ask;
+			out_var = &(dev_ptr->minor);
+			break;
+		case PMLV_MENU_MIRRORS:
+			msg_to_show = MSG_lvmlv_mirrors_ask;
+			out_var = &(dev_ptr->mirrors);
+			break;
+		case PMLV_MENU_REGIONSIZE:
+			msg_to_show = MSG_lvmlv_regsiz_ask;
+			out_var = &(dev_ptr->regionsize);
+			break;
+		case PMLV_MENU_PERSISTENT:
+			dev_ptr->persistent = !dev_ptr->persistent;
+			return 0;
+		case PMLV_MENU_READAHEAD:
+			msg_to_show = MSG_lvmlv_readahsect_ask;
+			out_var = &(dev_ptr->readahead);
+			break;
+		case PMLV_MENU_STRIPES:
+			msg_to_show = MSG_lvmlv_stripes_ask;
+			out_var = &(dev_ptr->stripes);
+			break;
+		case PMLV_MENU_STRIPESIZE:
+			if (dev_ptr->stripesize << 1 > 512)
+				dev_ptr->stripesize = 4;	
+			else
+				dev_ptr->stripesize <<= 1;
+			return 0;
+		case PMLV_MENU_ZERO:
+			dev_ptr->zero = !dev_ptr->zero;
+			return 0;
+		case PMLV_MENU_REMOVE:
+			dev_ptr->size = 0;
+			return 0;
+	}
+	if (out_var == NULL || msg_to_show == NULL)
+		return -1;
+	snprintf(buf, SSTRSIZE, "%d", *out_var);
+	msg_prompt_win(msg_to_show, -1, 18, 0, 0, buf, buf, SSTRSIZE);
+	if (atoi(buf) >= 0)
+		*out_var = atoi(buf);
+	return 0;
+}
+
+static void
+pm_lvmlv_init(void *arg, void *none)
+{
+	lv_t *dev_ptr = arg;
+	memset(dev_ptr, 0, sizeof *(dev_ptr));
+	*dev_ptr = (struct lv_t) {
+		.blocked = 0,
+		.size = 1024,
+		.stripesize = 64,
+	};
+	sprintf (dev_ptr->name, "lvol%.2d", rand()%100);
+	return;
+}
+
+static int
+pm_lvmlv_check(void *arg)
+{
+	lv_t *dev_ptr = arg;
+	if (dev_ptr->size > 0 && strlen(dev_ptr->name) > 0)
+		return 1;
+	else {
+		dev_ptr->size = 0;
+		return 0;
+	}
+}
+
+static int
+pm_lvm_commit(void)
+{
+	int i, ii, error;
+	uint used_size = 0;
+	char params[STRSIZE*3];
+	char devs[STRSIZE*3];
+
+	for (i = 0; i < MAX_LVM_VG; i++) {
+		/* Stage 0: checks */
+		if (! pm_lvm_check(&lvms[i]))
+			continue;
+		for (ii = 0; ii < MAX_LVM_LV; ii++)
+			used_size += lvms[i].lv[ii].size;
+		if (used_size > lvms[i].total_size)
+			continue;
+
+		params[0] = '\0';
+		devs[0] = '\0';
+		error = 0;
+		/* Stage 1: creating Physical Volumes (PV's) */
+		for (ii = 0; ii < MAX_LVM_PV && ! error; ii++)
+			if (lvms[i].pv[ii].pm != NULL) {
+				run_program(RUN_SILENT | RUN_ERROR_OK, 
+										"lvm pvremove -ffy /dev/r%s",
+										(char*)lvms[i].pv[ii].pm_name);
+				error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+										"lvm pvcreate -ffy /dev/r%s",
+										(char*)lvms[i].pv[ii].pm_name);
+				if (error)
+					break;
+				snprintf(devs, STRSIZE*3, "%s /dev/r%s", devs, (char*)lvms[i].pv[ii].pm_name);
+			}
+		if (error)
+			continue;
+		/* Stage 2: creating Volume Groups (VG's) */
+		if (lvms[i].maxlogicalvolumes > 0)
+			snprintf(params, STRSIZE*3, "%s -l %d", params, lvms[i].maxlogicalvolumes);
+		if (lvms[i].maxphysicalvolumes > 0)
+			snprintf(params, STRSIZE*3, "%s -p %d", params, lvms[i].maxphysicalvolumes);
+		if (lvms[i].physicalextentsize > 0)
+			snprintf(params, STRSIZE*3, "%s -s %d", params, lvms[i].physicalextentsize);
+		error += run_program(RUN_DISPLAY | RUN_PROGRESS, "lvm vgcreate %s %s %s",
+							params, lvms[i].name, devs);
+		if (error)
+			continue;
+		/* Stage 3: creating Logical Volumes (LV's) */
+		for (ii = 0; ii < MAX_LVM_LV; ii++) {
+			if (lvms[i].lv[ii].size <= 0)
+				continue;
+
+			params[0] = '\0';
+			snprintf(params, STRSIZE*3, "%s -C %c", params, lvms[i].lv[ii].contiguous?'y':'n');
+			snprintf(params, STRSIZE*3, "%s -M %c", params, lvms[i].lv[ii].persistent?'y':'n');
+			snprintf(params, STRSIZE*3, "%s -p %s", params, lvms[i].lv[ii].readonly?"r":"rw");
+			snprintf(params, STRSIZE*3, "%s -Z %c", params, lvms[i].lv[ii].zero?'y':'n');
+			if (strlen(lvms[i].lv[ii].name) > 0)
+				snprintf(params, STRSIZE*3, "%s -n %s", params, lvms[i].lv[ii].name);
+			if (strlen(lvms[i].lv[ii].extents) > 0)
+				snprintf(params, STRSIZE*3, "%s -l %s", params, lvms[i].lv[ii].extents);
+			if (lvms[i].lv[ii].minor > 0)
+				snprintf(params, STRSIZE*3, "%s --minor %d", params, lvms[i].lv[ii].minor);
+			if (lvms[i].lv[ii].mirrors > 0) {
+				snprintf(params, STRSIZE*3, "%s -m %d", params, lvms[i].lv[ii].mirrors);
+				if (lvms[i].lv[ii].regionsize > 0)
+					snprintf(params, STRSIZE*3, "%s -R %d", params, lvms[i].lv[ii].regionsize);
+			}
+			if (lvms[i].lv[ii].readahead > 0)
+				snprintf(params, STRSIZE*3, "%s -r %d", params, lvms[i].lv[ii].readahead);
+			if (lvms[i].lv[ii].stripes > 0) {
+				snprintf(params, STRSIZE*3, "%s -i %d", params, lvms[i].lv[ii].stripes);
+				if (lvms[i].lv[ii].stripesize > 0)
+					snprintf(params, STRSIZE*3, "%s -I %d", params, lvms[i].lv[ii].stripesize);
+			}
+			snprintf(params, STRSIZE*3, "%s -L %uM", params, lvms[i].lv[ii].size);
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS, "lvm lvcreate %s %s",
+									params, lvms[i].name);
+		}
+		if (! error) {
+			lvms[i].blocked = 1;
+			for (ii = 0; ii < MAX_LVM_PV; ii++)
+				if (lvms[i].pv[ii].pm != NULL)
+					lvms[i].pv[ii].pm->blocked++;
+			for (ii = 0; ii < MAX_LVM_LV; ii++)
+				if (lvms[i].lv[ii].size > 0)
+					lvms[i].lv[ii].blocked = 1;
+		}
+	}
+
+	return 0;
+}
+
+/***
+GPT
+***/
+
+int
+pm_gpt_convert(pm_devs_t *pm_cur)
+{
+	int i, error = 0;
+
+	msg_display(MSG_removepartswarn);
+	process_menu(MENU_noyes, NULL);
+	if (! yesno)
+		return -1;
+
+	if (! pm_cur->gpt)
+		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "gpt create -f %s", 
+				pm_cur->diskdev);
+	else {
+		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "gpt destroy %s", 
+				pm_cur->diskdev);
+		for (i = 0; i < MAX_WEDGES; i++)
+			if (wedges[i].pm == pm_cur)
+				wedges[i].pm = NULL;
+	}
+	if (!error) {
+		pm_cur->gpt = !pm_cur->gpt;
+		pm_select(pm_cur);
+		label_read();
+	}
+	return error;
+}
+
+static int
+pm_wedge_getfree(void)
+{
+	int i;
+	for (i = 0; i < MAX_WEDGES; i++)
+		if (! wedges[i].allocated && wedges[i].pm == NULL)
+			return i;
+	return -1;
+}
+
+void
+pm_wedges_fill(pm_devs_t *pm_cur)
+{
+	int i, current;
+
+	for (i = 0; i < MAX_WEDGES; i++)
+		if (wedges[i].pm == pm_cur && ! wedges[i].allocated)
+			wedges[i].pm = NULL;
+
+	for (i = 0; i < MAXPARTITIONS && i < MAX_WEDGES; i++)
+		if (pm_cur->bsdlabel[i].pi_fstype != FS_UNUSED) {
+			current = pm_wedge_getfree();
+			if (current < 0) {
+				process_menu(MENU_ok, deconst(MSG_limitcount));
+				return;
+			}
+			wedges[current].pm = pm_cur;
+			wedges[current].ptn = i;
+		}
+	return;
+}
+
+static int
+pm_wedge_create(int num, pm_devs_t **pm_dk)
+{
+	int i, ii, hackerr, error;
+	partinfo *p = &(wedges[num].pm->bsdlabel[wedges[num].ptn]);
+
+	if (num > MAX_WEDGES)
+		return -1;
+
+	/* There is no ability to use requied dkX device, so that's hack */
+	for (i = 0; i < num; i++)
+		if (! wedges[i].allocated) {
+			hackerr = 1;
+			for (ii = 0; hackerr && ii < 3; ii++)
+				hackerr = run_program(RUN_SILENT | RUN_ERROR_OK,
+					"dkctl %s addwedge HACK%d %d %d unused",
+					wedges[num].pm->diskdev,
+					rand()%33, rand()%33, 0);
+			wedges[i].todel = 1;
+		}
+	
+	run_program(RUN_SILENT | RUN_ERROR_OK,
+					"dkctl %s listwedges", wedges[num].pm->diskdev);
+
+	error = run_program(RUN_DISPLAY | RUN_PROGRESS,
+			"dkctl %s addwedge dk%d %u %u %s",
+			wedges[num].pm->diskdev,
+			num,
+			p->pi_offset,
+			p->pi_size,
+			getfstypename(p->pi_fstype));
+	if (!error) {
+		wedges[num].allocated = 1;
+		wedges[num].pm->blocked++;
+		if (pm_dk != NULL) {
+			*pm_dk = malloc(sizeof(pm_devs_t));
+			memset(*pm_dk, 0, sizeof **pm_dk);
+			memcpy(&(*pm_dk)->bsdlabel[0], p, sizeof (*pm_dk)->bsdlabel[0]);
+			(*pm_dk)->found = -1;
+			(*pm_dk)->isspecial = 1;
+			(*pm_dk)->sectorsize = 512; /* XXX: xxx */
+			(*pm_dk)->dlcylsize = MEG;
+			(*pm_dk)->refdev = wedges[num].pm;
+			snprintf((*pm_dk)->diskdev, SSTRSIZE, "dk%d", num);
+			snprintf((*pm_dk)->diskdev_descr, STRSIZE, "   %s (%s)",
+				(*pm_dk)->diskdev, getfstypename(p->pi_fstype));
+		}
+	} else
+		if (logfp)
+			fprintf(logfp, "Cannot create wedge dk%d for %s.\n",
+				num, wedges[num].pm->diskdev);
+
+	/* Hack, see above */
+	for (i = 0; i < num; i ++)
+		if (! wedges[i].allocated && wedges[i].todel) {
+			hackerr = run_program(RUN_SILENT | RUN_ERROR_OK,
+				"dkctl %s delwedge dk%d", wedges[num].pm->diskdev, i);
+			wedges[i].todel = 0;
+		}
+
+	return error;
+}
+
+static int
+pm_gpt_commit(void)
+{
+	uint i, error;
+	pm_devs_t *pm_i, *pm_dk = NULL;
+	char fstype[STRSIZE]; fstype[0] = '\0';
+	partinfo *p;
+
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		if (pm_i->gpt && pm_i->unsaved)
+			run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"gpt remove -a %s",
+				pm_i->diskdev);
+
+	for (i = 0; i < MAX_WEDGES; i++) {
+		if (wedges[i].pm == NULL ||
+			! wedges[i].pm->unsaved ||
+			wedges[i].ptn < 0)
+			continue;
+		error = 0;
+		p = &(wedges[i].pm->bsdlabel[wedges[i].ptn]);
+		if (wedges[i].pm->gpt) {
+			if (get_gptfs_by_id(p->pi_fstype) != NULL)
+				snprintf(fstype, STRSIZE, "-t %s", get_gptfs_by_id(p->pi_fstype));
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"gpt add -i %u -b %u -s %u %s %s",
+				wedges[i].ptn + 1,
+				p->pi_offset, p->pi_size,
+				fstype, wedges[i].pm->diskdev);
+		}
+		
+		if (error || wedges[i].allocated) {
+			if (logfp && error)
+				fprintf(logfp, "Cannot create GPT partition #%d on %s\n",
+					i, wedges[i].pm->diskdev);
+			continue;
+		}
+
+		error += pm_wedge_create(i, &pm_dk);
+		if (pm_dk != NULL) {
+			/* Create filesystem on wedge and add it to list */
+			pm_select(pm_dk);
+			make_filesystems();
+			SLIST_INSERT_AFTER(wedges[i].pm, pm_dk, l);
+			memset(p, 0, sizeof *p);
+			if (error)
+				return -1;
+		}
+	}
+
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		if (pm_i->gpt && pm_i->unsaved)
+			pm_i->unsaved = 0;
+
+	return 0;
+}
+
+/***
+Partman generic functions 
+***/
+
+int
+pm_getrefdev(pm_devs_t *pm_cur)
+{
+	int i, ii, dev_num, num_devs, num_devs_s;
+	char dev[SSTRSIZE]; dev[0] = '\0';
+
+	pm_cur->refdev = NULL;
+	if (! strncmp(pm_cur->diskdev, "cgd", 3)) {
+		dev_num = pm_cur->diskdev[3] - '0';
+		for (i = 0; i < MAX_CGD; i++)
+			if (cgds[i].blocked && cgds[i].node == dev_num) {
+				pm_cur->refdev = &cgds[i];
+
+				snprintf(pm_cur->diskdev_descr, STRSIZE, "%s (%s, %s-%d)",
+					pm_cur->diskdev_descr, cgds[i].pm_name,
+					cgds[i].enc_type, cgds[i].key_size);
+				break;
+			}
+ 	} else if (! strncmp(pm_cur->diskdev, "vnd", 3)) {
+ 		dev_num = pm_cur->diskdev[3] - '0';
+ 		for (i = 0; i < MAX_VND; i++)
+			if (vnds[i].blocked && vnds[i].node == dev_num) {
+				pm_cur->refdev = &vnds[i];
+				pm_getdevstring(dev, SSTRSIZE, vnds[i].pm, vnds[i].pm_part);
+				snprintf(pm_cur->diskdev_descr, STRSIZE, "%s (%s, %s)",
+					pm_cur->diskdev_descr, dev, vnds[i].filepath);
+				break;
+			}
+	} else if (! strncmp(pm_cur->diskdev, "raid", 4)) {
+		dev_num = pm_cur->diskdev[4] - '0';
+ 		for (i = 0; i < MAX_RAID; i++)
+			if (raids[i].blocked && raids[i].node == dev_num) {
+				pm_cur->refdev = &raids[i];
+				num_devs = 0; num_devs_s = 0;
+				for (ii = 0; ii < MAX_IN_RAID; ii++)
+					if (raids[i].pm[ii] != NULL) {
+						if(raids[i].pm_is_spare[ii])
+							num_devs_s++;
+						else
+							num_devs++;
+					}
+				snprintf(pm_cur->diskdev_descr, STRSIZE,
+					"%s (lvl %d, %d disks, %d spare)", pm_cur->diskdev_descr,
+					raids[i].raid_level, num_devs, num_devs_s);
+				break;
+			}
+	} else
+		return -1;
+	return 0;
+}
+
+/* Detect that partition is in use */
+int
+pm_partusage(pm_devs_t *pm_cur, int part_num, int do_del)
+{
+	int i, ii, retvalue = 0;
+
+	if (part_num < 0) {
+		/* Check all partitions on device */
+		for (i = 0; i < MAXPARTITIONS; i++)
+			retvalue += pm_partusage(pm_cur, i, do_del);
+		return retvalue;
+	}
+
+	for (i = 0; i < MAX_CGD; i++)
+		if (cgds[i].enabled &&
+			cgds[i].pm == pm_cur &&
+			cgds[i].pm_part == part_num) {
+			if (do_del) {
+				cgds[i].pm = NULL;
+				strcpy(cgds[i].pm_name, "");
+			}
+			return 1;
+		}
+	for (i = 0; i < MAX_RAID; i++)
+		for (ii = 0; ii < MAX_IN_RAID; ii++)
+			if (raids[i].enabled &&
+				raids[i].pm[ii] == pm_cur &&
+				raids[i].pm_part[ii] == part_num) {
+					if (do_del)
+						raids[i].pm[ii] = NULL;
+					return 1;
+			}
+	for (i = 0; i < MAX_LVM_VG; i++)
+		for (ii = 0; ii < MAX_LVM_PV; ii++)
+			if (lvms[i].enabled &&
+				lvms[i].pv[ii].pm == pm_cur &&
+				lvms[i].pv[ii].pm_part == part_num) {
+					if (do_del)
+						lvms[i].pv[ii].pm = NULL;
+					return 1;
+			}
+
+	return 0;
+}
+
+/* Cleanup removed devices */
+static int
+pm_clean(void)
+{
+	int count = 0;
+	pm_devs_t *pm_i;
+
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		if (! pm_i->found) {
+			count++;
+			SLIST_REMOVE(&pm_head, pm_i, pm_devs_t, l);
+			free(pm_i);
+		}
+	return count;
+}
+
+void 
+pm_make_bsd_partitions(pm_devs_t *pm_cur)
+{
+	int i;
+	partinfo baklabel[MAXPARTITIONS];
+	memcpy(baklabel, &pm_cur->bsdlabel, sizeof baklabel);
+
+	pm_cur->unsaved = 1;
+	layoutkind = LY_SETNEW;
+	md_make_bsd_partitions();
+	pm_cur->bootable = (pm_cur->bsdlabel[pm_cur->rootpart].pi_flags & PIF_MOUNT) ?
+		1 : 0;
+	for (i = 0; i < MAXPARTITIONS; i++)
+		if (pm_cur->bsdlabel[i].pi_fstype != baklabel[i].pi_fstype ||
+				pm_cur->bsdlabel[i].lvmpv != baklabel[i].lvmpv)
+			pm_partusage(pm_cur, i, 1);
+}
+
+void
+pm_setfstype(pm_devs_t *pm_cur, int part_num, int fstype)
+{
+	pm_cur->bsdlabel[part_num].pi_mount[0] = '\0';
+	pm_cur->bsdlabel[part_num].pi_flags = 0;
+	pm_cur->bsdlabel[part_num].lvmpv = 0;
+	pm_cur->bsdlabel[part_num].pi_fstype = fstype;
+	return;	
+}
+
+static void
+pm_select(pm_devs_t *pm_devs_in)
+{
+	pm = pm_devs_in;
+	if (logfp)
+		(void)fprintf(logfp, "Partman device: %s\n", pm->diskdev);
+	return;
+}
+
+void
+pm_rename(pm_devs_t *pm_cur)
+{
+	pm_select(pm_cur);
+	msg_prompt_win(MSG_packname, -1, 18, 0, 0, pm_cur->bsddiskname,
+		pm_cur->bsddiskname, sizeof pm_cur->bsddiskname);
+	(void) savenewlabel(pm_cur->bsdlabel, MAXPARTITIONS);
+	return;
+}
+
+int
+pm_editpart(int part_num)
+{
+	partinfo backup = pm->bsdlabel[part_num];
+
+	edit_ptn(&(struct menudesc){.cursel = part_num}, NULL);
+	if (checkoverlap(pm->bsdlabel, MAXPARTITIONS, PART_D, PART_C)) {
+		msg_display_add(MSG_cantsave);
+		process_menu(MENU_ok, NULL);
+		pm->bsdlabel[part_num] = backup;
+		return -1;
+	}
+	pm->unsaved = 1;
+	return 0;
+}
+
+/* Safe erase of disk */
+int
+pm_shred(pm_devs_t *pm_cur, int part, int shredtype)
+{
+	int error = -1;
+	char dev[SSTRSIZE];
+
+	pm_getdevstring(dev, SSTRSIZE, pm_cur, part);
+	switch(shredtype) {
+		case SHRED_ZEROS:
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"dd of=/dev/%s if=/dev/zero bs=1m progress=100 msgfmt=human",
+				dev);
+			break;
+		case SHRED_RANDOM:
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"dd of=/dev/%s if=/dev/urandom bs=1m progress=100 msgfmt=human",
+				dev);
+			break;
+		case SHRED_CRYPTO:
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"sh -c 'cgdconfig -s cgd0 /dev/%s aes-cbc 128 < /dev/urandom'",
+				dev); /* XXX: cgd0?! */
+			if (! error) {
+				error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+					"dd of=/dev/rcgd0d if=/dev/urandom bs=1m progress=100 msgfmt=human");
+				error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+					"cgdconfig -u cgd0");
+			}
+			break;
+		default:
+			return -1;
+	}
+	pm_partusage(pm_cur, -1, 1);
+	memset(&pm_cur->oldlabel, 0, sizeof pm_cur->oldlabel);
+	memset(&pm_cur->bsdlabel, 0, sizeof pm_cur->bsdlabel);
+	return error;
+}
+
+static int
+pm_mountall_sort(const void *a, const void *b)
+{
+	return strcmp(mnts[*(const int *)a].on, mnts[*(const int *)b].on);
+}
+
+/* Mount all available partitions */
+static int
+pm_mountall(void)
+{
+	int num_devs = 0;
+	int mnts_order[MAX_MNTS];
+	int i, ii, error, ok;
+	char dev[SSTRSIZE]; dev[0] = '\0';
+	pm_devs_t *pm_i;
+	
+	localfs_dev[0] = '\0';
+	memset(&mnts, 0, sizeof mnts);
+
+	SLIST_FOREACH(pm_i, &pm_head, l) {
+		ok = 0;
+		for (i = 0; i < MAXPARTITIONS; i++) {
+			if (!(pm_i->bsdlabel[i].pi_flags & PIF_MOUNT && 
+					pm_i->bsdlabel[i].mnt_opts != NULL))
+				continue;
+			mnts[num_devs].mnt_opts = pm_i->bsdlabel[i].mnt_opts;
+			if (pm_i->bsdlabel[i].mounted != NULL &&
+					strlen(pm_i->bsdlabel[i].mounted) > 0) {
+				/* Device is already mounted. So, doing mount_null */
+				strlcpy(mnts[num_devs].dev, pm_i->bsdlabel[i].mounted, MOUNTLEN);
+				mnts[num_devs].mnt_opts = "-t null";
+			} else {
+				pm_getdevstring(dev, SSTRSIZE, pm_i, i);
+				snprintf(mnts[num_devs].dev, STRSIZE, "/dev/%s", dev);
+			}
+			mnts[num_devs].on = pm_i->bsdlabel[i].pi_mount;
+			if (strcmp(pm_i->bsdlabel[i].pi_mount, "/") == 0) {
+				if (pm_i->isspecial)
+					pm_i->bootable = 1;
+				/* Use disk with / as a default if the user has 
+				the sets on a local disk */
+				strlcpy(localfs_dev, pm_i->diskdev, SSTRSIZE);
+			}
+			num_devs++;
+			ok = 1;
+		}
+		if (ok)
+			md_pre_mount();
+	}
+	if (strlen(localfs_dev) < 1) {
+		msg_display(MSG_noroot);
+		process_menu(MENU_ok, NULL);
+		return -1;
+	}
+	for (i = 0; i < num_devs; i++)
+		mnts_order[i] = i;
+	qsort(mnts_order, num_devs, sizeof mnts_order[0], pm_mountall_sort);
+
+	for (i = 0; i < num_devs; i++) {
+		ii = mnts_order[i];
+		make_target_dir(mnts[ii].on);
+		error = target_mount_do(mnts[ii].mnt_opts, mnts[ii].dev, mnts[ii].on);
+		if (error)
+			return error;
+	}
+	return 0;
+}
+
+/* Mount partition bypassing ordinary order */
+static int
+pm_mount(pm_devs_t *pm_cur, int part_num)
+{
+	int error = 0;
+	char buf[MOUNTLEN];
+
+	if (strlen(pm_cur->bsdlabel[part_num].mounted) > 0)
+		return 0;
+
+	snprintf(buf, MOUNTLEN, "/tmp/%s%c", pm_cur->diskdev, part_num + 'a');
+	if (! dir_exists_p(buf))
+		run_program(RUN_DISPLAY | RUN_PROGRESS, "/bin/mkdir -p %s", buf);
+	if (pm_cur->bsdlabel[part_num].pi_flags & PIF_MOUNT &&
+		pm_cur->bsdlabel[part_num].mnt_opts != NULL &&
+		strlen(pm_cur->bsdlabel[part_num].mounted) < 1)
+		error += run_program(RUN_DISPLAY | RUN_PROGRESS, "/sbin/mount %s /dev/%s%c %s",
+				pm_cur->bsdlabel[part_num].mnt_opts,
+				pm_cur->diskdev, part_num + 'a', buf);
+
+	if (error)
+		pm_cur->bsdlabel[part_num].mounted[0] = '\0';
+	else {
+		strlcpy(pm_cur->bsdlabel[part_num].mounted, buf, MOUNTLEN);
+		pm_cur->blocked++;
+	}
+	return error;
+}
+
+void
+pm_umount(pm_devs_t *pm_cur, int part_num)
+{
+	char buf[SSTRSIZE]; buf[0] = '\0';
+	pm_getdevstring(buf, SSTRSIZE, pm_cur, part_num);
+
+	if (run_program(RUN_DISPLAY | RUN_PROGRESS,
+			"umount -f /dev/%s", buf) == 0) {
+		pm_cur->bsdlabel[part_num].mounted[0] = '\0';
+		if (pm_cur->blocked > 0)
+			pm_cur->blocked--;
+	}
+	return;
+}
+
+int
+pm_unconfigure(pm_devs_t *pm_cur)
+{
+	int i, error = 0, num = 0;
+	if (! strncmp(pm_cur->diskdev, "cgd", 3)) {
+ 		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "cgdconfig -u %s", pm_cur->diskdev);
+ 		if (! error && pm_cur->refdev != NULL) {
+			((cgds_t*)pm_cur->refdev)->pm->blocked--;
+			((cgds_t*)pm_cur->refdev)->blocked = 0;
+ 		}
+ 	} else if (! strncmp(pm_cur->diskdev, "vnd", 3)) {
+		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "vnconfig -u %s", pm_cur->diskdev);
+ 		if (! error && pm_cur->refdev != NULL) {
+			((vnds_t*)pm_cur->refdev)->pm->blocked--;
+			((vnds_t*)pm_cur->refdev)->blocked = 0;
+ 		}
+	} else if (! strncmp(pm_cur->diskdev, "raid", 4)) {
+		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "raidctl -u %s", pm_cur->diskdev);
+		if (! error && pm_cur->refdev != NULL) {
+			((raids_t*)pm_cur->refdev)->blocked = 0;
+			for (i = 0; i < MAX_IN_RAID; i++)
+				if (((raids_t*)pm_cur->refdev)->pm[i] != NULL)
+					((raids_t*)pm_cur->refdev)->pm[i]->blocked--;
+		}
+	} else if (! strncmp(pm_cur->diskdev, "dk", 2)) {
+		if (pm_cur->refdev == NULL)
+			return -2;
+		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "dkctl %s delwedge %s",
+			((pm_devs_t*)pm_cur->refdev)->diskdev, pm_cur->diskdev);
+		if (! error) {
+			if (pm_cur->refdev != NULL && ((pm_devs_t*)pm_cur->refdev)->blocked > 0)
+				((pm_devs_t*)pm_cur->refdev)->blocked--;
+			sscanf(pm_cur->diskdev, "dk%d", &num);
+			if (num >= 0 && num < MAX_WEDGES)
+				wedges[num].allocated = 0;
+		}
+	} /* XXX: lvm */
+	else
+		error = run_program(RUN_DISPLAY | RUN_PROGRESS, "eject -t disk /dev/%sd",
+			pm_cur->diskdev);
+	if (!error)
+		pm_cur->found = 0;
+	return error;
+}
+
+/* Last checks before leaving partition manager */
+static int
+pm_lastcheck(void)
+{
+	FILE *file_tmp = fopen(concat_paths(targetroot_mnt, "/etc/fstab"), "r");
+	if (file_tmp == NULL)
+		return 1;
+	fclose(file_tmp);
+	return 0;
+}
+
+/* Is there some unsaved changes? */
+static int
+pm_needsave(void)
+{
+	pm_devs_t *pm_i;
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		if (pm_i->unsaved) {
+			/* Oops, we have unsaved changes */
+			changed = 1;
+			msg_display(MSG_saveprompt);
+			process_menu(MENU_yesno, NULL);
+			return (yesno);
+		}
+	return 0;
+}
+
+/* Write all changes to disk */
+static int
+pm_commit(menudesc *m, void *arg)
+{
+	int retcode;
+	pm_devs_t *pm_i;
+	if (m != NULL && arg != NULL)
+		((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	pm_gpt_commit();
+
+	SLIST_FOREACH(pm_i, &pm_head, l) {
+		if (! pm_i->unsaved)
+			continue;
+		pm_select(pm_i);
+
+		if (pm_i->isspecial) {
+			if (make_filesystems() != 0) {
+				if (logfp)
+					fprintf(logfp, "Special disk %s preparing error\n", pm_i->diskdev);
+				continue;
+			}
+			pm_i->unsaved = 0;
+		} else if (! pm_i->gpt) {
+			savenewlabel(pm_i->bsdlabel, MAXPARTITIONS);
+			if (
+				write_disklabel() != 0   || /* Write slices table (disklabel) */
+				md_post_disklabel() != 0 || /* Enable swap and check badblock */
+				make_filesystems() != 0     /* Create filesystems by newfs */
+			) {
+				/* Oops, something failed... */
+				if (logfp)
+					fprintf(logfp, "Disk %s preparing error\n", pm_i->diskdev);
+				continue;
+			}
+			pm_i->unsaved = 0;
+		}
+	}
+
+	/* Call all functions that may create new devices */
+	if ((retcode = pm_raid_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "RAIDframe configuring error #%d\n", retcode);
+		return -1;
+	}
+	if ((retcode = pm_cgd_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "CGD configuring error #%d\n", retcode);
+		return -1;
+	}
+	if ((retcode = pm_lvm_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "LVM configuring error #%d\n", retcode);
+		return -1;
+	}
+	if ((retcode = pm_vnd_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "VND configuring error #%d\n", retcode);
+		return -1;
+	}
+	if (m != NULL && arg != NULL)
+		pm_upddevlist(m, arg);
+	if (logfp)
+		fflush (logfp);
+    return 0;
+}
+
+static int
+pm_savebootsector(void)
+{
+	pm_devs_t *pm_i;
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		if (pm_i->bootable) {
+			if (! strncmp("raid", pm_i->diskdev, 4))
+				if (run_program(RUN_DISPLAY | RUN_PROGRESS,
+					"raidctl -v -A root %s", pm_i->diskdev) != 0) {
+					if (logfp)
+						fprintf(logfp, "Error writting RAID bootsector to %s\n",
+							pm_i->diskdev);
+					continue;
+				}
+			if (pm_i->gpt && ! pm_i->isspecial) {
+				if (pm_i->rootpart < 0 ||
+					run_program(RUN_DISPLAY | RUN_PROGRESS,
+					"gpt biosboot -i %d %s",
+					pm_i->rootpart + 1, pm_i->diskdev) != 0) {
+			 		if (logfp)
+						fprintf(logfp, "Error writting GPT bootsector to %s\n",
+							pm_i->diskdev);
+					continue;
+				}
+			} else {
+				pm_select(pm_i);
+			 	if (check_partitions() == 0 || md_post_newfs() != 0) {
+		 			if (logfp)
+						fprintf(logfp, "Error writting bootsector to %s\n",
+							pm_i->diskdev);
+					continue;
+				}
+			}
+		}
+	return 0;
+}
+
+/* Function for 'Enter'-menu */
+static int
+pm_submenu(menudesc *m, void *arg)
+{
+	int part_num = -1;
+	pm_devs_t *pm_cur = NULL;
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	switch (((part_entry_t *)arg)[m->cursel].type) {
+		case PM_DISK_T:
+		case PM_WEDGE_T:
+		case PM_PART_T:
+		case PM_SPEC_T:
+			if (((part_entry_t *)arg)[m->cursel].dev_ptr != NULL) {
+				pm_cur = ((part_entry_t *)arg)[m->cursel].dev_ptr;
+				if (pm_cur == NULL) 
+					return -1;
+				if (pm_cur->blocked) {
+					msg_display(MSG_wannaunblock);
+					process_menu(MENU_noyes, NULL);
+					if (!yesno)
+						return -2;
+					pm_cur->blocked = 0;
+				}
+				pm_select(pm_cur);
+			}
+		default:
+			break;
+	}
+
+	switch (((part_entry_t *)arg)[m->cursel].type) {
+		case PM_DISK_T:
+			if (pm_cur->gpt) {
+				process_menu(MENU_pmgptentry, &part_num);
+				pm_wedges_fill(pm_cur);
+			} else
+				process_menu(MENU_pmdiskentry, &part_num);
+			break;
+		case PM_WEDGE_T:
+		case PM_PART_T:
+			part_num = ((part_entry_t *)arg)[m->cursel].dev_num;
+			process_menu(MENU_pmpartentry, &part_num);
+			if (pm_cur->gpt)
+				pm_wedges_fill(pm_cur);
+			break;
+		case PM_SPEC_T:
+			part_num = 0;
+			process_menu(MENU_pmpartentry, &part_num);
+			break;
+		case PM_RAID_T:
+			return pm_edit(PMR_MENU_END, pm_raid_edit_menufmt,
+				pm_raid_set_value, pm_raid_check, pm_raid_init,
+				NULL, ((part_entry_t *)arg)[m->cursel].dev_ptr, 0, &raids_t_info);
+		case PM_VND_T:
+			return pm_edit(PMV_MENU_END, pm_vnd_edit_menufmt,
+				pm_vnd_set_value, pm_vnd_check, pm_vnd_init,
+				NULL, ((part_entry_t *)arg)[m->cursel].dev_ptr, 0, &vnds_t_info);
+		case PM_CGD_T:
+			return pm_cgd_edit(((part_entry_t *)arg)[m->cursel].dev_ptr,
+				NULL);
+		case PM_LVM_T:
+			return pm_edit(PML_MENU_END, pm_lvm_edit_menufmt,
+				pm_lvm_set_value, pm_lvm_check, pm_lvm_init,
+				NULL, ((part_entry_t *)arg)[m->cursel].dev_ptr, 0, &lvms_t_info);
+		case PM_LVMLV_T:
+			return pm_edit(PMLV_MENU_END, pm_lvmlv_edit_menufmt,
+				pm_lvmlv_set_value, pm_lvmlv_check, pm_lvmlv_init,
+				NULL, ((part_entry_t *)arg)[m->cursel].dev_ptr,
+				((part_entry_t *)arg)[m->cursel].dev_ptr_delta, &lv_t_info);
+	}
+	return 0;
+}
+
+/* Functions that generate menu entries text */
+static void
+pm_menufmt(menudesc *m, int opt, void *arg)
+{
+	const char *dev_status = "";
+	char buf[STRSIZE];
+	int part_num = ((part_entry_t *)arg)[opt].dev_num;
+	pm_devs_t *pm_cur = ((part_entry_t *)arg)[opt].dev_ptr;
+
+	switch (((part_entry_t *)arg)[opt].type) {
+		case PM_DISK_T:
+			if (pm_cur->blocked)
+				dev_status = msg_string(MSG_pmblocked);
+			else if (! pm_cur->unsaved)
+				dev_status = msg_string(MSG_pmunchanged);
+			else if (pm_cur->bootable)
+				dev_status = msg_string(MSG_pmsetboot);
+			else
+				dev_status = msg_string(MSG_pmused);
+			wprintw(m->mw, "%-33.32s %-22.21s %12.12s",
+				pm_cur->diskdev_descr,
+				(pm_cur->gpt) ?
+					msg_string(MSG_pmgptdisk) :
+					pm_cur->bsddiskname,
+				dev_status);
+			break;
+		case PM_WEDGE_T:
+			part_num = ((part_entry_t *)arg)[opt].wedge_num;
+			snprintf(buf, STRSIZE, "dk%d: %s",
+				part_num,
+				wedges[part_num].pm->bsdlabel[wedges[part_num].ptn].pi_mount);
+			wprintw(m->mw, "   %-30.29s %-22.21s %11uM",
+				buf,
+				(wedges[part_num].pm->bsdlabel[wedges[part_num].ptn].lvmpv) ? 
+					"lvm pv" :
+					getfslabelname(wedges[part_num].pm->bsdlabel[wedges[part_num].
+						ptn].pi_fstype),
+				wedges[part_num].pm->bsdlabel[wedges[part_num].ptn].pi_size /
+					(MEG / pm_cur->sectorsize));
+			break;
+		case PM_PART_T:
+			snprintf(buf, STRSIZE, "%s%c: %s %s",
+				pm_cur->diskdev,
+				'a' + part_num,
+				pm_cur->bsdlabel[part_num].pi_mount,
+				(strlen(pm_cur->bsdlabel[part_num].mounted) > 0) ? msg_string(MSG_pmmounted) : 
+					(part_num == PART_B ||
+						strlen (pm_cur->bsdlabel[part_num].pi_mount ) < 1 ||
+						pm_cur->bsdlabel[part_num].pi_flags & PIF_MOUNT) ?
+						"" : msg_string(MSG_pmunused));
+			wprintw(m->mw, "   %-30.29s %-22.21s %11uM",
+				buf,
+				(pm_cur->bsdlabel[part_num].lvmpv) ? 
+					"lvm pv" :
+					getfslabelname(pm_cur->bsdlabel[part_num].pi_fstype),
+				pm_cur->bsdlabel[part_num].pi_size / (MEG / pm_cur->sectorsize));
+			break;
+		case PM_SPEC_T:
+			snprintf(buf, STRSIZE, "%s: %s",
+				pm_cur->diskdev_descr, pm_cur->bsdlabel[0].pi_mount);
+			wprintw(m->mw, "%-33.32s %-22.21s %11uM", buf,
+				getfslabelname(pm_cur->bsdlabel[0].pi_fstype),
+				pm_cur->bsdlabel[0].pi_size / (MEG / pm_cur->sectorsize));
+			break;
+		case PM_RAID_T:
+			pm_raid_menufmt(m, opt, arg);
+			break;
+		case PM_VND_T:
+			pm_vnd_menufmt(m, opt, arg);
+			break;
+		case PM_CGD_T:
+			pm_cgd_menufmt(m, opt, arg);
+			break;
+		case PM_LVM_T:
+			pm_lvm_menufmt(m, opt, arg);
+			break;
+		case PM_LVMLV_T:
+			pm_lvmlv_menufmt(m, opt, arg);
+			break;
+	}
+	return;
+}
+
+/* Submenu for RAID/LVM/CGD/VND */
+static void
+pm_upddevlist_adv(menudesc *m, void *arg, int *i,
+	pm_upddevlist_adv_t *d)
+{
+	int ii;
+	if (d->create_msg != NULL) {
+		/* We want to have menu entrie that create new device */
+		((part_entry_t *)arg)[*i].type = d->pe_type;
+		((part_entry_t *)arg)[*i].dev_ptr = NULL;
+		((part_entry_t *)arg)[*i].dev_ptr_delta = d->s->parent_size * d->sub_num;
+		m->opts[(*i)++] = (struct menu_ent) {
+			.opt_name = d->create_msg,
+			.opt_action = pm_submenu,
+		};
+	}
+	for (ii = 0; ii < d->s->max; ii++) {
+		if (d->s->entry_enabled == NULL ||
+			d->s->entry_blocked == NULL ||
+			*(int*)((char*)d->s->entry_enabled + d->s->entry_size * ii +
+				d->s->parent_size * d->sub_num) == 0 ||
+			*(int*)((char*)d->s->entry_blocked + d->s->entry_size * ii +
+				d->s->parent_size * d->sub_num) != 0)
+			continue;
+		/* We have a entry for displaying */
+		changed = 1;
+		m->opts[*i] = (struct menu_ent) {
+			.opt_name = NULL,
+			.opt_action = pm_submenu,
+		};
+		((part_entry_t *)arg)[*i].type = d->pe_type;
+		((part_entry_t *)arg)[*i].dev_ptr = (char*)d->s->entry_first +
+			d->s->entry_size * ii + d->s->parent_size * d->sub_num;
+		(*i)++;
+		/* We should to show submenu for current entry */
+		if (d->sub != NULL) {
+			d->sub->sub_num = ii;
+			pm_upddevlist_adv(m, arg, i, d->sub);
+		}
+	}
+	return;
+}
+
+/* Update partman main menu with devices list */
+static int
+pm_upddevlist(menudesc *m, void *arg)
+{
+	int i = 0, ii;
+	pm_devs_t *pm_i;
+	if (arg != NULL)
+		((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	changed = 0;
+	/* Mark all devices as not found */
+	SLIST_FOREACH(pm_i, &pm_head, l)
+		if (pm_i->found > 0)
+			pm_i->found = 0;
+	/* Detect all present devices */
+	find_disks("partman");
+	pm_lvm_find();
+	pm_clean();
+
+	if (m == NULL || arg == NULL)
+		return -1;
+
+	SLIST_FOREACH(pm_i, &pm_head, l) {
+		m->opts[i].opt_name = NULL;
+		m->opts[i].opt_action = pm_submenu;
+		((part_entry_t *)arg)[i].dev_ptr = pm_i;
+		((part_entry_t *)arg)[i].dev_num = -1;
+		if (pm_i->isspecial)
+			((part_entry_t *)arg)[i].type = PM_SPEC_T;
+		else {
+			((part_entry_t *)arg)[i].type = PM_DISK_T;
+			if (pm_i->gpt) {
+				pm_wedges_fill(pm_i);
+				for (ii = 0; ii < MAX_WEDGES; ii++)
+					if (wedges[ii].pm == pm_i) {
+						i++;
+						m->opts[i].opt_name = NULL;
+						m->opts[i].opt_action = pm_submenu;
+						((part_entry_t *)arg)[i].dev_ptr = pm_i;
+						((part_entry_t *)arg)[i].dev_num = wedges[ii].ptn;
+						((part_entry_t *)arg)[i].wedge_num = ii;
+						((part_entry_t *)arg)[i].type = PM_WEDGE_T;
+					}
+			} else {
+				for (ii = 0; ii < MAXPARTITIONS; ii++)
+					if (pm_i->bsdlabel[ii].pi_fstype != FS_UNUSED) {
+						i++;
+						m->opts[i].opt_name = NULL;
+						m->opts[i].opt_action = pm_submenu;
+						((part_entry_t *)arg)[i].dev_ptr = pm_i;
+						((part_entry_t *)arg)[i].dev_num = ii;
+						((part_entry_t *)arg)[i].type = PM_PART_T;
+					}
+			}
+		}
+		i++;
+	}
+	pm_upddevlist_adv(m, arg, &i,
+		&(pm_upddevlist_adv_t) {MSG_create_cgd, PM_CGD_T, &cgds_t_info, 0, NULL});
+	pm_upddevlist_adv(m, arg, &i,
+		&(pm_upddevlist_adv_t) {MSG_create_cnd, PM_VND_T, &vnds_t_info, 0, NULL});
+	pm_upddevlist_adv(m, arg, &i,
+		&(pm_upddevlist_adv_t) {MSG_create_vg, PM_LVM_T, &lvms_t_info, 0,
+		&(pm_upddevlist_adv_t) {MSG_create_lv, PM_LVMLV_T, &lv_t_info, 0, NULL}});
+	pm_upddevlist_adv(m, arg, &i,
+		&(pm_upddevlist_adv_t) {MSG_create_raid, PM_RAID_T, &raids_t_info, 0, NULL});
+
+	m->opts[i++] = (struct menu_ent) {
+		.opt_name = MSG_updpmlist,
+		.opt_action = pm_upddevlist,
+	};
+	m->opts[i  ] = (struct menu_ent) {
+		.opt_name = MSG_savepm,
+		.opt_action = pm_commit,
+	};
+	for (ii = 0; ii <= i; ii++) {
+		m->opts[ii].opt_menu = OPT_NOMENU;
+		m->opts[ii].opt_flags = OPT_EXIT;
+	}
+
+	if (((part_entry_t *)arg)[0].retvalue >= 0)
+		m->cursel = ((part_entry_t *)arg)[0].retvalue - 1;
+	return i;
+}
+
+static void
+pm_menuin(menudesc *m, void *arg)
+{
+	if (cursel > m->numopts)
+		m->cursel = m->numopts;
+	else if (cursel < 0)
+		m->cursel = 0;
+	else
+		m->cursel = cursel;
+}
+
+static void
+pm_menuout(menudesc *m, void *arg)
+{
+	cursel = m->cursel;
+}
+
+/* Main partman function */
+int
+partman(void)
+{
+	int menu_no, menu_num_entries;
+	static int firstrun = 1;
+	menu_ent menu_entries[MAX_ENTRIES+6];
+	part_entry_t args[MAX_ENTRIES];
+
+	if (firstrun) {
+		raids_t_info = (structinfo_t) {
+			.max = MAX_RAID,
+			.entry_size = sizeof raids[0],
+			.entry_first = &raids[0],
+			.entry_enabled = &(raids[0].enabled),
+			.entry_blocked = &(raids[0].blocked),
+			.entry_node = &(raids[0].node),
+		};
+		vnds_t_info = (structinfo_t) {
+			.max = MAX_VND,
+			.entry_size = sizeof vnds[0],
+			.entry_first = &vnds[0],
+			.entry_enabled = &(vnds[0].enabled),
+			.entry_blocked = &(vnds[0].blocked),
+			.entry_node = &(vnds[0].node),
+		};
+		cgds_t_info = (structinfo_t) {
+			.max = MAX_CGD,
+			.entry_size = sizeof cgds[0],
+			.entry_first = &cgds[0],
+			.entry_enabled = &(cgds[0].enabled),
+			.entry_blocked = &(cgds[0].blocked),
+			.entry_node = &(cgds[0].node),
+		};
+		lvms_t_info = (structinfo_t) {
+			.max = MAX_LVM_VG,
+			.entry_size = sizeof lvms[0],
+			.entry_first = &lvms[0],
+			.entry_enabled = &(lvms[0].enabled),
+			.entry_blocked = &(lvms[0].blocked),
+			.entry_node = NULL,
+		};
+		lv_t_info = (structinfo_t) {
+			.max = MAX_LVM_LV,
+			.entry_size = sizeof lvms[0].lv[0], 
+			.entry_first = &lvms[0].lv[0],
+			.entry_enabled = &(lvms[0].lv[0].size),
+			.entry_blocked = &(lvms[0].lv[0].blocked),
+			.parent_size = sizeof lvms[0],
+		};
+
+		memset(&raids, 0, sizeof raids);
+		memset(&cgds, 0, sizeof cgds);
+		memset(&vnds, 0, sizeof vnds);
+		memset(&lvms, 0, sizeof lvms);
+		cursel = 0;
+		changed = 0;
+		firstrun = 0;
+	}
+
+	do {
+		menu_num_entries = pm_upddevlist(&(menudesc){.opts = menu_entries}, args);
+		menu_no = new_menu(MSG_partman_header,
+			menu_entries, menu_num_entries+1, 1, 1, 0, 75, /* Fixed width */
+			MC_ALWAYS_SCROLL | MC_NOBOX | MC_NOCLEAR,
+			pm_menuin, pm_menufmt, pm_menuout, NULL, MSG_finishpm);
+		if (menu_no == -1)
+			args[0].retvalue = -1;
+		else {
+			args[0].retvalue = 0;
+			clear();
+			refresh();
+			process_menu(menu_no, &args);
+			free_menu(menu_no);
+		}
+
+		if (args[0].retvalue == 0) {
+			if (pm_needsave())
+				pm_commit(NULL, NULL);
+			if (pm_mountall() != 0 ||
+				make_fstab() != 0 ||
+				pm_lastcheck() != 0 ||
+				pm_savebootsector() != 0) {
+					msg_display(MSG_wannatry);
+					process_menu(MENU_yesno, NULL);
+					args[0].retvalue = (yesno) ? 1:-1;
+			}
+		}
+	} while (args[0].retvalue > 0);
+	
+	/* retvalue <0 - error, retvalue ==0 - user quits, retvalue >0 - all ok */
+	return (args[0].retvalue >= 0)?0:-1;
+}
diff --git a/distrib/utils/sysinst/savenewlabel.c b/distrib/utils/sysinst/savenewlabel.c
index b8567a9..7a30466 100644
--- a/distrib/utils/sysinst/savenewlabel.c
+++ b/distrib/utils/sysinst/savenewlabel.c
@@ -58,7 +58,22 @@ int
 savenewlabel(partinfo *lp, int nparts)
 {
 	FILE *f;
+	char *f_name = malloc(STRSIZE * sizeof(char));
 	int i;
+	pm_devs_t *pm_i;
+
+	/* Check names collision */
+	if (partman_go)
+		SLIST_FOREACH(pm_i, &pm_head, l)
+			for (i = 'a'; pm_i != pm && i < 'z' &&
+					! strcmp(pm_i->bsddiskname, pm->bsddiskname); i++) {
+				if (strlen(pm_i->bsddiskname) > 0)
+					pm_i->bsddiskname[strlen(pm_i->bsddiskname)-1] = i;
+				else
+					snprintf(pm_i->bsddiskname, DISKNAME_SIZE, "disk %c", i);
+			}
+
+	snprintf(f_name, STRSIZE, "/tmp/disktab.%s", pm->bsddiskname);
 
 	/*
 	  N.B. disklabels only support up to 2TB (32-bit field for sectors).
@@ -67,40 +82,41 @@ savenewlabel(partinfo *lp, int nparts)
 	 */
 
 	/* Create /etc/disktab */
-	f = fopen("/tmp/disktab", "w");
+
+	f = fopen(f_name, "w");
 	if (logfp)
-		(void)fprintf(logfp, "Creating disklabel %s\n", bsddiskname);
+		(void)fprintf(logfp, "Creating disklabel %s in %s\n", pm->bsddiskname,
+						f_name);
 	scripting_fprintf(NULL, "cat <<EOF >>/etc/disktab\n");
 	if (f == NULL) {
 		endwin();
-		(void)fprintf(stderr, "Could not open /etc/disktab");
+		(void)fprintf(stderr, "Could not open %s for writing\n", f_name);
 		if (logfp)
-			(void)fprintf(logfp,
-			    "Failed to open /etc/disktab for appending.\n");
+			(void)fprintf(logfp, "Could not open %s for writing\n", f_name);
 		exit (1);
 	}
-	scripting_fprintf(f, "%s|NetBSD installation generated:\\\n", bsddiskname);
-	scripting_fprintf(f, "\t:dt=%s:ty=winchester:\\\n", disktype);
-	scripting_fprintf(f, "\t:nc#%d:nt#%d:ns#%d:\\\n", dlcyl, dlhead, dlsec);
-	scripting_fprintf(f, "\t:sc#%d:su#%" PRIu32 ":\\\n", dlhead*dlsec,
-	    (uint32_t)dlsize);
-	scripting_fprintf(f, "\t:se#%d:%s\\\n", sectorsize, doessf);
-	if ((size_t)nparts > __arraycount(bsdlabel)) {
-		nparts = __arraycount(bsdlabel);
+	scripting_fprintf(f, "%s|NetBSD installation generated:\\\n", pm->bsddiskname);
+	scripting_fprintf(f, "\t:dt=%s:ty=winchester:\\\n", pm->disktype);
+	scripting_fprintf(f, "\t:nc#%d:nt#%d:ns#%d:\\\n", pm->dlcyl, pm->dlhead, pm->dlsec);
+	scripting_fprintf(f, "\t:sc#%d:su#%" PRIu32 ":\\\n", pm->dlhead*pm->dlsec,
+	    (uint32_t)pm->dlsize);
+	scripting_fprintf(f, "\t:se#%d:%s\\\n", pm->sectorsize, pm->doessf);
+	if ((size_t)nparts > __arraycount(pm->bsdlabel)) {
+		nparts = __arraycount(pm->bsdlabel);
 		if (logfp)
 			(void)fprintf(logfp, "nparts limited to %d.\n", nparts);
 	}
 	for (i = 0; i < nparts; i++) {
 		scripting_fprintf(f, "\t:p%c#%" PRIu32 ":o%c#%" PRIu32
-		    ":t%c=%s:", 'a'+i, (uint32_t)bsdlabel[i].pi_size,
-		    'a'+i, (uint32_t)bsdlabel[i].pi_offset, 'a'+i,
-		    getfslabelname(bsdlabel[i].pi_fstype));
-		if (PI_ISBSDFS(&bsdlabel[i]))
+		    ":t%c=%s:", 'a'+i, (uint32_t)lp[i].pi_size,
+		    'a'+i, (uint32_t)lp[i].pi_offset, 'a'+i,
+		    getfslabelname(lp[i].pi_fstype));
+		if (PI_ISBSDFS(&lp[i]))
 			scripting_fprintf (f, "b%c#%" PRIu32 ":f%c#%" PRIu32
 			    ":", 'a'+i,
-			    (uint32_t)(bsdlabel[i].pi_fsize *
-			    bsdlabel[i].pi_frag),
-			    'a'+i, (uint32_t)bsdlabel[i].pi_fsize);
+			    (uint32_t)(lp[i].pi_fsize *
+			    lp[i].pi_frag),
+			    'a'+i, (uint32_t)lp[i].pi_fsize);
 	
 		if (i < nparts - 1)
 			scripting_fprintf(f, "\\\n");
@@ -110,5 +126,6 @@ savenewlabel(partinfo *lp, int nparts)
 	fclose (f);
 	scripting_fprintf(NULL, "EOF\n");
 	fflush(NULL);
+	run_program(0, "sh -c 'cat /tmp/disktab.* >/tmp/disktab'");
 	return(0);
 }
diff --git a/distrib/utils/sysinst/sizemultname.c b/distrib/utils/sysinst/sizemultname.c
index 5829c73..ffd9c16 100644
--- a/distrib/utils/sysinst/sizemultname.c
+++ b/distrib/utils/sysinst/sizemultname.c
@@ -52,7 +52,7 @@ void
 set_sizemultname_cyl(void)
 {
 
-	sizemult = dlcylsize;
+	sizemult = pm->dlcylsize;
 	multname = msg_string(MSG_cylname);
 }
 
@@ -60,6 +60,6 @@ void
 set_sizemultname_meg(void)
 {
 
-	sizemult = MEG / sectorsize;
+	sizemult = MEG / pm->sectorsize;
 	multname = msg_string(MSG_megname);
 }
diff --git a/distrib/utils/sysinst/target.c b/distrib/utils/sysinst/target.c
index dee3266..811ef1a 100644
--- a/distrib/utils/sysinst/target.c
+++ b/distrib/utils/sysinst/target.c
@@ -146,20 +146,20 @@ backtowin(void)
 /*
  * Is the root partition we're running from the same as the root 
  * which the user has selected to install/upgrade?
- * Uses global variable "diskdev" to find the selected device for
+ * Uses global variable "pm->diskdev" to find the selected device for
  * install/upgrade.
  */
 int
 target_already_root(void)
 {
 
-	if (strcmp(diskdev, "") == 0)
+	if (strcmp(pm->diskdev, "") == 0)
 		/* No root partition was ever selected.
 		 * Assume that the currently mounted one should be used
 		 */
 		return 1;
 
-	return is_active_rootpart(diskdev, rootpart);
+	return is_active_rootpart(pm->diskdev, pm->rootpart);
 }
 
 
@@ -280,7 +280,10 @@ do_target_chdir(const char *dir, int must_succeed)
 	error = 0;
 	tgt_dir = target_expand(dir);
 
-#ifndef DEBUG
+#ifdef DEBUG
+	printf("target_chdir (%s)\n", tgt_dir);
+	//return (0);
+#endif
 	/* chdir returns -1 on error and sets errno. */
 	if (chdir(tgt_dir) < 0)
 		error = errno;
@@ -303,10 +306,6 @@ do_target_chdir(const char *dir, int must_succeed)
 	}
 	errno = error;
 	return (error);
-#else
-	printf("target_chdir (%s)\n", tgt_dir);
-	return (0);
-#endif
 }
 
 void
@@ -396,7 +395,7 @@ target_fopen(const char *filename, const char *type)
  * NB: does not prefix mount-from, which probably breaks nullfs mounts.
  */
 int
-target_mount(const char *opts, const char *from, int ptn, const char *on)
+target_mount_do(const char *opts, const char *from, const char *on)
 {
 	struct unwind_mount *m;
 	int error;
@@ -415,8 +414,8 @@ target_mount(const char *opts, const char *from, int ptn, const char *on)
 	backtowin();
 #endif
 
-	error = run_program(0, "/sbin/mount %s /dev/%s%c %s%s",
-			opts, from, 'a' + ptn, target_prefix(), on);
+	error = run_program(0, "/sbin/mount %s %s %s%s",
+			opts, from, target_prefix(), on);
 	if (error) {
 		free(m);
 		return error;
@@ -426,6 +425,19 @@ target_mount(const char *opts, const char *from, int ptn, const char *on)
 	return 0;
 }
 
+int
+target_mount(const char *opts, const char *from, int ptn, const char *on)
+{
+	int error;
+	char *frompath;
+	asprintf (&frompath, "/dev/%s%c", from, (ptn < 0)? 0 : 'a' + ptn);
+	if (frompath == 0)
+		return (ENOMEM);
+	error = target_mount_do(opts, frompath, on);
+	free(frompath);
+	return error;
+}
+
 /*
  * unwind the mount stack, unmounting mounted filesystems.
  * For now, ignore any errors in unmount. 
diff --git a/distrib/utils/sysinst/upgrade.c b/distrib/utils/sysinst/upgrade.c
index af7d088..9bf303d 100644
--- a/distrib/utils/sysinst/upgrade.c
+++ b/distrib/utils/sysinst/upgrade.c
@@ -54,6 +54,8 @@ static int merge_X(const char *);
 void
 do_upgrade(void)
 {
+	int retcode = 0;
+	partman_go = 0;
 
 	msg_display(MSG_upgradeusure);
 	process_menu(MENU_noyes, NULL);
@@ -68,8 +70,6 @@ do_upgrade(void)
 	if (md_pre_update() < 0)
 		return;
 
-	process_menu(MENU_distset, NULL);
-
 	if (mount_disks() != 0)
 		return;
 
@@ -96,6 +96,9 @@ do_upgrade(void)
 	wrefresh(stdscr);
 
 	/* Done with disks. Ready to get and unpack tarballs. */
+	process_menu(MENU_distset, &retcode);
+	if (retcode == 0)
+		return;
 	if (get_and_unpack_sets(1, MSG_disksetupdoneupdate,
 	    MSG_upgrcomplete, MSG_abortupgr) != 0)
 		return;
@@ -172,6 +175,7 @@ merge_X(const char *xroot)
 void
 do_reinstall_sets(void)
 {
+	int retcode = 0;
 
 	unwind_mounts();
 	msg_display(MSG_reinstallusure);
@@ -182,12 +186,13 @@ do_reinstall_sets(void)
 	if (find_disks(msg_string(MSG_reinstall)) < 0)
 		return;
 
-	process_menu(MENU_distset, NULL);
-
 	if (mount_disks() != 0)
 		return;
 
 	/* Unpack the distribution. */
+	process_menu(MENU_distset, &retcode);
+	if (retcode == 0)
+		return;
 	if (get_and_unpack_sets(0, NULL, MSG_unpackcomplete, MSG_abortunpack) != 0)
 		return;
 
diff --git a/distrib/utils/sysinst/util.c b/distrib/utils/sysinst/util.c
index f290979..17adc80 100644
--- a/distrib/utils/sysinst/util.c
+++ b/distrib/utils/sysinst/util.c
@@ -358,8 +358,10 @@ floppy_fetch(const char *set_name)
 int
 get_via_floppy(void)
 {
-
+	yesno = -1;
 	process_menu(MENU_floppysource, NULL);
+	if (yesno == SET_RETRY)
+		return SET_RETRY;
 
 	fetch_fn = floppy_fetch;
 
@@ -487,14 +489,6 @@ cd_has_sets(void)
 	return dir_exists_p(ext_dir_bin);
 }
 
-
-static int
-set_cd_select(menudesc *m, void *arg)
-{
-	*(int *)arg = m->cursel;
-	return 1;
-}
-
 /*
  * Check whether we can remove the boot media.
  * If it is not a local filesystem, return -1.
@@ -551,7 +545,7 @@ get_via_cdrom(void)
 			cd_menu[i].opt_name = cds[i].menu;
 			cd_menu[i].opt_menu = OPT_NOMENU;
 			cd_menu[i].opt_flags = OPT_EXIT;
-			cd_menu[i].opt_action = set_cd_select;
+			cd_menu[i].opt_action = set_menu_select;
 		}
 		/* create a menu offering available choices */
 		menu_cd = new_menu(MSG_Available_cds,
@@ -577,7 +571,10 @@ get_via_cdrom(void)
 	}
 
 	/* ask for paths on the CD */
+	yesno = -1;
 	process_menu(MENU_cdromsource, NULL);
+	if (yesno == SET_RETRY)
+		return SET_RETRY;
 
 	if (cd_has_sets())
 		return SET_OK;
@@ -593,9 +590,11 @@ get_via_cdrom(void)
 int
 get_via_localfs(void)
 {
-
 	/* Get device, filesystem, and filepath */
+	yesno = -1;
 	process_menu (MENU_localfssource, NULL);
+	if (yesno == SET_RETRY)
+		return SET_RETRY;
 
 	/* Mount it */
 	if (run_program(0, "/sbin/mount -rt %s /dev/%s /mnt2",
@@ -619,9 +618,11 @@ get_via_localfs(void)
 int
 get_via_localdir(void)
 {
-
 	/* Get filepath */
+	yesno = -1;
 	process_menu(MENU_localdirsource, NULL);
+	if (yesno == SET_RETRY)
+		return SET_RETRY;
 
 	/*
 	 * We have to have an absolute path ('cos pax runs in a
@@ -1604,3 +1605,30 @@ ext_dir_for_set(const char *set_name) {
 	return set_is_source(set_name) ? ext_dir_src : ext_dir_bin;
 }
 
+void
+do_coloring(unsigned int fg, unsigned int bg) {
+	if (bg > COLOR_WHITE)
+		bg = COLOR_BLUE;
+	if (fg > COLOR_WHITE)
+		fg = COLOR_WHITE;
+	if (fg != bg && has_colors()) {
+		init_pair(1, fg, bg);
+		wbkgd(stdscr, COLOR_PAIR(1));
+		wbkgd(mainwin, COLOR_PAIR(1));
+		wattrset(stdscr, COLOR_PAIR(1));
+		wattrset(mainwin, COLOR_PAIR(1));
+	}
+	/* redraw screen */
+	touchwin(stdscr);
+	touchwin(mainwin);
+	wrefresh(stdscr);
+	wrefresh(mainwin);
+	return;
+}
+
+int
+set_menu_select(menudesc *m, void *arg)
+{
+	*(int *)arg = m->cursel;
+	return 1;
+}
