diff --git a/distrib/utils/sysinst/Makefile.inc b/distrib/utils/sysinst/Makefile.inc
index 6353721..19c67d8 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/}
diff --git a/distrib/utils/sysinst/arch/acorn32/md.c b/distrib/utils/sysinst/arch/acorn32/md.c
index efa9de6..96708ff 100644
--- a/distrib/utils/sysinst/arch/acorn32/md.c
+++ b/distrib/utils/sysinst/arch/acorn32/md.c
@@ -66,7 +66,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 	static unsigned char bb[DEV_BSIZE];
@@ -74,9 +74,9 @@ md_get_info(void)
 	int offset = 0;
 
 	if (strncmp(pm->diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
 	snprintf(dev_name, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
 
@@ -86,7 +86,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf(stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -173,11 +173,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -186,8 +186,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	pm->ptstart = offset;
 /*	endwin();
@@ -199,7 +199,7 @@ md_get_info(void)
 	printf("dlsz=%d\n", pm->dlsize);
 	printf("pstart=%d\n", pm->ptstart);
 	printf("pstart=%d\n", partsize);
-	printf("secpun=%d\n", pm->disklabel.d_secperunit);
+	printf("secpun=%d\n", disklabel.d_secperunit);
 	backtowin();*/
 
 	return 1;
diff --git a/distrib/utils/sysinst/arch/alpha/md.c b/distrib/utils/sysinst/arch/alpha/md.c
index b481739..cd8fb82 100644
--- a/distrib/utils/sysinst/arch/alpha/md.c
+++ b/distrib/utils/sysinst/arch/alpha/md.c
@@ -63,7 +63,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -75,7 +75,7 @@ md_get_info(void)
 		fprintf (stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -83,11 +83,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -96,8 +96,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/amd64/md.h b/distrib/utils/sysinst/arch/amd64/md.h
index e5ce41d..6f4325e 100644
--- a/distrib/utils/sysinst/arch/amd64/md.h
+++ b/distrib/utils/sysinst/arch/amd64/md.h
@@ -89,7 +89,7 @@
  * On amd64, we allow "wd"  ST-506/IDE disks,  "sd" scsi disks, "ld" logical
  * disks and "raid" raidframe disks.
  */
-#define DISK_NAMES "wd", "sd", "ld", "raid:pm->no_mbr", "xbd:pm->no_mbr"
+#define DISK_NAMES "wd", "sd", "ld", "raid:no_mbr", "xbd:no_mbr"
 
 /*
  * Machine-specific command to write a new label to a disk.
diff --git a/distrib/utils/sysinst/arch/arc/md.c b/distrib/utils/sysinst/arch/arc/md.c
index e0a93c4..0363ef9 100644
--- a/distrib/utils/sysinst/arch/arc/md.c
+++ b/distrib/utils/sysinst/arch/arc/md.c
@@ -159,7 +159,7 @@ md_make_bsd_partitions(void)
 		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 {
@@ -173,7 +173,7 @@ md_make_bsd_partitions(void)
 		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/* XXX Check we have a sensible layout */
 		;
 	} else
diff --git a/distrib/utils/sysinst/arch/atari/md.c b/distrib/utils/sysinst/arch/atari/md.c
index 59aaacc..4c2ab3d 100644
--- a/distrib/utils/sysinst/arch/atari/md.c
+++ b/distrib/utils/sysinst/arch/atari/md.c
@@ -80,9 +80,9 @@ md_make_bsd_partitions(void)
 	 * Setup the disktype so /etc/disktab gets proper info
 	 */
 	if (strncmp (pm->diskdev, "sd", 2) == 0)
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 	else
-		disktype = "ST506";
+		pm->disktype = "ST506";
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/cats/md.c b/distrib/utils/sysinst/arch/cats/md.c
index e799339..6ac23d6 100644
--- a/distrib/utils/sysinst/arch/cats/md.c
+++ b/distrib/utils/sysinst/arch/cats/md.c
@@ -63,7 +63,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 #if 0
@@ -73,9 +73,9 @@ md_get_info(void)
 	int offset = 0;
 
 	if (strncmp(pm->diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
 	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
@@ -85,7 +85,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf(stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -94,11 +94,11 @@ md_get_info(void)
 
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -107,8 +107,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	pm->ptstart = offset;
 /*	endwin();
@@ -120,7 +120,7 @@ md_get_info(void)
 	printf("dlsz=%d\n", pm->dlsize);
 	printf("pstart=%d\n", pm->ptstart);
 	printf("pstart=%d\n", partsize);
-	printf("secpun=%d\n", pm->disklabel.d_secperunit);
+	printf("secpun=%d\n", disklabel.d_secperunit);
 	backtowin();*/
 
 	return 1;
diff --git a/distrib/utils/sysinst/arch/cobalt/md.c b/distrib/utils/sysinst/arch/cobalt/md.c
index 1826669..a96053f 100644
--- a/distrib/utils/sysinst/arch/cobalt/md.c
+++ b/distrib/utils/sysinst/arch/cobalt/md.c
@@ -160,7 +160,7 @@ md_make_bsd_partitions(void)
 		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 {
@@ -174,7 +174,7 @@ md_make_bsd_partitions(void)
 		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/* XXX Check we have a sensible layout */
 		;
 	} else
diff --git a/distrib/utils/sysinst/arch/emips/md.c b/distrib/utils/sysinst/arch/emips/md.c
index fc6a514..30e46e9 100644
--- a/distrib/utils/sysinst/arch/emips/md.c
+++ b/distrib/utils/sysinst/arch/emips/md.c
@@ -62,7 +62,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -76,7 +76,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -87,11 +87,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -100,8 +100,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	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 f381f46..2a7b53f 100644
--- a/distrib/utils/sysinst/arch/evbarm/md.c
+++ b/distrib/utils/sysinst/arch/evbarm/md.c
@@ -63,7 +63,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -77,9 +77,9 @@ md_get_info(void)
 		return 0;
 
 	if (strncmp(pm->diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
 	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
@@ -89,7 +89,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf(stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -97,11 +97,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -110,8 +110,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/evbppc/md.c b/distrib/utils/sysinst/arch/evbppc/md.c
index b60eb35..f311431 100644
--- a/distrib/utils/sysinst/arch/evbppc/md.c
+++ b/distrib/utils/sysinst/arch/evbppc/md.c
@@ -103,7 +103,7 @@ 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",
 		    pm->diskdev);
diff --git a/distrib/utils/sysinst/arch/evbsh3/md.c b/distrib/utils/sysinst/arch/evbsh3/md.c
index d858a3c..76df729 100644
--- a/distrib/utils/sysinst/arch/evbsh3/md.c
+++ b/distrib/utils/sysinst/arch/evbsh3/md.c
@@ -51,7 +51,7 @@
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -63,7 +63,7 @@ md_get_info(void)
 		fprintf (stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -71,11 +71,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -84,8 +84,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/evbsh3/md.h b/distrib/utils/sysinst/arch/evbsh3/md.h
index 9c8947a..7182e72 100644
--- a/distrib/utils/sysinst/arch/evbsh3/md.h
+++ b/distrib/utils/sysinst/arch/evbsh3/md.h
@@ -36,7 +36,7 @@
 /*
  * Symbolic names for disk partitions
  */
-#include <machine/pm->disklabel.h>
+#include <machine/disklabel.h>
 
 #define	PART_ROOT	PART_A
 #define	PART_SWAP	PART_B
diff --git a/distrib/utils/sysinst/arch/ews4800mips/md.c b/distrib/utils/sysinst/arch/ews4800mips/md.c
index a77bb43..925dde8 100644
--- a/distrib/utils/sysinst/arch/ews4800mips/md.c
+++ b/distrib/utils/sysinst/arch/ews4800mips/md.c
@@ -65,7 +65,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -77,7 +77,7 @@ md_get_info(void)
 		fprintf (stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -85,11 +85,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -98,8 +98,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/hp300/md.c b/distrib/utils/sysinst/arch/hp300/md.c
index ff3d6c6..e58dc39 100644
--- a/distrib/utils/sysinst/arch/hp300/md.c
+++ b/distrib/utils/sysinst/arch/hp300/md.c
@@ -64,7 +64,7 @@ md_get_info(void)
 	char buf[1024];
 	int fd;
 	char dev_name[100];
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 
 	snprintf(dev_name, sizeof(dev_name), "/dev/r%sc", pm->diskdev);
 
@@ -76,7 +76,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -85,18 +85,18 @@ md_get_info(void)
 		close(fd);
 		exit(1);
 	}
-	if (pm->disklabel.d_secsize != 512) {
+	if (disklabel.d_secsize != 512) {
 		endwin();
 		fprintf(stderr, "Non-512byte/sector disk is not supported.\n");
 		close(fd);
 		exit(1);
 	}
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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;
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
 
 	if (read(fd, buf, 1024) < 0) {
diff --git a/distrib/utils/sysinst/arch/hp700/md.c b/distrib/utils/sysinst/arch/hp700/md.c
index 17ebd2e..229729c 100644
--- a/distrib/utils/sysinst/arch/hp700/md.c
+++ b/distrib/utils/sysinst/arch/hp700/md.c
@@ -66,7 +66,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -80,7 +80,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -91,11 +91,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -104,8 +104,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	/*
 	 * hp700 PDC can only address up to 2GB.
diff --git a/distrib/utils/sysinst/arch/hpcarm/md.c b/distrib/utils/sysinst/arch/hpcarm/md.c
index 628a48c..4820214 100644
--- a/distrib/utils/sysinst/arch/hpcarm/md.c
+++ b/distrib/utils/sysinst/arch/hpcarm/md.c
@@ -132,7 +132,7 @@ 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",
 		    pm->diskdev);
diff --git a/distrib/utils/sysinst/arch/hpcmips/md.c b/distrib/utils/sysinst/arch/hpcmips/md.c
index cbdd705..47eee83 100644
--- a/distrib/utils/sysinst/arch/hpcmips/md.c
+++ b/distrib/utils/sysinst/arch/hpcmips/md.c
@@ -106,7 +106,7 @@ 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",
 		    pm->diskdev);
diff --git a/distrib/utils/sysinst/arch/i386/md.c b/distrib/utils/sysinst/arch/i386/md.c
index 4b51cb90..bed7e5e 100644
--- a/distrib/utils/sysinst/arch/i386/md.c
+++ b/distrib/utils/sysinst/arch/i386/md.c
@@ -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", pm->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) {
diff --git a/distrib/utils/sysinst/arch/i386/md.h b/distrib/utils/sysinst/arch/i386/md.h
index ee1adfa..d99f4e3 100644
--- a/distrib/utils/sysinst/arch/i386/md.h
+++ b/distrib/utils/sysinst/arch/i386/md.h
@@ -84,7 +84,7 @@
  * On i386, we allow "wd"  ST-506/IDE disks,  "sd" scsi disks, "ld" logical
  * disks, "ed" IBM ESDI disks, "raid" raidframe disks
  */
-#define DISK_NAMES "wd", "sd", "ld", "ed", "raid:pm->no_mbr", "xbd:pm->no_mbr"
+#define DISK_NAMES "wd", "sd", "ld", "ed", "raid:no_mbr", "xbd:no_mbr"
 
 /*
  * Machine-specific command to write a new label to a disk.
diff --git a/distrib/utils/sysinst/arch/luna68k/md.c b/distrib/utils/sysinst/arch/luna68k/md.c
index 7e52b20..b27b69f 100644
--- a/distrib/utils/sysinst/arch/luna68k/md.c
+++ b/distrib/utils/sysinst/arch/luna68k/md.c
@@ -64,7 +64,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -76,7 +76,7 @@ md_get_info(void)
 		fprintf (stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -84,11 +84,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -97,8 +97,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/mac68k/md.c b/distrib/utils/sysinst/arch/mac68k/md.c
index 20119eb..c2ad149 100644
--- a/distrib/utils/sysinst/arch/mac68k/md.c
+++ b/distrib/utils/sysinst/arch/mac68k/md.c
@@ -134,7 +134,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd, i;
 	char dev_name[100];
 	struct apple_part_map_entry block;
@@ -154,7 +154,7 @@ md_get_info(void)
 	/*
 	 * Try to get the default disklabel info for the device
 	 */
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s\n", dev_name);
 		close(fd);
@@ -164,15 +164,15 @@ md_get_info(void)
 	 * Get the disk parameters from the disk driver.  It should have
 	 *  obained them by querying the disk itself.
 	 */
-	blk_size = pm->disklabel.d_secsize;
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
+	blk_size = disklabel.d_secsize;
+	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.
 	 */
-	pm->dlsize = pm->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 +
@@ -185,7 +185,7 @@ md_get_info(void)
 	   }
 	   pm->dlsize -= new_map[i].pmPartBlkCnt;
 	}
-	pm->dlsize = pm->disklabel.d_secperunit;
+	pm->dlsize = disklabel.d_secperunit;
 #if 0
 	msg_display(MSG_dldebug, blk_size, pm->dlcyl, pm->dlhead, pm->dlsec, pm->dlsize);
 	process_menu(MENU_ok, NULL);
@@ -224,10 +224,10 @@ md_get_info(void)
 	 * Setup the disktype so /etc/disktab gets proper info
 	 */
 	if (strncmp(pm->diskdev, "sd", 2) == 0) {
-		disktype = "SCSI";
-		doessf = "sf:";
+		pm->disktype = "SCSI";
+		pm->doessf = "sf:";
 	} else
-		disktype = "IDE";
+		pm->disktype = "IDE";
 
 	return edit_diskmap();
 }
@@ -270,7 +270,7 @@ md_make_bsd_partitions(void)
 	pm->bsdlabel[RAW_PART].pi_size = pm->dlsize;
 	/*
 	 * Now, scan through the Disk Partition Map and transfer the
-	 *  information into the incore pm->disklabel.
+	 *  information into the incore disklabel.
 	 */
 	for (i=0;i<map.usable_cnt;i++) {
 	    j = map.mblk[i];
@@ -322,10 +322,10 @@ md_make_bsd_partitions(void)
 		exit (1);
 	}
 	(void)fprintf (f, "%s|NetBSD installation generated:\\\n", pm->bsddiskname);
-	(void)fprintf (f, "\t:dt=%s:ty=winchester:\\\n", disktype);
+	(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, doessf);
+	(void)fprintf (f, "\t:se#%d:%s\\\n", blk_size, pm->doessf);
 	for (i=0; i<8; i++) {
 		if (pm->bsdlabel[i].pi_fstype == FS_HFS)
 		    (void)fprintf (f, "\t:p%c#%d:o%c#%d:t%c=macos:",
@@ -369,7 +369,7 @@ md_pre_disklabel(void)
 {
     int fd;
     char dev_name[100];
-    struct pm->disklabel lp;
+    struct disklabel lp;
     Block0 new_block0 = {APPLE_DRVR_MAP_MAGIC, 512,
 	 		 0, 0, 0, 0, 0, 0, 0, 0, {0}};
 
@@ -457,7 +457,7 @@ md_pre_disklabel(void)
 int
 md_post_disklabel(void)
 {
-    struct pm->disklabel updated_label;
+    struct disklabel updated_label;
     int fd, i, no_match;
     char dev_name[100], buf[80];
     const char *fst[] = {"free", "swap", " v6 ", " v7 ", "sysv", "v71k",
diff --git a/distrib/utils/sysinst/arch/macppc/md.c b/distrib/utils/sysinst/arch/macppc/md.c
index ff9c6e7..d9138ea 100644
--- a/distrib/utils/sysinst/arch/macppc/md.c
+++ b/distrib/utils/sysinst/arch/macppc/md.c
@@ -63,7 +63,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -75,7 +75,7 @@ md_get_info(void)
 		fprintf (stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -83,11 +83,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -96,8 +96,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/mipsco/md.c b/distrib/utils/sysinst/arch/mipsco/md.c
index 7f2db6a..5722452 100644
--- a/distrib/utils/sysinst/arch/mipsco/md.c
+++ b/distrib/utils/sysinst/arch/mipsco/md.c
@@ -63,7 +63,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -77,7 +77,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -88,11 +88,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -101,8 +101,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/mvme68k/md.c b/distrib/utils/sysinst/arch/mvme68k/md.c
index 7821f98..4d774ca 100644
--- a/distrib/utils/sysinst/arch/mvme68k/md.c
+++ b/distrib/utils/sysinst/arch/mvme68k/md.c
@@ -64,7 +64,7 @@ md_get_info(void)
 	char buf[1024];
 	int fd;
 	char dev_name[100];
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 
 	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
@@ -76,7 +76,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -85,18 +85,18 @@ md_get_info(void)
 		close(fd);
 		exit(1);
 	}
-	if (pm->disklabel.d_secsize != 512) {
+	if (disklabel.d_secsize != 512) {
 		endwin();
 		fprintf(stderr, "Non-512byte/sector disk is not supported.\n");
 		close(fd);
 		exit(1);
 	}
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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;
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
 
 	if (read(fd, buf, 1024) < 0) {
@@ -107,7 +107,7 @@ md_get_info(void)
 	}
 
 	/* preserve first cylinder for system. */
-	pm->ptstart = pm->disklabel.d_secpercyl;
+	pm->ptstart = disklabel.d_secpercyl;
 
 	close(fd);
 
diff --git a/distrib/utils/sysinst/arch/news68k/md.c b/distrib/utils/sysinst/arch/news68k/md.c
index f355c04..385cfa7 100644
--- a/distrib/utils/sysinst/arch/news68k/md.c
+++ b/distrib/utils/sysinst/arch/news68k/md.c
@@ -64,7 +64,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -76,7 +76,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf(stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -84,11 +84,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -97,8 +97,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl * pm->dlhead * pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/newsmips/md.c b/distrib/utils/sysinst/arch/newsmips/md.c
index 030cbef..a37c56b 100644
--- a/distrib/utils/sysinst/arch/newsmips/md.c
+++ b/distrib/utils/sysinst/arch/newsmips/md.c
@@ -63,7 +63,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -75,7 +75,7 @@ md_get_info(void)
 		fprintf (stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf (stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -83,11 +83,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -96,8 +96,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/ofppc/md.c b/distrib/utils/sysinst/arch/ofppc/md.c
index d522ee6..7d6d7aea 100644
--- a/distrib/utils/sysinst/arch/ofppc/md.c
+++ b/distrib/utils/sysinst/arch/ofppc/md.c
@@ -101,7 +101,7 @@ md_make_bsd_partitions(void)
 	if (rdb_found) {
 		/*
 		 * We found RDB partitions on the disk, which cannot be
-		 * modified by rewriting the pm->disklabel.
+		 * modified by rewriting the disklabel.
 		 * So just use what we have got.
 		 */
 		for (part = 0; part < maxpart; part++) {
@@ -218,7 +218,7 @@ rdb_edit_check:
 		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 {
@@ -232,7 +232,7 @@ rdb_edit_check:
 		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/* XXX Check we have a sensible layout */
 		;
 	} else
diff --git a/distrib/utils/sysinst/arch/pmax/md.c b/distrib/utils/sysinst/arch/pmax/md.c
index 19aabd8..a0033a2 100644
--- a/distrib/utils/sysinst/arch/pmax/md.c
+++ b/distrib/utils/sysinst/arch/pmax/md.c
@@ -62,7 +62,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -76,7 +76,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -87,11 +87,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -100,8 +100,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/sandpoint/md.c b/distrib/utils/sysinst/arch/sandpoint/md.c
index fc42a72..76a9156 100644
--- a/distrib/utils/sysinst/arch/sandpoint/md.c
+++ b/distrib/utils/sysinst/arch/sandpoint/md.c
@@ -137,7 +137,7 @@ 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",
 		    pm->diskdev);
diff --git a/distrib/utils/sysinst/arch/sgimips/md.c b/distrib/utils/sysinst/arch/sgimips/md.c
index 98d7897..d13f78e 100644
--- a/distrib/utils/sysinst/arch/sgimips/md.c
+++ b/distrib/utils/sysinst/arch/sgimips/md.c
@@ -79,7 +79,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -93,7 +93,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -104,11 +104,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -117,8 +117,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/sgimips/md.h b/distrib/utils/sysinst/arch/sgimips/md.h
index d51ce67..92be0d4 100644
--- a/distrib/utils/sysinst/arch/sgimips/md.h
+++ b/distrib/utils/sysinst/arch/sgimips/md.h
@@ -63,7 +63,7 @@
  * hand-edited disklabel will NOT be written by MI code.
  */
 /*
- * sgimips should not use -r, as this prevents the SGI pm->disklabel
+ * sgimips should not use -r, as this prevents the SGI disklabel
  * from being written.
  */
 #define DISKLABEL_CMD "disklabel -w"
diff --git a/distrib/utils/sysinst/arch/shark/md.c b/distrib/utils/sysinst/arch/shark/md.c
index 593f6ca..ae41583 100644
--- a/distrib/utils/sysinst/arch/shark/md.c
+++ b/distrib/utils/sysinst/arch/shark/md.c
@@ -65,14 +65,14 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
 	if (strncmp(pm->diskdev, "wd", 2) == 0)
-		disktype = "ST506";
+		pm->disktype = "ST506";
 	else
-		disktype = "SCSI";
+		pm->disktype = "SCSI";
 
 	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
@@ -82,7 +82,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		endwin();
 		fprintf(stderr, "Can't read disklabel on %s.\n", dev_name);
 		close(fd);
@@ -90,11 +90,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -103,8 +103,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/sparc/md.c b/distrib/utils/sysinst/arch/sparc/md.c
index 1fa8360..01b1270 100644
--- a/distrib/utils/sysinst/arch/sparc/md.c
+++ b/distrib/utils/sysinst/arch/sparc/md.c
@@ -68,7 +68,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -82,7 +82,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -93,11 +93,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -106,8 +106,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/sparc64/md.c b/distrib/utils/sysinst/arch/sparc64/md.c
index 7a1152f..03be22d 100644
--- a/distrib/utils/sysinst/arch/sparc64/md.c
+++ b/distrib/utils/sysinst/arch/sparc64/md.c
@@ -69,7 +69,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -83,7 +83,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -94,11 +94,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -107,8 +107,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/vax/md.c b/distrib/utils/sysinst/arch/vax/md.c
index 2fc804c..4f026e3 100644
--- a/distrib/utils/sysinst/arch/vax/md.c
+++ b/distrib/utils/sysinst/arch/vax/md.c
@@ -66,7 +66,7 @@ md_init_set_status(int flags)
 int
 md_get_info(void)
 {
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 	int fd;
 	char dev_name[100];
 
@@ -80,7 +80,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -91,11 +91,11 @@ md_get_info(void)
 	}
 	close(fd);
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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 (pm->dlcyl*pm->dlhead*pm->dlsec)
@@ -104,8 +104,8 @@ md_get_info(void)
 	 * in-core RAW_PART size  value, updating the label will fail.)
 	 */
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
-	if (pm->disklabel.d_secperunit > pm->dlsize)
-		pm->dlsize = pm->disklabel.d_secperunit;
+	if (disklabel.d_secperunit > pm->dlsize)
+		pm->dlsize = disklabel.d_secperunit;
 
 	return 1;
 }
diff --git a/distrib/utils/sysinst/arch/x68k/md.c b/distrib/utils/sysinst/arch/x68k/md.c
index dd862ea..762036c 100644
--- a/distrib/utils/sysinst/arch/x68k/md.c
+++ b/distrib/utils/sysinst/arch/x68k/md.c
@@ -81,7 +81,7 @@ md_get_info(void)
 	char buf[1024];
 	int fd;
 	char dev_name[100];
-	struct pm->disklabel pm->disklabel;
+	struct disklabel disklabel;
 
 	snprintf(dev_name, 100, "/dev/r%sc", pm->diskdev);
 
@@ -93,7 +93,7 @@ md_get_info(void)
 		fprintf(stderr, "Can't open %s\n", dev_name);
 		exit(1);
 	}
-	if (ioctl(fd, DIOCGDINFO, &pm->disklabel) == -1) {
+	if (ioctl(fd, DIOCGDINFO, &disklabel) == -1) {
 		if (logfp)
 			(void)fprintf(logfp, "Can't read disklabel on %s.\n",
 				dev_name);
@@ -102,18 +102,18 @@ md_get_info(void)
 		close(fd);
 		exit(1);
 	}
-	if (pm->disklabel.d_secsize != 512) {
+	if (disklabel.d_secsize != 512) {
 		endwin();
 		fprintf(stderr, "Non-512byte/sector disk is not supported.\n");
 		close(fd);
 		exit(1);
 	}
 
-	pm->dlcyl = pm->disklabel.d_ncylinders;
-	pm->dlhead = pm->disklabel.d_ntracks;
-	pm->dlsec = pm->disklabel.d_nsectors;
-	pm->sectorsize = pm->disklabel.d_secsize;
-	pm->dlcylsize = pm->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;
 	pm->dlsize = pm->dlcyl*pm->dlhead*pm->dlsec;
 
 	if (read(fd, buf, 1024) < 0) {
diff --git a/distrib/utils/sysinst/bsddisklabel.c b/distrib/utils/sysinst/bsddisklabel.c
index 82c116d..745cdf1 100644
--- a/distrib/utils/sysinst/bsddisklabel.c
+++ b/distrib/utils/sysinst/bsddisklabel.c
@@ -218,8 +218,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?"Mountpoint or 'raid' or 'cgd'?":MSG_askfsmount,
+			-1, 18, 0, 0, NULL, p->mount, sizeof p->mount);
 		if (p->mount[0] == 0)
 			return 0;
 	}
@@ -347,7 +347,8 @@ get_ptn_sizes(daddr_t part_start, daddr_t sectors, int no_swap)
 	struct ptn_size *p;
 	daddr_t size;
 
-	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},
@@ -379,133 +380,134 @@ 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;
+			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 / 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++) {
+		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);
-			pi.free_space -= p->size;
+			pm->pi.free_space -= p->size;
 		}
 
 		/* Steal space from swap to make things fit.. */
-		if (pi.free_space < 0) {
-			i = roundup(-pi.free_space, pm->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, pm->dlcylsize);
-		if (pi.free_space > i * 2)
+		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;
 		}
 
 		/* 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 (pm->bsdlabel[i].pi_size == 0)
-				pi.free_parts++;
+				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_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);
+		set_ptn_menu(&pm->pi);
 		pm->current_cylsize = pm->dlcylsize;
-		process_menu(pi.menu_no, &pi);
-	} while (pi.free_space < 0 || pi.free_parts < 0);
+		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 < pm->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 % pm->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, pm->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;
 		}
@@ -521,6 +523,13 @@ get_ptn_sizes(daddr_t part_start, daddr_t sectors, int no_swap)
 			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,7 +547,9 @@ 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.
@@ -553,12 +564,13 @@ make_bsd_partitions(void)
 	ptend = pm->ptstart + pm->ptsize;
 
 	/* Ask for layout type -- standard or special */
-	msg_display(MSG_layout,
+	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 */
 	pm->current_cylsize = pm->dlcylsize;
@@ -633,7 +645,7 @@ make_bsd_partitions(void)
 	pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
 #endif
 
-	if (layoutkind == 4) {
+	if (layoutkind == LY_USEEXIST) {
 		/*
 		 * If 'pm->oldlabel' is a default label created by the kernel it
 		 * will have exactly one valid partition besides raw_part
@@ -673,10 +685,10 @@ make_bsd_partitions(void)
 		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, "/");
@@ -694,23 +706,35 @@ make_bsd_partitions(void)
 		pm->bsdlabel[i] = pm->oldlabel[i];
 	 }
 
-	if (layoutkind != 4)
+	if (layoutkind == LY_SETNEW)
 		get_ptn_sizes(partstart, ptend - partstart, no_swap);
 
+	if (layoutkind == LY_NEWRAID) {
+		set_ptype(&(pm->bsdlabel[PART_E]), FS_RAID, 0);
+		pm->bsdlabel[PART_E].pi_size = pm->ptsize;
+	}
+
+	if (layoutkind == LY_NEWCGD) {
+		set_ptype(&(pm->bsdlabel[PART_E]), FS_CGD, 0);
+		pm->bsdlabel[PART_E].pi_size = pm->ptsize;
+	}
+
 	/*
 	 * 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(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
-		msg_display(MSG_abort);
-		return 0;
-	}
-	if (partman_go == 0 && 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, pm->bsddiskname, pm->bsddiskname, sizeof pm->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(pm->bsdlabel, maxpart);
@@ -746,9 +770,9 @@ check_partitions(void)
 	}
 #endif
 #ifndef HAVE_UFS2_BOOT
-	fstype = pm->bsdlabel[rootpart].pi_fstype;
+	fstype = pm->bsdlabel[pm->rootpart].pi_fstype;
 	if (fstype == FS_BSDFFS &&
-	    (pm->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 5593d02..0530c23 100644
--- a/distrib/utils/sysinst/configmenu.c
+++ b/distrib/utils/sysinst/configmenu.c
@@ -93,6 +93,7 @@ configinfo config_list[] = {
 	{MSG_run_ntpdate, CONFIGOPT_NTPDATE, "ntpdate", toggle_rcvar, NULL},
 	{MSG_enable_mdnsd, CONFIGOPT_MDNSD, "mdnsd", toggle_rcvar, NULL},
 	{"Enable XDM", CONFIGOPT_XDM, "xdm", toggle_rcvar, NULL},
+	{"Enable CGD", CONFIGOPT_XDM, "cgd", toggle_rcvar, NULL},
 	{NULL,		CONFIGOPT_LAST,	NULL, NULL, NULL}
 }; // TODO: XDM
 
diff --git a/distrib/utils/sysinst/defs.h b/distrib/utils/sysinst/defs.h
index f47b3d4..6cae884 100644
--- a/distrib/utils/sysinst/defs.h
+++ b/distrib/utils/sysinst/defs.h
@@ -51,7 +51,7 @@ deconst(const void *p)
 
 #include "msg_defs.h"
 #include "menu_defs.h"
-#include "mbr.h"
+#include "mbr.h" // TODO: sss
 
 #define min(a,b)	((a) < (b) ? (a) : (b))
 #define max(a,b)	((a) > (b) ? (a) : (b))
@@ -84,6 +84,12 @@ 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 */
+#define LY_SETNEW 1
+#define LY_NEWRAID 2
+#define LY_NEWCGD 3
+#define LY_USEEXIST 4
+
 /* Installation sets */
 enum {
     SET_NONE,
@@ -244,7 +250,7 @@ pid_t ttysig_forward;
 int layoutkind;
 int sizemult;
 const char *multname;
-int partman_go;   /* run partition manager */
+int partman_go; /* run extended partition manager */
 int fstab_prepared; /* Should we create new /etc/fstab or append old? */
 
 /* logging variables */
@@ -252,34 +258,35 @@ int fstab_prepared; /* Should we create new /etc/fstab or append old? */
 FILE *logfp;
 FILE *script;
 
-
-int rootpart;				/* partition we install into */
-const char *disktype;		/* ST506, SCSI, ... */
-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))
 daddr_t tmp_ramdisk_size;
+#define MAX_DISKS 15
 
-#define DISKNAME_SIZE 16
-char bsddiskname[DISKNAME_SIZE]; // TODO: xxx
-const char *doessf;
+unsigned int root_limit;    /* BIOS (etc) read limit */
 
-/* Information for extended partition manager */
+/* All information that is unique for each drive */
+enum SHRED_T { SHRED_NONE=0, SHRED_ZEROS, SHRED_RANDOM, SHRED_CRYPTO };
 typedef struct pm_devs_t {
-    /* Actual name of the disk. */
-    char diskdev[SSTRSIZE];
+    int changed; /* Flag indicating to partman that device need saving */
+    int found; /* Flag to delete unplugged and unconfigured devices */
+    char diskdev[SSTRSIZE]; /* Actual name of the disk. */
     char diskdev_descr[STRSIZE];
     char id_dk[SSTRSIZE];
     int bootable;
+#define DISKNAME_SIZE 16
     char bsddiskname[DISKNAME_SIZE];
     partinfo oldlabel[MAXPARTITIONS]; /* What we found on the disk */
     partinfo bsdlabel[MAXPARTITIONS]; /* What we want it to look like */
     mbr_info_t mbr;
     int no_mbr; /* set for raid (etc) */
     int use_gpt;
+    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;
@@ -287,18 +294,12 @@ typedef struct pm_devs_t {
     daddr_t ptstart, ptsize;
     /* If we have an MBR boot partition, start and size in sectors */
     int bootstart, bootsize;
+    struct ptn_info pi;
     struct pm_devs_t *next;
 } pm_devs_t;
-pm_devs_t *pm_devs; /* Pointer to head of list with all devices */
-pm_devs_t *pm_found; /* Pointer to selected in find_disks device
-                        (when extended partition manager isn't used) */
 pm_devs_t *pm; /* Pointer to currend device with which we work */
-
-#define MNTS_MAX 100
-struct {
-    const char *diskdev, *mnt_opts, *fsname;
-    char *pi_mount;
-} mnts[MNTS_MAX];
+pm_devs_t *pm_head; /* Pointer to head of list with all devices */
+pm_devs_t *pm_found; /* Pointer for next allocating device in find_disks() */
 
 /* Relative file name for storing a distribution. */
 char xfer_dir[STRSIZE];
@@ -412,15 +413,16 @@ 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);
+const char *fstype_name(int);
+void label_read(void);
+
+/* from partman.c */
 int	partman(void);
-int partman_adddisk(menudesc *, void *);
-int partman_addvnd(menudesc *, void *);
-int partman_deldev(menudesc *, void *);
-int partman_commit(menudesc *, void *);
-int partman_mountall(void);
-void partman_menufmt(menudesc *, int, void *);
-void partman_select(pm_devs_t *);
+int partman_mountmenu(void);
+int partman_shred(char *, int);
+int partman_unconfigure(void);
+int partman_cgd_edit_adddisk(int, pm_devs_t *);
 
 /* from disks_lfs.c */
 int	fs_is_lfs(void *);
@@ -508,6 +510,7 @@ 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)
diff --git a/distrib/utils/sysinst/disks.c b/distrib/utils/sysinst/disks.c
index be1c612..5400696 100644
--- a/distrib/utils/sysinst/disks.c
+++ b/distrib/utils/sysinst/disks.c
@@ -62,7 +62,6 @@
 #include "txtwalk.h"
 
 /* Disk descriptions */
-#define MAX_DISKS 15
 struct disk_desc {
 	char	dd_name[SSTRSIZE];
 	char	dd_descr[70];
@@ -86,7 +85,7 @@ static void fixsb(const char *, const char *, char);
 #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 +296,7 @@ get_descr(struct disk_desc *dd)
 	/* try SCSI */
 	if (get_descr_scsi(dd, fd))
 		goto done;
+	/* TODO: get description from raid, cgd, vnd... */
 
 done:
 	if (fd >= 0)
@@ -349,22 +349,15 @@ 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) + !partman_go];
+	menu_ent dsk_menu[nelem(disks) + 1]; // + 1 for extended partitioning entry
 	struct disk_desc *disk;
-	int i;
-	int numdisks;
-	int selected_disk = -1;
+	pm_devs_t *pm_i, *pm_swap;
+	int i, already_found;
+	int numdisks, selected_disk = -1;
 	int menu_no;
 
 	/* Find disks. */
@@ -376,77 +369,132 @@ 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;
-	} 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_dsk_select;
-		}
-		if (partman_go == 0) {
+	if (! partman_go) {
+		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;
+			}
+			
 			dsk_menu[i].opt_name = "Extended partitioning"; // TODO: localize
 			dsk_menu[i].opt_menu = OPT_NOMENU;
 			dsk_menu[i].opt_flags = OPT_EXIT;
-			dsk_menu[i].opt_action = set_dsk_select;
+			dsk_menu[i].opt_action = set_menu_select;
+
+			menu_no = new_menu(MSG_Available_disks,
+				dsk_menu, numdisks + 1, -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);
 		}
-
-		menu_no = new_menu(MSG_Available_disks,
-			dsk_menu, numdisks + !partman_go, -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 (selected_disk == -1)
-	    return -1;
-	if (selected_disk == numdisks) {
-		partman_go = 1;
-	    return -2;
+		if (selected_disk == numdisks) {
+			partman_go = 1;
+	    	return -2;
+		}
+		if (selected_disk < 0 || selected_disk >= numdisks)
+	    	return -1;
 	}
 
-	disk = disks + selected_disk;
-	pm = pm_found;
-	pm->bootable = 0;
-	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); // TODO: sss
-
-	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;
-	pm->no_mbr = disk->dd_no_mbr;
-	if (pm->dlsize == 0)
-		pm->dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec;
-	if (pm->dlsize > UINT32_MAX) {
-		msg_display(MSG_toobigdisklabel);
-		process_menu(MENU_ok, NULL);
-		return -1;
+	/* Mark all devicec as not found */
+	for (pm_i = pm_head->next; partman_go && pm_i != NULL;
+		 pm_i = pm_i->next)
+			pm_i->found = 0;
+	/* 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;
+			for (pm_i = pm_head; pm_i->next != NULL; pm_i = pm_i->next)
+				if (!already_found && 
+						strcmp(pm_i->next->diskdev, disk->dd_name) == 0) {
+					pm_i->next->found = 1;
+					already_found = 1;
+				}
+			if (already_found)
+				/* We already added this device, skipping */
+				continue;
+		}
+		pm = pm_found;
+		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->sectorsize = disk->dd_secsize;
+		pm->dlcyl = disk->dd_cyl;
+		pm->dlhead = disk->dd_head;
+		pm->dlsec = disk->dd_sec;
+		pm->dlsize = disk->dd_totsec;
+		pm->no_mbr = disk->dd_no_mbr;
+		if (pm->dlsize == 0)
+			pm->dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec;
+		if (pm->dlsize > UINT32_MAX) {
+			if (logfp)
+				fprintf(logfp, "Cannot process disk %s: too big size (%d)\n",
+					pm->diskdev, (int)pm->dlsize); // TODO: localize
+			if (partman_go)
+				continue;
+			msg_display(MSG_toobigdisklabel);
+			process_menu(MENU_ok, NULL);
+			return -1;
+		}
+		pm->dlcylsize = pm->dlhead * pm->dlsec;
+
+		label_read();
+		if (partman_go) {
+			pm_i->next = pm_found;
+			pm_found = malloc(sizeof (pm_devs_t));
+			memset(pm_found, 0, sizeof *pm_found);
+			pm_found->next = NULL;
+		} else
+			/* We is not in partman and do not want to process all devices, exit */
+			break;
 	}
-	pm->dlcylsize = pm->dlhead * pm->dlsec;
+	for (pm_i = pm_head; partman_go && pm_i->next != NULL;
+			pm_i = pm_i->next)
+		if (! pm_i->next->found) {
+			/* If device not found then delete it */
+			if (pm_i->next->next == NULL) {
+				free(pm_i->next);
+				pm_i->next = NULL;
+				break;
+			} else {
+				pm_swap = pm_i->next->next;
+				free(pm_i->next);
+				pm_i->next = pm_swap;
+			}
+		}
+	return numdisks;
+}
 
+void
+label_read(void)
+{
 	/* Get existing/default label */
 	memset(&pm->oldlabel, 0, sizeof pm->oldlabel);
 	incorelabel(pm->diskdev, pm->oldlabel);
-
 	/* Set 'target' label to current label in case we don't change it */
 	memcpy(&pm->bsdlabel, &pm->oldlabel, sizeof pm->bsdlabel);
-
-	return numdisks;
+	savenewlabel(pm->oldlabel, getmaxpartitions());
 }
 
 void
@@ -797,10 +845,8 @@ make_fstab(void)
 	scripting_fprintf(NULL, "EOF\n");
 
 	fstab_prepared = 1;
-#ifndef DEBUG
 	fclose(f);
 	fflush(NULL);
-#endif
 	return 0;
 }
 
@@ -938,7 +984,7 @@ mount_root(void)
 {
 	int	error;
 
-	error = fsck_preen(pm->diskdev, rootpart, "ffs");
+	error = fsck_preen(pm->diskdev, pm->rootpart, "ffs");
 	if (error != 0)
 		return error;
 
@@ -950,7 +996,7 @@ mount_root(void)
 	 * XXX consider -o remount in case target root is
 	 * current root, still readonly from single-user?
 	 */
-	return target_mount("", pm->diskdev, rootpart, "");
+	return target_mount("", pm->diskdev, pm->rootpart, "");
 }
 
 /* Get information on the file systems mounted from the root filesystem.
@@ -1092,11 +1138,11 @@ bootxx_name(void)
 	char *bootxx;
 
 	/* check we have boot code for the root partition type */
-	fstype = pm->bsdlabel[rootpart].pi_fstype;
+	fstype = pm->bsdlabel[pm->rootpart].pi_fstype;
 	switch (fstype) {
 #if defined(BOOTXX_FFSV1) || defined(BOOTXX_FFSV2)
 	case FS_BSDFFS:
-		if (pm->bsdlabel[rootpart].pi_flags & PIF_FFSv2) {
+		if (pm->bsdlabel[pm->rootpart].pi_flags & PIF_FFSv2) {
 #ifdef BOOTXX_FFSV2
 			bootxxname = BOOTXX_FFSV2;
 #else
@@ -1129,288 +1175,30 @@ bootxx_name(void)
 }
 #endif
 
-
-
-
-void
-partman_select(pm_devs_t *pm_devs_in)
-{
-	pm = pm_devs_in;
-	if (logfp)
-		(void)fprintf(logfp,"Partman device: %s\n", pm->diskdev);
-	return;
-
-}
-
-// TODO: mount order
-static int
-partman_mountall_sort(const void *a, const void *b)
-{
-	return strcmp(mnts[*(const int *)a].pi_mount,
-		      mnts[*(const int *)b].pi_mount);
-}
-
-int
-partman_mountall(void)
-{
-	pm_devs_t *pm_devs_i;
-	int num_devs = 0;
-	int i, error;
-
-	int mnts_order[MNTS_MAX]; // TODO: rewrite
-	for (pm_devs_i = pm_devs->next, num_devs = 0; pm_devs_i != NULL;
-			pm_devs_i = pm_devs_i->next) {
-		fprintf(logfp,"::%s\n",pm_devs_i->diskdev); fflush(logfp);
-		for (i = 0; i < MAXPARTITIONS; i++) {
-			if (pm_devs_i->bsdlabel[i].pi_flags & PIF_MOUNT &&
-					pm_devs_i->bsdlabel[i].mnt_opts != NULL) {
-				mnts[num_devs].diskdev = pm_devs_i->diskdev;
-				mnts[num_devs].mnt_opts = pm_devs_i->bsdlabel[i].mnt_opts;
-				mnts[num_devs].fsname = pm_devs_i->bsdlabel[i].fsname;
-				mnts[num_devs].pi_mount = pm_devs_i->bsdlabel[i].pi_mount;
-				num_devs++;
-				fprintf(logfp,":::%s\n",mnts[num_devs].pi_mount); fflush(logfp);
-			}
-		}
-	}
-	for (i = 0; i < num_devs; i++)
-		mnts_order[i] = i;
-	qsort(mnts_order, num_devs, sizeof mnts_order[0], partman_mountall_sort);
-
-	for (i = 0; i < num_devs; i++) {
-		make_target_dir(mnts[i].pi_mount);
-		error = target_mount(mnts[i].mnt_opts, pm->diskdev, i, mnts[i].pi_mount);
-		if (error) {
-			msg_display(MSG_mountfail, pm->diskdev, 'a' + i, mnts[i].pi_mount);
-			process_menu(MENU_ok, NULL);
-			return error;
-		}
-	}
-	return 0;
-}
-
-int
-partman_adddisk(menudesc *m, void *arg)
-{
-	*(int *)arg = m->cursel + 1;
-	pm_devs_t *pm_devs_tmp;
-
-	if (find_disks(msg_string(MSG_install)) < 0)
-		return -1;
-
-	clear();
-	refresh();
-
-	if (check_swap(pm->diskdev, 0) > 0) {
-		msg_display(MSG_swapactive);
-		process_menu(MENU_ok, NULL);
-		if (check_swap(pm->diskdev, 1) < 0) {
-			msg_display(MSG_swapdelfailed);
-			process_menu(MENU_ok, NULL);
-			return -1;
-		}
-	}
-
-	for (pm_devs_tmp = pm_devs; pm_devs_tmp->next != NULL;
-			pm_devs_tmp = pm_devs_tmp->next)
-		if (strcmp(pm_devs_tmp->next->diskdev, pm->diskdev) == 0)
-			return 0;
-	pm_devs_tmp->next = pm_found;
-
-	pm_found = malloc(sizeof (pm_devs_t));
-	pm_found->next = NULL;
-
-	return 0;
-}
-
-int
-partman_addvnd(menudesc *m, void *arg)
-{
-	*(int *)arg = m->cursel + 1;
-	return 0;
-}
-
-int
-partman_deldev(menudesc *m, void *arg)
-{
-	pm_devs_t *pm_devs_tmp, *pm_devs_swap;
-	*(int *)arg = m->cursel + 1;
-
-	for (pm_devs_tmp = pm_devs; pm_devs_tmp->next != NULL;
-			pm_devs_tmp = pm_devs_tmp->next)
-		if (pm_devs_tmp->next == pm) {
-			if (pm_devs_tmp->next->next == NULL) {
-				free(pm_devs_tmp->next);
-				pm_devs_tmp->next = NULL;
-			} else {
-				pm_devs_swap = pm_devs_tmp->next->next;
-				free(pm_devs_tmp->next);
-				pm_devs_tmp->next = pm_devs_swap;
-			}
-			return 0;
-		}
-	return -1;
-}
-
-int
-partman_commit(menudesc *m, void *arg)
-{
-	pm_devs_t *pm_devs_i;
-	*(int *)arg = m->cursel + 1;
-
-	for (pm_devs_i = pm_devs->next; pm_devs_i != NULL;
-			pm_devs_i = pm_devs_i->next) {
-		partman_select(pm_devs_i);
-		if (
-				md_pre_disklabel() != 0  || /* Write partition table */
-				write_disklabel() != 0   || /* Write slices table (disklabel) */
-				md_post_disklabel() != 0 || /* Enable swap and check badblock */
-				make_filesystems()          /* Create filesystems by newfs */
-			) { /* If something fails... */
-			return -1;
-		}
-		/* Write bootsector if needed */
-		if (pm_devs_i->bootable && md_post_newfs() != 0) {
-			return -1;
-		}
-	}
-    return 0;
-}
-
-static int
-partman_submenu(menudesc *m, void *arg)
-{
-	pm_devs_t *pm_devs_i;
-	int retvalue;
-	int ok = 0;
-	int i;
-	*(int *)arg = m->cursel + 1;
-
-	/* write selected disk to diskdev variable */
-	for (pm_devs_i = pm_devs->next, i = 0; !ok && pm_devs_i != NULL;
-			pm_devs_i = pm_devs_i->next, i++)
-		if (i == m->cursel) {
-			partman_select(pm_devs_i);
-			ok = 1;
-			break;
-		}
-	if (!ok)
-		return -1;
-
-	process_menu(MENU_pmentry, &retvalue);
-	return 0;
-}
-
-void
-partman_menufmt(menudesc *m, int ptn, void *arg)
-{
-	pm_devs_t *pm_devs_i;
-	int i;
-	unsigned int maxpart;
-	char *dev_mounts = malloc(STRSIZE * sizeof(char));
-	dev_mounts[0] = '\0';
-
-	for (pm_devs_i = pm_devs->next, i = 0;
-			i != ptn && pm_devs_i != NULL;
-			pm_devs_i = pm_devs_i->next, i++);
-	if (i != ptn || pm_devs_i == NULL) 
-		return;
-
-	maxpart = ((unsigned int)getmaxpartitions() > nelem(pm_devs_i->bsdlabel))?
-				nelem(pm_devs_i->bsdlabel) : (unsigned int)getmaxpartitions();
-	for (i = 0; (unsigned int)i < maxpart; i++) {
-		if (pm_devs_i->bsdlabel[i].pi_mount != 0 &&
-				pm_devs_i->bsdlabel[i].pi_fstype != FS_UNUSED) {
-			strcat(dev_mounts, pm_devs_i->bsdlabel[i].pi_mount);
-			strcat(dev_mounts, " ");
-		}
-	}
-
-	wprintw(m->mw,"%-25s %-20s %4s", pm_devs_i->diskdev_descr, dev_mounts,
-			(pm_devs_i->bootable)?"BOOT":"" );
-	return;
-}
-
-// TODO: switch to langfiles
-// TODO: resolve case with 2 same bsddisknames
-int
-partman(void)
+const char *
+fstype_name(int fstype)
 {
-	menu_ent part_menu[MAX_DISKS];
-	int menu_pm;
-	int i, ii;
-	int retvalue = 0;
-	pm_devs_t *pm_devs_i;
-
-	do {
-		clear();
-		refresh();
-		for (pm_devs_i = pm_devs->next, i = 0; pm_devs_i != NULL;
-				pm_devs_i = pm_devs_i->next, i++) {
-			part_menu[i].opt_name = NULL;
-			part_menu[i].opt_action = partman_submenu;
-		}
-
-		part_menu[i] = (struct menu_ent) {
-			.opt_name = "Add disk",
-			.opt_action = partman_adddisk,
-		};
-		part_menu[++i] = (struct menu_ent) {
-			.opt_name = "Create CGD",
-			.opt_action = partman_addvnd,
-		};
-		part_menu[++i] = (struct menu_ent) {
-			.opt_name = "Create VND disk",
-			.opt_action = partman_addvnd,
-		};
-		part_menu[++i] = (struct menu_ent) {
-			.opt_name = "Create LVM VG",
-			.opt_action = partman_addvnd,
-		};
-		part_menu[++i] = (struct menu_ent) {
-			.opt_name = "Create RAIFframe",
-			.opt_action = partman_addvnd,
-		};
-		part_menu[++i] = (struct menu_ent) {
-			.opt_name = "Commit changes",
-			.opt_action = partman_commit,
-		};
-
-		for (ii = 0; ii <= i; ii++) {
-			part_menu[ii].opt_menu = OPT_NOMENU;
-			part_menu[ii].opt_flags = OPT_EXIT;
-		}
-
-		menu_pm = new_menu("Disk editor. All disks, partitions, LVM, RAID displayed there.\nAt first add drive, then prepare partitions and go.",
-			part_menu, i+1,	1, 1, 0, 0, MC_ALWAYS_SCROLL | MC_NOBOX | MC_NOCLEAR,
-			NULL, partman_menufmt, NULL, NULL, NULL);
-		retvalue = 0;
-		if (menu_pm == -1)
-			retvalue = -1;
-		else {
-			process_menu(menu_pm, &retvalue);
-			free_menu(menu_pm);
-		}
-
-		if (logfp)
-			(void)fprintf(logfp, "partman retvalue is %d\n", retvalue);
-	} while (retvalue > 0);
-	
-	// TODO: check_partitions()
-	/* Check that fstab on target device is readable - if so then we can go */
-	if (retvalue == 0) {
-		if (partman_mountall() != 0 ||
-			make_fstab() != 0)
-			retvalue = -1;
-		else {
-			FILE *file_tmp = fopen(concat_paths(targetroot_mnt, "/etc/fstab"), "r");
-			if (file_tmp == NULL)
-				retvalue = -1;
-			else
-				fclose(file_tmp);
-		}
+	switch (fstype) {
+		case FS_BSDFFS:
+			return "FFS";
+		case FS_BSDLFS:
+			return "LFS";
+		case FS_SWAP:
+			return "SWAP";
+		case FS_EX2FS:
+			return "EXT2";
+		case FS_MSDOS:
+			return "FAT";
+		case FS_APPLEUFS:
+			return "APPLEUFS";
+		case FS_SYSVBFS:
+			return "SYSVB";
+		case FS_RAID:
+			return "RAID";
+		case FS_CGD:
+			return "CGD";
+		case FS_UNUSED:
+			return "none";
 	}
-
-	/* retvalue <0 - error, retvalue ==0 - user quits, retvalue >0 - all ok */
-	return (retvalue >= 0)?0:-1;
-}
+	return "???";
+}
\ No newline at end of file
diff --git a/distrib/utils/sysinst/label.c b/distrib/utils/sysinst/label.c
index ebdb567..a91e866 100644
--- a/distrib/utils/sysinst/label.c
+++ b/distrib/utils/sysinst/label.c
@@ -161,7 +161,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;
 }
diff --git a/distrib/utils/sysinst/main.c b/distrib/utils/sysinst/main.c
index 69723e8..c7592a6 100644
--- a/distrib/utils/sysinst/main.c
+++ b/distrib/utils/sysinst/main.c
@@ -76,6 +76,8 @@ struct {
 
 /* 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;
@@ -105,7 +107,7 @@ static const struct f_arg fflagopts[] = {
 	{"local dir", "release", localfs_dir, sizeof localfs_dir},
 	{"targetroot mount", "/targetroot", targetroot_mnt, sizeof targetroot_mnt},
 	{"dist postfix", ".tgz", dist_postfix, sizeof dist_postfix},
-	{"diskname", "mydisk", bsddiskname, sizeof bsddiskname}, /* TODO: xxx */
+	{"diskname", "mydisk", bsddiskname, sizeof bsddiskname},
 	{"pkg host", SYSINST_PKG_HOST, pkg.host, sizeof pkg.host},
 	{"pkg dir", SYSINST_PKG_DIR, pkg.dir, sizeof pkg.dir},
 	{"pkg prefix", "/" MACH "/" REL "/All", pkg_dir, sizeof pkg_dir},
@@ -128,20 +130,20 @@ init(void)
 	const struct f_arg *arg;
 	
 	sizemult = 1;
-	disktype = "unknown";
 	tmp_ramdisk_size = 0;
-	doessf = "";
 	clean_xfer_dir = 0;
 	mnt2_mounted = 0;
 	fd_type = "msdos";
+	layoutkind = LY_SETNEW;
 
-	pm_devs = malloc (sizeof (pm_devs_t));
-	pm_devs->next = NULL;
+	pm_head = malloc (sizeof (pm_devs_t));
+	memset(pm_head, 0, sizeof *pm_head);
 	pm_found = malloc (sizeof (pm_devs_t));
-	pm_found->next = NULL;
+	memset(pm_found, 0, sizeof *pm_found);
 
 	for (arg = fflagopts; arg->name != NULL; arg++)
 		strlcpy(arg->var, arg->dflt, arg->size);
+	strlcpy(pm_found->bsddiskname, bsddiskname, sizeof pm_found->bsddiskname);
 	pkg.xfer_type = pkgsrc.xfer_type = "http";
 	
 	clr_arg.bg=COLOR_BLUE;
@@ -360,7 +362,7 @@ toplevel(void)
 	 * XXX must be idempotent, since we get run each time the main
 	 *     menu is displayed.
 	 */
-	chdir(getenv("HOME")? getenv("HOME") : "/");
+	chdir(getenv("HOME"));
 	unwind_mounts();
 
 	/* Display banner message in (english, francais, deutsch..) */
@@ -496,6 +498,7 @@ process_f_flag(char *f_name)
 			break;
 		}
 	}
+	strlcpy(pm_found->bsddiskname, bsddiskname, sizeof pm_found->bsddiskname);
 
 	fclose(fp);
 }
diff --git a/distrib/utils/sysinst/mbr.c b/distrib/utils/sysinst/mbr.c
index c916074..d93ef25 100644
--- a/distrib/utils/sysinst/mbr.c
+++ b/distrib/utils/sysinst/mbr.c
@@ -1272,8 +1272,12 @@ edit_mbr(mbr_info_t *mbri)
 
 	part = &mbrs->mbr_parts[0];
 	get_ptn_alignment(part);  /* update ptn_alignment */
-	msg_display(MSG_fullpart, pm->diskdev);
-	process_menu(MENU_fullpart, &usefull);
+	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) {
diff --git a/distrib/utils/sysinst/menus.mi b/distrib/utils/sysinst/menus.mi
index 08c8d1f..6fd5a1e 100644
--- a/distrib/utils/sysinst/menus.mi
+++ b/distrib/utils/sysinst/menus.mi
@@ -177,7 +177,7 @@ menu utility, title MSG_NetBSD_VERSION_Utilities, exit,
 			network_up = 0;
 			config_network();
 		};
-	option MSG_Partition_a_disk, action { partman(); };
+	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,
@@ -206,8 +206,8 @@ 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 {
@@ -241,7 +241,7 @@ 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, exit;
+menu distset, title MSG_Select_your_distribution, exit, no default exit;
 	display action { msg_display (MSG_distset); };
 	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); };
@@ -506,11 +506,72 @@ menu pkgsrc, y=-4, x=0, w=70, no box, no clear,
 		};
 	option MSG_quit_install, exit, action { yesno = SET_SKIP; };
 
-menu pmentry, x=50, y=5, sub menu, exit, default exit;
-	option "Prepare",			exit, action { md_get_info(); };
-	option "Prepare GPT",		exit, action { md_get_info(); };
-	option "Commit prepare",	exit, action { md_pre_disklabel(); };
-	option "Disk label",		exit, action { md_make_bsd_partitions(); };
-	option "Commit label",		exit, action { write_disklabel(); md_post_disklabel(); };
-	option "Toggle bootable",   exit, action { pm->bootable = !pm->bootable; };
-	option "Remove",			exit, action { partman_deldev(m, arg); };
+menu pmentry, x=50, y=5, exit, default exit; /* TODO: localize */
+	option "Prepare MBR",		exit, action { pm->changed = 1; md_get_info(); };
+	option "Prepare GPT [WIP]",	exit, action { pm->changed = 1; };
+	option "Edit BSD partitions", exit, action { *(int *)arg = 1; pm->changed = 1;
+								layoutkind = LY_SETNEW;
+								md_make_bsd_partitions();
+								if (pm->bsdlabel[pm->rootpart].pi_flags & PIF_MOUNT)
+									pm->bootable = 1;
+								else
+									pm->bootable = 0; };
+	option "Set disk name",		exit, action { msg_prompt_win(MSG_packname, -1,
+								18,	0, 0, pm->bsddiskname, pm->bsddiskname,
+								sizeof pm->bsddiskname); };
+	option "RAID there",		exit, action { *(int *)arg = 1; pm->changed = 1;
+												layoutkind = LY_NEWRAID;
+												md_make_bsd_partitions(); };
+	option "Encrypt",			exit, action { *(int *)arg = 1; pm->changed = 1;
+												layoutkind = LY_NEWCGD;
+												md_make_bsd_partitions();
+												partman_cgd_edit_adddisk(0, pm); };
+	option "Bootable flag",		exit, action { pm->changed = 1;
+												pm->bootable = !pm->bootable; };
+	option "Safe erase",		next menu shred_modes;
+	option "Undo changes",		exit, action { label_read(); pm->changed = 0; };
+	option "Mount...",			exit, action { partman_mountmenu(); };
+	option "Umount/Unconfigure", exit, action { *(int *)arg = 1;
+												partman_unconfigure(); };
+
+menu shred_modes, x=50, y=5, exit, default exit;
+	option "Fill by zeros",			exit, action { partman_shred(pm->diskdev,
+													SHRED_ZEROS); };
+	option "Fill by random data",	exit, action { partman_shred(pm->diskdev,
+													SHRED_RANDOM); };
+	option "Fill by crypto data",	exit, action { partman_shred(pm->diskdev,
+													SHRED_CRYPTO); };
+
+menu raidlevel;
+	option "0 - No parity, only simple striping.", exit,
+		action { *(int *)arg = 0; };
+	option "1 - Mirroring.  The parity is the mirror.", exit,
+		action { *(int *)arg = 1; };
+	option "4 - Striping with parity stored on the last component.", exit,
+		action { *(int *)arg = 4; };
+	option "5 - Striping with parity at the all components.", 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/net.c b/distrib/utils/sysinst/net.c
index 100331a..90d6b7a 100644
--- a/distrib/utils/sysinst/net.c
+++ b/distrib/utils/sysinst/net.c
@@ -510,13 +510,6 @@ handle_license(const char *dev)
 	return 1;
 }
 
-static int
-set_net_select(menudesc *m, void *arg)
-{
-	*(int *)arg = m->cursel;
-	return 1;
-}
-
 /*
  * Get the information to configure the network, configure it and
  * make sure both the gateway and the name server are up.
@@ -564,7 +557,7 @@ config_network(void)
 		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_net_select;
+		net_menu[i].opt_action = set_menu_select;
 	}
 again:
 	selected_net = -1;
diff --git a/distrib/utils/sysinst/partman.c b/distrib/utils/sysinst/partman.c
new file mode 100644
index 0000000..c1453cd
--- /dev/null
+++ b/distrib/utils/sysinst/partman.c
@@ -0,0 +1,1366 @@
+/*	$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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <util.h>
+
+#include "defs.h"
+#include "md.h"
+#include "msg_defs.h"
+#include "menu_defs.h"
+
+
+typedef struct {
+	int retvalue;
+	int dev_num;
+	pm_devs_t *dev_pm;
+	char fullname[SSTRSIZE];
+	enum {PM_DISK_T, PM_PART_T, PM_RAID_T, PM_VND_T, PM_CGD_T} type;
+} part_entry_t;
+
+#define MNTS_MAX 96
+struct {
+    const char *diskdev, *mnt_opts, *fsname;
+    char *pi_mount;
+    int pm_part;
+} mnts[MNTS_MAX];
+
+#define MAX_RAIDS 16 // TODO: replace by true way
+#define MAX_IN_RAID 48
+struct raids_t {
+	int enabled;
+	pm_devs_t *pm[MAX_IN_RAID];
+	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;
+} raids[MAX_RAIDS];
+
+#define MAX_VNDS 4
+struct vnds_t {
+	int enabled;
+	char filepath[STRSIZE];
+	int size;
+	int readonly;
+	int is_exist;
+	int manual_geom;
+	int secsize, nsectors, ntracks, ncylinders;
+} vnds[MAX_VNDS];
+
+#define MAX_CGDS 4
+struct cgds_t {
+	int enabled;
+	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[MAX_CGDS];
+
+int manage_newdev;
+int manage_curdev;
+int manage_raid_spare_cur;
+
+enum { /* Raid 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
+};
+
+static int partman_manage_edit(int, void (*)(menudesc *, int, void *),
+	int (*)(menudesc *, void *), int (*)(int), void (*)(void *),
+	void *, int, int, int , void *);
+part_entry_t partman_manage_getdev(int);
+static int partman_raid_disk_add(menudesc *, void *);
+static int partman_raid_disk_del(menudesc *, void *);
+static int partman_cgd_disk_set(part_entry_t *);
+static void partman_select(pm_devs_t *);
+static int partman_mountall_sort(const void *, const void *);
+static int partman_mountall(void);
+static int partman_upddevlist(menudesc *, void *);
+static int partman_commit(menudesc *, void *);
+static int partman_submenu(menudesc *, void *);
+static void partman_menufmt(menudesc *, int, void *);
+
+
+static int
+partman_manage_edit(int menu_entries_count, void (*menu_fmt)(menudesc *, int, void *),
+	int (*action)(menudesc *, void *), int (*check_fun)(int),
+	void (*entry_init)(void *),	void* entry_init_arg,
+	int dev_num, int max, int entry_size, void *entry_enabled)
+{
+	int i, retvalue = 0, ok = 0;
+
+	if (dev_num < 0) {
+		/* We should create new device */
+		for (i = 0; i < max && !ok; i++)
+			if (*(int*)((char*)entry_enabled + entry_size * i) != 1) {
+				manage_curdev = i;
+				entry_init(entry_init_arg);
+				*(int*)((char*)entry_enabled + entry_size * i) = 1;
+				ok = 1;
+			}
+		if (!ok) {
+			msg_prompt_win("Limit for the devices count was reached!", -1, 18, 0, 0, NULL, NULL, 0);
+			return -1;
+		}
+	} else {
+		/* ... or edit existent */
+		if (*(int*)((char*)entry_enabled + entry_size * dev_num) == 0) {
+			if (logfp)
+				fprintf(logfp, "partman_manage_edit: invalid drive\n");
+				msg_prompt_win("Invalid device!", -1, 18, 0, 0, NULL, NULL, 0);
+			return -2;
+		}
+		manage_curdev = dev_num;
+	}
+
+	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) {"REMOVE", 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, &retvalue);
+	free_menu(menu_no);
+	if (check_fun != NULL)
+		check_fun(manage_curdev);
+
+	return retvalue;
+}
+
+part_entry_t
+partman_manage_getdev(int fstype)
+{
+	pm_devs_t *pm_i;
+	int dev_num = -1, num_devs;
+	int i;
+	int menu_no;
+	menu_ent menu_entries[MAX_DISKS*MAXPARTITIONS];
+	part_entry_t disk_entries[MAX_DISKS*MAXPARTITIONS];
+
+	for (pm_i = pm_head->next, num_devs = 0; pm_i != NULL; pm_i = pm_i->next)
+		for (i = 0; i < MAXPARTITIONS; i++) {
+			if (pm_i->bsdlabel[i].pi_fstype == fstype) {
+				disk_entries[num_devs].dev_pm = pm_i;
+				disk_entries[num_devs].dev_num = 'a' + i;
+				snprintf(disk_entries[num_devs].fullname, SSTRSIZE, "%s%c",
+						pm_i->diskdev, 'a' + 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("Available 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 (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];
+}
+
+/*** RAIDs ***/
+
+static void
+partman_raid_menufmt(menudesc *m, int opt, void *arg)
+{
+	int i, num, ok = 0;
+	
+	num = ((part_entry_t *)arg)[opt].dev_num;
+
+	if (raids[num].enabled != 0) {
+		wprintw(m->mw, "   RAID%d - ", raids[num].RAID_level);
+		for (i = 0; i < MAX_IN_RAID; i++)
+			if (raids[num].pm[i] != NULL) {
+				wprintw(m->mw, "%s ", raids[num].pm_name[i]);
+				ok = 1;
+			}
+		if (!ok)
+			wprintw(m->mw, "no components");
+	}
+	return;
+}
+
+static void
+partman_raid_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	int i;
+	char buf[STRSIZE];
+	buf[0] = '\0';
+
+	switch (opt){
+		case PMR_MENU_DEVS:
+			for (i = 0; i < MAX_IN_RAID; i++)
+				if (raids[manage_curdev].pm[i] != NULL && raids[manage_curdev].pm_is_spare[i] == 0)
+					snprintf(buf, STRSIZE, "%s %s", buf, raids[manage_curdev].pm_name[i]);
+			wprintw(m->mw, "Disks: %33s", buf);
+			break;
+		case PMR_MENU_DEVSSPARE:
+			for (i = 0; i < MAX_IN_RAID; i++)
+				if (raids[manage_curdev].pm[i] != NULL && raids[manage_curdev].pm_is_spare[i] != 0)
+					snprintf(buf, STRSIZE, "%s %s", buf, raids[manage_curdev].pm_name[i]);
+			wprintw(m->mw, "Spares: %32s", buf);
+			break;
+		case PMR_MENU_RAIDLEVEL:
+			wprintw(m->mw, "RAID level:       %22d", raids[manage_curdev].RAID_level);
+			break;
+		case PMR_MENU_NUMROW:
+			wprintw(m->mw, "numRow:           %22d", raids[manage_curdev].numRow);
+			break;
+		case PMR_MENU_NUMCOL:
+			wprintw(m->mw, "numCol:           %22d", raids[manage_curdev].numCol);
+			break;
+		case PMR_MENU_NUMSPARE:
+			wprintw(m->mw, "numSpare:         %22d", raids[manage_curdev].numSpare);
+			break;
+		case PMR_MENU_SECTPERSU:
+			wprintw(m->mw, "sectPerSU:        %22d", raids[manage_curdev].sectPerSU);
+			break;
+		case PMR_MENU_SUSPERPARITYUNIT:
+			wprintw(m->mw, "SUsPerParityUnit: %22d", raids[manage_curdev].SUsPerParityUnit);
+			break;
+		case PMR_MENU_SUSPERRECONUNIT:
+			wprintw(m->mw, "SUsPerReconUnit:  %22d", raids[manage_curdev].SUsPerReconUnit);
+			break;
+	}
+	return;
+}
+
+static int
+partman_raid_set_value(menudesc *m, void *arg)
+{
+	char buf[SSTRSIZE];
+	const char *msg_to_show = NULL;
+	int retvalue = -1;
+	int *out_var = NULL;
+	static menu_ent menuent_disk_adddel[] = {
+	    {"Add", OPT_NOMENU, OPT_EXIT, partman_raid_disk_add}, 
+	    {"Remove", OPT_NOMENU, OPT_EXIT, partman_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:
+			manage_raid_spare_cur = 0;
+			process_menu(menu_disk_adddel, NULL);
+			return 0;
+		case PMR_MENU_DEVSSPARE:
+			manage_raid_spare_cur = 1;
+			process_menu(menu_disk_adddel, NULL);
+			return 0;
+		case PMR_MENU_RAIDLEVEL:
+			process_menu(MENU_raidlevel, &retvalue);
+			if (retvalue > 0)
+				raids[manage_curdev].RAID_level = retvalue;
+			return 0;
+		case PMR_MENU_NUMROW:
+			msg_prompt_win("Multi-dimensional arrays are NOT supported!",
+							-1, 18, 0, 0, NULL, NULL, 0);
+			return 0;
+			msg_to_show = "numRow?";
+			out_var = &(raids[manage_curdev].numRow);
+			break;
+		case PMR_MENU_NUMCOL:
+			msg_to_show = "numCol?";
+			out_var = &(raids[manage_curdev].numCol);
+			break;
+		case PMR_MENU_NUMSPARE:
+			msg_to_show = "numSpare?";
+			out_var = &(raids[manage_curdev].numSpare);
+			break;
+		case PMR_MENU_SECTPERSU:
+			msg_to_show = "sectPerSU?";
+			out_var = &(raids[manage_curdev].sectPerSU);
+			break;
+		case PMR_MENU_SUSPERPARITYUNIT:
+			msg_to_show = "SUsPerParityUnit?";
+			out_var = &(raids[manage_curdev].SUsPerParityUnit);
+			break;
+		case PMR_MENU_SUSPERRECONUNIT:
+			msg_to_show = "SUsPerReconUnit?";
+			out_var = &(raids[manage_curdev].SUsPerReconUnit);
+			break;
+		case PMR_MENU_REMOVE:
+			raids[manage_curdev].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
+partman_raid_new_init(void* none)
+{
+	memset(&(raids[manage_curdev]), 0, sizeof raids[manage_curdev]);
+	raids[manage_curdev] = (struct raids_t) {
+		.enabled = 1,
+		.sectPerSU = 32,
+		.SUsPerParityUnit = 1,
+		.SUsPerReconUnit = 1,
+	};
+	return;
+}
+
+static int
+partman_raid_check(int dev_num)
+{
+	int ok = 0, i;
+	for (i = 0; i < MAX_IN_RAID; i++)
+		if (raids[dev_num].pm[i] != NULL && 
+				raids[dev_num].pm_is_spare[i] != 1) {
+			ok = 1;
+			break;
+		}
+	if (! ok)
+		raids[manage_curdev].enabled = 0;
+	return raids[manage_curdev].enabled;
+}
+
+static int
+partman_raid_disk_add(menudesc *m, void *arg)
+{
+	int i;
+	part_entry_t disk_entries = partman_manage_getdev(FS_RAID);
+	if (disk_entries.retvalue < 0)
+		return disk_entries.retvalue;
+
+	for (i = 0; i < MAX_IN_RAID; i++)
+		if (raids[manage_curdev].pm[i] == NULL) {
+			raids[manage_curdev].pm[i] = disk_entries.dev_pm;
+			raids[manage_curdev].pm_part[i] = disk_entries.dev_num;
+			raids[manage_curdev].pm_is_spare[i] = manage_raid_spare_cur;
+			strncpy(raids[manage_curdev].pm_name[i], disk_entries.fullname, SSTRSIZE);
+			if (manage_raid_spare_cur)
+				raids[manage_curdev].numSpare++;
+			else
+				raids[manage_curdev].numCol++;
+			raids[manage_curdev].numRow = 1;
+			break;
+		}
+	return 0;
+}
+
+static int
+partman_raid_disk_del(menudesc *m, void *arg)
+{
+	int retvalue = -1, num_devs = 0;
+	int i, pm_cur;
+	int menu_no;
+	menu_ent menu_entries[MAX_IN_RAID];
+	part_entry_t submenu_args[MAX_IN_RAID];
+
+	for (i = 0; i < MAX_IN_RAID; i++) {
+		if (raids[manage_curdev].pm[i] == NULL ||
+			raids[manage_curdev].pm_is_spare[i] != manage_raid_spare_cur)
+			continue;
+		menu_entries[num_devs] = (struct menu_ent) {
+			.opt_name = raids[manage_curdev].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("Disks in RAID:",
+		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 (raids[manage_curdev].pm_is_spare[pm_cur])
+		raids[manage_curdev].numSpare--;
+	else
+		raids[manage_curdev].numCol--;
+	raids[manage_curdev].numRow = (raids[manage_curdev].numCol)?1:0;
+	raids[manage_curdev].pm[pm_cur] = NULL;
+
+	return 0;
+}
+
+static int
+partman_raid_edit(menudesc *m, void *arg)
+{
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	return partman_manage_edit(PMR_MENU_END, partman_raid_edit_menufmt,
+		partman_raid_set_value,	partman_raid_check, partman_raid_new_init,
+		NULL, ((part_entry_t *)arg)[m->cursel].dev_num, MAX_RAIDS,
+		sizeof raids[0], &(raids[0].enabled));
+}
+
+static int
+partman_raid_commit(void)
+{
+	int i, ii, raid_devnum;
+	FILE *f;
+	char f_name[STRSIZE];
+
+	for (raid_devnum = 0, i = 0; raid_devnum < MAX_RAIDS && i < MAX_RAIDS;
+			raid_devnum++, i++) {
+		if (! partman_raid_check(i))
+			continue;
+
+		/* Trying to detect free raid device (yes, ugly way) */
+		while (run_program(RUN_SILENT | RUN_ERROR_OK, "raidctl -G raid%d",
+				raid_devnum) == 0)
+			raid_devnum++;
+
+		/* Generating configure file for our raid */
+		snprintf(f_name, SSTRSIZE, "/tmp/raid.%d.conf", raid_devnum);
+		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, "raidctl -C %s raid%d",
+							f_name, raid_devnum) == 0 &&
+			run_program(RUN_DISPLAY, "raidctl -I %d raid%d",
+							rand(), raid_devnum) == 0 &&
+			run_program(RUN_DISPLAY, "raidctl -vi raid%d",
+							raid_devnum) == 0
+			)
+			raids[i].enabled = 0; /* RAID creation done, remove it from list to 
+									 prevent it's repeated reinitialization */
+	}
+	return 0;
+}
+
+/*** VND ***/
+
+static void
+partman_vnd_menufmt(menudesc *m, int opt, void *arg)
+{
+	int num = ((part_entry_t *)arg)[opt].dev_num;
+
+	if (vnds[num].enabled != 0) {
+		if (strlen(vnds[num].filepath) < 1)
+			wprintw(m->mw, "   PATH NOT DEFINED!");
+		else
+			wprintw(m->mw, "   %s (%dMB)", vnds[num].filepath, vnds[num].size);
+	}
+	return;
+}
+
+static void
+partman_vnd_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	char buf[SSTRSIZE];
+	strcpy(buf, "-");
+
+	switch (opt){
+		case PMV_MENU_FILEPATH:
+			wprintw(m->mw, "File path: %29s", vnds[manage_curdev].filepath);
+			break;
+		case PMV_MENU_EXIST:
+			wprintw(m->mw, "Assign exist image: %20s", vnds[manage_curdev].is_exist?"yes":"no");
+			break;
+		case PMV_MENU_SIZE:
+			if (!vnds[manage_curdev].is_exist)
+				snprintf(buf, SSTRSIZE, "%d", vnds[manage_curdev].size);
+			wprintw(m->mw, "Size (MB):        %22s", buf);
+			break;
+		case PMV_MENU_RO:
+			wprintw(m->mw, "Read-only:        %22s", vnds[manage_curdev].readonly?"yes":"no");
+			break;
+		case PMV_MENU_MGEOM:
+			if (!vnds[manage_curdev].is_exist)
+				snprintf(buf, SSTRSIZE, "%s", vnds[manage_curdev].manual_geom?"yes":"no");
+			wprintw(m->mw, "Set geometry by hand: %18s", buf);
+			break;
+		case PMV_MENU_SECSIZE:
+			if (vnds[manage_curdev].manual_geom && !vnds[manage_curdev].is_exist)
+				snprintf(buf, SSTRSIZE, "%d", vnds[manage_curdev].secsize);
+			wprintw(m->mw, "Bytes per Sector:     %18s", buf);
+			break;
+		case PMV_MENU_NSECTORS:
+			if (vnds[manage_curdev].manual_geom && !vnds[manage_curdev].is_exist)
+				snprintf(buf, SSTRSIZE, "%d", vnds[manage_curdev].nsectors);
+			wprintw(m->mw, "Sectors per Track:    %18s", buf);
+			break;
+		case PMV_MENU_NTRACKS:
+			if (vnds[manage_curdev].manual_geom && !vnds[manage_curdev].is_exist)
+				snprintf(buf, SSTRSIZE, "%d", vnds[manage_curdev].ntracks);
+			wprintw(m->mw, "Tracks per Cylinder:  %18s", buf);
+			break;
+		case PMV_MENU_NCYLINDERS:
+			if (vnds[manage_curdev].manual_geom && !vnds[manage_curdev].is_exist)
+				snprintf(buf, SSTRSIZE, "%d", vnds[manage_curdev].ncylinders);
+			wprintw(m->mw, "Cylinders:        %22s", buf);
+			break;
+
+	}
+	return;
+}
+
+static int
+partman_vnd_set_value(menudesc *m, void *arg)
+{
+	char buf[SSTRSIZE];
+	const char *msg_to_show = NULL;
+	int *out_var = NULL;
+	
+	switch (m->cursel) {
+		case PMV_MENU_FILEPATH:
+			msg_prompt_win("File path?", -1, 18, 0, 0, vnds[manage_curdev].filepath,
+				vnds[manage_curdev].filepath, STRSIZE);
+			return 0;
+		case PMV_MENU_EXIST:
+			vnds[manage_curdev].is_exist = !vnds[manage_curdev].is_exist;
+			return 0;
+		case PMV_MENU_SIZE:
+			if (vnds[manage_curdev].is_exist)
+				return 0;
+			msg_to_show = "Size (MB)";
+			out_var = &(vnds[manage_curdev].size);
+			break;
+		case PMV_MENU_RO:
+			vnds[manage_curdev].readonly = !vnds[manage_curdev].readonly;
+			return 0;
+		case PMV_MENU_MGEOM:
+			if (vnds[manage_curdev].is_exist)
+				return 0;
+			vnds[manage_curdev].manual_geom = !vnds[manage_curdev].manual_geom;
+			return 0;
+		case PMV_MENU_SECSIZE:
+			if (!vnds[manage_curdev].manual_geom || vnds[manage_curdev].is_exist)
+				return 0;
+			msg_to_show = "Bytes per Sector";
+			out_var = &(vnds[manage_curdev].secsize);
+			break;
+		case PMV_MENU_NSECTORS:
+			if (!vnds[manage_curdev].manual_geom || vnds[manage_curdev].is_exist)
+				return 0;
+			msg_to_show = "Sectors per Track";
+			out_var = &(vnds[manage_curdev].nsectors);
+			break;
+		case PMV_MENU_NTRACKS:
+			if (!vnds[manage_curdev].manual_geom || vnds[manage_curdev].is_exist)
+				return 0;
+			msg_to_show = "Tracks per Cylinder";
+			out_var = &(vnds[manage_curdev].ntracks);
+			break;
+		case PMV_MENU_NCYLINDERS:
+			if (!vnds[manage_curdev].manual_geom || vnds[manage_curdev].is_exist)
+				return 0;
+			msg_to_show = "Cylinders";
+			out_var = &(vnds[manage_curdev].ncylinders);
+			break;
+		case PMV_MENU_REMOVE:
+			vnds[manage_curdev].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
+partman_vnd_new_init(void * none)
+{
+	memset(&(vnds[manage_curdev]), 0, sizeof vnds[manage_curdev]);
+	vnds[manage_curdev] = (struct vnds_t) {
+		.enabled = 1,
+		.filepath[0] = '\0',
+		.is_exist = 0,
+		.size = 1024,
+		.readonly = 0,
+		.manual_geom = 0,
+		.secsize = 512,
+		.nsectors = 18,
+		.ntracks = 2,
+		.ncylinders = 80
+	};
+	return;
+}
+
+static int
+partman_vnd_check(int dev_num)
+{
+	if (strlen(vnds[dev_num].filepath) < 1 ||
+			vnds[dev_num].size < 1)
+		vnds[dev_num].enabled = 0;
+	return vnds[dev_num].enabled;
+}
+
+static int
+partman_vnd_edit(menudesc *m, void *arg)
+{
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	return partman_manage_edit(PMV_MENU_END, partman_vnd_edit_menufmt,
+		partman_vnd_set_value, partman_vnd_check, partman_vnd_new_init,
+		NULL, ((part_entry_t *)arg)[m->cursel].dev_num, MAX_VNDS,
+		sizeof vnds[0], &(vnds[0].enabled));
+}
+
+/* TODO: should use only unallocated devices */
+/* TODO: vnconfig always return 0? */
+static int
+partman_vnd_commit(void)
+{
+	int i, not_ok;
+	char r_o[3];
+
+	for (i = 0; i < MAX_VNDS; i++) {
+		not_ok = 0;
+		if (! partman_vnd_check(i))
+			continue;
+		strcpy(r_o, vnds[i].readonly?"-r":"");
+		/* If this is a new image */
+		if (!vnds[i].is_exist)
+			not_ok += run_program(RUN_DISPLAY,
+						"dd if=/dev/zero of=%s bs=1m count=%d progress=100 msgfmt=human",
+						target_expand(vnds[i].filepath), vnds[i].size);
+		if (not_ok)
+			continue;
+
+		/* If this is a new image with manual geometry */
+		if (!vnds[i].is_exist && vnds[i].manual_geom)
+			not_ok += run_program(RUN_DISPLAY,
+						"vnconfig %s vnd%d %s %d %d %d %d", r_o, i,
+						target_expand(vnds[i].filepath), vnds[i].secsize,
+						vnds[i].nsectors, vnds[i].ntracks,	vnds[i].ncylinders);
+		/* If this is a existent image or image without manual geometry */
+		else
+			not_ok += run_program(RUN_DISPLAY, "vnconfig %s vnd%d %s",
+						r_o, i, target_expand(vnds[i].filepath));
+
+		if (! not_ok)
+			vnds[i].enabled = 0;
+	}
+	return 0;
+}
+
+/*** CGD ***/
+
+static void
+partman_cgd_menufmt(menudesc *m, int opt, void *arg)
+{
+	int num = ((part_entry_t *)arg)[opt].dev_num;
+
+	if (cgds[num].enabled != 0) {
+		if (cgds[num].pm == NULL)
+			wprintw(m->mw, "   DISK NOT DEFINED!");
+		else
+			wprintw(m->mw, "   %s%c (%s-%d)", cgds[num].pm->diskdev,
+				cgds[num].pm_part, cgds[num].enc_type, cgds[num].key_size);
+	}
+	return;
+}
+
+static void
+partman_cgd_edit_menufmt(menudesc *m, int opt, void *arg)
+{
+	switch (opt){
+		case PMC_MENU_DEV:
+			wprintw(m->mw, "Base device:    %24s", cgds[manage_curdev].pm_name);
+			break;
+		case PMC_MENU_ENCTYPE:
+			wprintw(m->mw, "Encyption:      %24s", cgds[manage_curdev].enc_type);
+			break;
+		case PMC_MENU_KEYSIZE:
+			wprintw(m->mw, "Key size:       %24d", cgds[manage_curdev].key_size);
+			break;
+		case PMC_MENU_IVTYPE:
+			wprintw(m->mw, "IV algorithm:   %24s", cgds[manage_curdev].iv_type);
+			break;
+		case PMC_MENU_KEYGENTYPE:
+			wprintw(m->mw, "Key generation: %24s", cgds[manage_curdev].keygen_type);
+			break;
+		case PMC_MENU_VERIFYTYPE:
+			wprintw(m->mw, "Verification method:   %17s", cgds[manage_curdev].verify_type);
+			break;
+	}
+	return;
+}
+
+static int
+partman_cgd_set_value(menudesc *m, void *arg)
+{
+	char *retstring;
+
+	switch (m->cursel) {
+		case PMC_MENU_DEV:
+			partman_cgd_disk_set(NULL);
+			return 0;
+		case PMC_MENU_ENCTYPE:
+			process_menu(MENU_cgd_enctype, &retstring);
+			cgds[manage_curdev].enc_type = retstring;
+			if (! strcmp(retstring, "blowfish-cbc"))
+				cgds[manage_curdev].key_size = 128;
+			if (! strcmp(retstring, "3des-cbc"))
+				cgds[manage_curdev].key_size = 192;
+			return 0;
+		case PMC_MENU_KEYSIZE:
+			if (! strcmp(cgds[manage_curdev].enc_type, "aes-cbc"))
+				cgds[manage_curdev].key_size +=
+					(cgds[manage_curdev].key_size < 256)? 64 : -128;
+			if (! strcmp(cgds[manage_curdev].enc_type, "blowfish-cbc"))
+				cgds[manage_curdev].key_size = 128;
+			if (! strcmp(cgds[manage_curdev].enc_type, "3des-cbc"))
+				cgds[manage_curdev].key_size = 192;
+			return 0;
+		case PMC_MENU_IVTYPE:
+			process_menu(MENU_cgd_ivtype, &retstring);
+			cgds[manage_curdev].iv_type = retstring;
+			return 0;
+		case PMC_MENU_KEYGENTYPE:
+			process_menu(MENU_cgd_keygentype, &retstring);
+			cgds[manage_curdev].keygen_type = retstring;
+			return 0;
+		case PMC_MENU_VERIFYTYPE:
+			process_menu(MENU_cgd_verifytype, &retstring);
+			cgds[manage_curdev].verify_type = retstring;
+			return 0;
+		case PMC_MENU_REMOVE:
+			cgds[manage_curdev].enabled = 0;
+			return 0;
+	}
+	return -1;
+}
+
+static void
+partman_cgd_new_init(void *assign_pm)
+{
+	part_entry_t disk_entrie;
+
+	memset(&(cgds[manage_curdev]), 0, sizeof cgds[manage_curdev]);
+	cgds[manage_curdev] = (struct cgds_t) {
+		.enabled = 1,
+		.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 (assign_pm != NULL) {
+			disk_entrie.dev_pm = assign_pm;
+			disk_entrie.dev_num = 'a' + PART_E;
+			snprintf(disk_entrie.fullname, SSTRSIZE, "%s%c",
+				pm->diskdev, 'a' + PART_E);
+		partman_cgd_disk_set(&disk_entrie);
+	}
+	return;
+}
+
+static int
+partman_cgd_check(int dev_num)
+{
+	if (cgds[manage_curdev].pm == NULL)
+		cgds[manage_curdev].enabled = 0;
+	return cgds[manage_curdev].enabled;
+}
+
+static int
+partman_cgd_disk_set(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 = partman_manage_getdev(FS_CGD);
+		if (disk_entrie->retvalue < 0) {
+			free(disk_entrie);
+			return -1;
+		}
+	}
+	cgds[manage_curdev].pm = disk_entrie->dev_pm;
+	cgds[manage_curdev].pm_part = disk_entrie->dev_num;
+	strncpy(cgds[manage_curdev].pm_name, disk_entrie->fullname, SSTRSIZE);
+
+	if (alloc_disk_entrie)
+		free(disk_entrie);
+	return 0;
+}
+
+int
+partman_cgd_edit_adddisk(int cursel, pm_devs_t *assign_pm)
+{
+	if (assign_pm != NULL)
+		cursel = -1;
+	return partman_manage_edit(PMC_MENU_END, partman_cgd_edit_menufmt,
+		partman_cgd_set_value, partman_cgd_check, partman_cgd_new_init,
+		assign_pm, cursel, MAX_CGDS, sizeof cgds[0], &(cgds[0].enabled));
+}
+
+static int
+partman_cgd_edit(menudesc *m, void *arg)
+{
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+	return partman_cgd_edit_adddisk(((part_entry_t *)arg)[m->cursel].dev_num, NULL);
+}
+
+/* TODO: should use only unallocated devices */
+static int
+partman_cgd_commit(void)
+{
+	int i;
+	for (i = 0; i < MAX_CGDS; i++) {
+		if (! partman_cgd_check(i))
+			continue;
+		if (run_program(RUN_DISPLAY, "cgdconfig -g -i %s -k %s -o /tmp/%s %s %d",
+			cgds[i].iv_type, cgds[i].keygen_type, cgds[i].pm_name,
+			cgds[i].enc_type, cgds[i].key_size) != 0)
+			continue;
+		if (run_program(RUN_DISPLAY, "cgdconfig -V re-enter cgd%d /dev/%s /tmp/%s",
+			i, cgds[i].pm_name, cgds[i].pm_name) != 0)
+			continue;
+		cgds[i].enabled = 0;
+	}
+
+	return 0;
+}
+
+/*** LVM ***/
+
+static int
+partman_lvm_edit(menudesc *m, void *arg)
+{
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	return 0;
+//	return partman_manage_edit(PML_MENU_END, partman_lvm_edit_menufmt,
+//		partman_lvm_set_value,	partman_lvm_check, partman_lvm_new_init,
+//		NULL, ((part_entry_t *)arg)[m->cursel].dev_num, MAX_LVMS,
+//		sizeof lvms[0], &(lvms[0].enabled));
+}
+
+/*** Partman generic functions ***/
+
+int
+partman_unconfigure(void)
+{
+	// TODO: rewrite
+	run_program(RUN_SILENT | RUN_ERROR_OK, "cgdconfig -u %s", pm->diskdev);
+	run_program(RUN_SILENT | RUN_ERROR_OK, "vnconfig -u %s", pm->diskdev);
+	run_program(RUN_SILENT | RUN_ERROR_OK, "raidctl -u %s", pm->diskdev);
+	run_program(RUN_SILENT | RUN_ERROR_OK, "umount /dev/%s*", pm->diskdev);
+	return 0;
+}
+
+static void
+partman_select(pm_devs_t *pm_devs_in)
+{
+	pm = pm_devs_in;
+	if (logfp)
+		(void)fprintf(logfp,"Partman device: %s\n", pm->diskdev);
+	return;
+
+}
+
+static int
+partman_mountall_sort(const void *a, const void *b)
+{
+	return strcmp(mnts[*(const int *)a].pi_mount,
+		      mnts[*(const int *)b].pi_mount);
+}
+
+static int
+partman_mountall(void)
+{
+	pm_devs_t *pm_i;
+	int num_devs = 0;
+	int i, ii, error, ok;
+	char diskdev_with_root[SSTRSIZE];
+	diskdev_with_root[0] = '\0';
+
+	int mnts_order[MNTS_MAX]; // TODO: rewrite
+	for (pm_i = pm_head->next, num_devs = 0; pm_i != NULL; pm_i = pm_i->next) {
+		ok = 0;
+		for (i = 0; i < MAXPARTITIONS; i++) {
+			if (pm_i->bsdlabel[i].pi_flags & PIF_MOUNT &&
+					pm_i->bsdlabel[i].mnt_opts != NULL) {
+				mnts[num_devs].pm_part  = i;
+				mnts[num_devs].diskdev  = pm_i->diskdev;
+				mnts[num_devs].mnt_opts = pm_i->bsdlabel[i].mnt_opts;
+				mnts[num_devs].fsname   = pm_i->bsdlabel[i].fsname;
+				mnts[num_devs].pi_mount = pm_i->bsdlabel[i].pi_mount;
+				if (strcmp(pm_i->bsdlabel[i].pi_mount, "/") == 0)
+					strlcpy(diskdev_with_root, pm_i->bsdlabel[i].pi_mount, 
+						sizeof diskdev_with_root);
+				num_devs++;
+				ok = 1;
+			}
+		}
+		if (ok)
+			md_pre_mount();
+	}
+	if (strlen(diskdev_with_root) == 0) {
+		msg_display("No root partition defined, cannot continue\n"); // TODO: localize
+		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], partman_mountall_sort);
+
+	for (i = 0; i < num_devs; i++) {
+		ii = mnts_order[i];
+		make_target_dir(mnts[ii].pi_mount);
+		error = target_mount(mnts[ii].mnt_opts, mnts[ii].diskdev, mnts[ii].pm_part, mnts[ii].pi_mount);
+		if (error) {
+			return error;
+		}
+	}
+	/* Use disk with / as a default if the user has the sets on a local disk */
+	strlcpy(localfs_dev, diskdev_with_root, sizeof localfs_dev);
+	return 0;
+}
+
+static void
+partman_mountmenu_menufmt(menudesc *m, int opt, void *arg)
+{
+	int num = ((part_entry_t *)arg)[opt].dev_num;
+
+	if (pm->bsdlabel[num].pi_flags & PIF_MOUNT && pm->bsdlabel[num].mnt_opts != NULL)
+		wprintw(m->mw, "%s%c at %s", pm->diskdev, 'a' + num, pm->bsdlabel[num].pi_mount);
+
+	return;
+}
+
+static int
+partman_mount(menudesc *m, void *arg)
+{
+	int num = ((part_entry_t *)arg)[m->cursel].dev_num;
+
+	if (pm->bsdlabel[num].pi_flags & PIF_MOUNT && pm->bsdlabel[num].mnt_opts != NULL)
+		return target_mount(pm->bsdlabel[num].mnt_opts, pm->diskdev, num,
+					pm->bsdlabel[num].pi_mount);
+	return -1;
+}
+
+int // TODO: eeee
+partman_mountmenu(void)
+{
+	int i, num_devs = 0;
+	int menu_no;
+	menu_ent menu_entries[MAXPARTITIONS];
+	part_entry_t args[MAXPARTITIONS];
+
+	for (i = 0; i < MAXPARTITIONS; i++) {
+		if (pm->bsdlabel[i].pi_flags & PIF_MOUNT &&
+				pm->bsdlabel[i].mnt_opts != NULL) {
+			menu_entries[num_devs] = (menu_ent) {
+				.opt_name = NULL,
+				.opt_action = partman_mount,
+				.opt_menu = OPT_NOMENU,
+				.opt_flags = OPT_EXIT,
+			};
+			args[num_devs].dev_num = i;
+			num_devs++;
+		}
+	}
+	menu_no = new_menu(NULL, menu_entries, num_devs, 50, 5, num_devs+3, 0,
+		MC_ALWAYS_SCROLL | MC_NOCLEAR, NULL, partman_mountmenu_menufmt,
+		NULL, NULL, NULL);
+	if (menu_no == -1)
+		return -1;
+	process_menu(menu_no, &args);
+	free_menu(menu_no);
+	return 0;
+}
+
+int
+partman_shred(char *dev, int shredtype)
+{
+	int error = 0;
+	switch(shredtype) {
+		case SHRED_NONE:
+			return 0;
+		case SHRED_ZEROS:
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"dd of=/dev/r%sd if=/dev/zero bs=1m progress=100 msgfmt=human", dev);
+			return error; 
+		case SHRED_RANDOM:
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"dd of=/dev/r%sd if=/dev/urandom bs=1m progress=100 msgfmt=human", dev);
+			return error;
+		case SHRED_CRYPTO:
+			error += run_program(RUN_DISPLAY | RUN_PROGRESS,
+				"sh -c 'cgdconfig -s cgd0 /dev/%sd aes-cbc 128 < /dev/urandom'",
+				dev);
+			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");
+			}
+			return error;
+	}
+	return -1;
+}
+
+static int
+partman_commit(menudesc *m, void *arg)
+{
+	int retcode;
+	pm_devs_t *pm_i;
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	for (pm_i = pm_head->next; pm_i != NULL; pm_i = pm_i->next) {
+		if (! pm_i->changed)
+			continue;
+		partman_select(pm_i);
+		if (
+				md_pre_disklabel() != 0  || /* Write partition table */
+				write_disklabel() != 0   || /* Write slices table (disklabel) */
+				md_post_disklabel() != 0 || /* Enable swap and check badblock */
+				make_filesystems()          /* Create filesystems by newfs */
+			) { /* If something fails... */
+			if (logfp)
+				fprintf(logfp, "Disk preparing error\n");
+			return -1;
+		} else
+			pm_i->changed = 0;
+		/* Write bootsector if needed */
+		if (pm_i->bootable && md_post_newfs() != 0)
+			return -1;
+	}
+	/* Call all functions that may create new devices */
+	if ((retcode = partman_raid_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "Raid configuring error #%d\n", retcode);
+		return -1;
+	}
+	if ((retcode = partman_vnd_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "VND configuring error #%d\n", retcode);
+		return -1;
+	}
+	if ((retcode = partman_cgd_commit()) != 0) {
+		if (logfp)
+			fprintf(logfp, "CGD configuring error #%d\n", retcode);
+		return -1;
+	}
+	partman_upddevlist(m, arg);
+	if (logfp)
+		fflush (logfp);
+    return 0;
+}
+
+static int
+partman_submenu(menudesc *m, void *arg)
+{
+	pm_devs_t *pm_i = ((part_entry_t *)arg)[m->cursel].dev_pm;;
+	int we_need_updlist = 0;
+	((part_entry_t *)arg)[0].retvalue = m->cursel + 1;
+
+	if (pm_i == NULL) 
+		return -1;
+	partman_select(pm_i);
+
+	process_menu(MENU_pmentry, &we_need_updlist);
+	if (we_need_updlist)
+		partman_upddevlist(m, arg);
+
+	return 0;
+}
+
+static void
+partman_menufmt(menudesc *m, int opt, void *arg)
+{
+	const char *dev_status = "";
+	int part_num = ((part_entry_t *)arg)[opt].dev_num;
+	pm_devs_t *pm_i = ((part_entry_t *)arg)[opt].dev_pm;
+
+	switch (((part_entry_t *)arg)[opt].type) {
+		case PM_DISK_T:
+			if (! pm_i->changed)
+				dev_status = "UNCHANGED";
+			else if (pm_i->bootable)
+				dev_status = "BOOT";
+			else
+				dev_status = "USED";
+			wprintw(m->mw, "%-33s Name:%-20s %9s", pm_i->diskdev_descr, pm_i->bsddiskname, dev_status);
+			break;
+		case PM_PART_T:
+			wprintw(m->mw, "   part %c: %-22s %-22s %11uM",
+				'a' + part_num,
+				pm_i->bsdlabel[part_num].pi_mount,
+				fstype_name(pm_i->bsdlabel[part_num].pi_fstype),
+				pm_i->bsdlabel[part_num].pi_size / (MEG / pm_i->sectorsize));
+			break;
+		case PM_RAID_T:
+			partman_raid_menufmt(m, opt, arg);
+			break;
+		case PM_VND_T:
+			partman_vnd_menufmt(m, opt, arg);
+			break;
+		case PM_CGD_T:
+			partman_cgd_menufmt(m, opt, arg);
+			break;
+	}
+	return;
+}
+
+static int
+partman_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;
+
+	find_disks("partman");
+
+	if (m != NULL && arg != NULL) {
+		for (pm_i = pm_head->next, i = 0; pm_i != NULL;
+				pm_i = pm_i->next, i++) {
+			m->opts[i].opt_name = NULL;
+			m->opts[i].opt_action = partman_submenu;
+			((part_entry_t *)arg)[i].dev_pm = pm_i;
+			((part_entry_t *)arg)[i].dev_num = -1;
+			((part_entry_t *)arg)[i].type = PM_DISK_T;
+			for (ii = 0; ii < MAXPARTITIONS; ii++) {
+				if ((pm_i->bsdlabel[ii].pi_flags & PIF_MOUNT &&
+						pm_i->bsdlabel[ii].pi_fstype != FS_UNUSED) ||
+						pm_i->bsdlabel[ii].pi_fstype == FS_RAID ||
+						pm_i->bsdlabel[ii].pi_fstype == FS_CGD) {
+					i++;
+					m->opts[i].opt_name = NULL;
+					m->opts[i].opt_action = partman_submenu;
+					((part_entry_t *)arg)[i].dev_pm = pm_i;
+					((part_entry_t *)arg)[i].dev_num = ii;
+					((part_entry_t *)arg)[i].type = PM_PART_T;
+				}
+			}
+		}
+		((part_entry_t *)arg)[i].dev_num = -1;
+		m->opts[i++] = (struct menu_ent) {
+			.opt_name = "Create cryptographic volume (CGD)",
+			.opt_action = partman_cgd_edit,
+		};
+		for (ii = 0; ii < MAX_CGDS; ii++) {
+			if (cgds[ii].enabled == 0)
+				continue;
+			m->opts[i] = (struct menu_ent) {
+				.opt_name = NULL,
+				.opt_action = partman_cgd_edit,
+			};
+			((part_entry_t *)arg)[i].dev_num = ii;
+			((part_entry_t *)arg)[i].type = PM_CGD_T;
+			i++;
+		}
+		((part_entry_t *)arg)[i].dev_num = -1;
+		m->opts[i++] = (struct menu_ent) {
+			.opt_name = "Create virtual disk image (VND)",
+			.opt_action = partman_vnd_edit,
+		};
+		for (ii = 0; ii < MAX_VNDS; ii++) {
+			if (vnds[ii].enabled == 0)
+				continue;
+			m->opts[i] = (struct menu_ent) {
+				.opt_name = NULL,
+				.opt_action = partman_vnd_edit,
+			};
+			((part_entry_t *)arg)[i].dev_num = ii;
+			((part_entry_t *)arg)[i].type = PM_VND_T;
+			i++;
+		}
+		((part_entry_t *)arg)[i].dev_num = -1;
+		m->opts[i++] = (struct menu_ent) {
+			.opt_name = "Create logical volume (LVM) [WIP]",
+			.opt_action = partman_lvm_edit,
+		};
+		((part_entry_t *)arg)[i].dev_num = -1;
+		m->opts[i++] = (struct menu_ent) {
+			.opt_name = "Create software RAID",
+			.opt_action = partman_raid_edit,
+		};
+		for (ii = 0; ii < MAX_RAIDS; ii++) {
+			if (raids[ii].enabled == 0)
+				continue;
+			m->opts[i] = (struct menu_ent) {
+				.opt_name = NULL,
+				.opt_action = partman_raid_edit,
+			};
+			((part_entry_t *)arg)[i].dev_num = ii;
+			((part_entry_t *)arg)[i].type = PM_RAID_T;
+			i++;
+		}
+		m->opts[i++] = (struct menu_ent) {
+			.opt_name = "Update devices list",
+			.opt_action = partman_upddevlist,
+		};
+		m->opts[i  ] = (struct menu_ent) {
+			.opt_name = "Save changes",
+			.opt_action = partman_commit,
+		};
+		for (ii = 0; ii <= i; ii++) {
+			m->opts[ii].opt_menu = OPT_NOMENU;
+			m->opts[ii].opt_flags = OPT_EXIT;
+		}
+	}
+	return i;
+}
+
+// TODO: switch to langfiles
+int
+partman(void)
+{
+	int menu_no;
+	int menu_num_entries;
+	menu_ent menu_entries[MAX_DISKS+6];
+	part_entry_t args[MAX_DISKS];
+
+	do {
+		clear();
+		refresh();
+		menu_num_entries = partman_upddevlist(&((menudesc) {.opts = menu_entries}), args);
+		menu_no = new_menu("Partition manager. All disks, partitions, LVM, RAID displayed there.\nAt first add drive, then prepare partitions and go.",
+			menu_entries, menu_num_entries+1, 1, 1, 0, 0,
+			MC_ALWAYS_SCROLL | MC_NOBOX | MC_NOCLEAR,
+			NULL, partman_menufmt, NULL, NULL, "Finish partitioning");
+		if (menu_no == -1)
+			args[0].retvalue = -1;
+		else {
+			args[0].retvalue = 0;
+			process_menu(menu_no, &args);
+			free_menu(menu_no);
+		}
+
+		// TODO: check_partitions()
+		/* Check that fstab on target device is readable - if so then we can go */
+		if (args[0].retvalue == 0) {
+			unwind_mounts();
+			if (partman_mountall() != 0 ||
+				make_fstab() != 0) {
+					msg_display("Do you want to try?");
+					process_menu(MENU_yesno, NULL);
+					args[0].retvalue = (yesno) ? 1:-1;
+			} else {
+				FILE *file_tmp = fopen(concat_paths(targetroot_mnt, "/etc/fstab"), "r");
+				if (file_tmp == NULL)
+					args[0].retvalue = -1;
+				else
+					fclose(file_tmp);
+			}
+		}
+	} 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 a4467de..a711ded 100644
--- a/distrib/utils/sysinst/savenewlabel.c
+++ b/distrib/utils/sysinst/savenewlabel.c
@@ -55,14 +55,19 @@ __RCSID("$NetBSD: savenewlabel.c,v 1.12 2012/01/05 22:18:36 christos Exp $");
 
 int
 /*ARGSUSED*/
-savenewlabel(partinfo *lp, int nparts)
+savenewlabel(partinfo *lp, int nparts) /* TODO: what does lp there? */
 {
 	FILE *f;
 	char *f_name = malloc(STRSIZE * sizeof(char));
 	int i;
+	pm_devs_t *pm_i;
 
-	strlcpy(f_name, "/tmp/disktab.", STRSIZE);
-	strlcat(f_name, pm->bsddiskname, STRSIZE);
+	/* Check names collision */
+	for (pm_i = pm_head->next; partman_go && pm_i != NULL; pm_i = pm_i->next)
+		while (pm_i != pm && !strcmp(pm_i->bsddiskname, pm->bsddiskname))
+			pm->bsddiskname[strlen(pm->bsddiskname)-1] = rand() % ('z' - 'a') + 'a';
+
+	snprintf(f_name, STRSIZE, "/tmp/disktab.%s", pm->bsddiskname); // TODO: test
 
 	/*
 	  N.B. disklabels only support up to 2TB (32-bit field for sectors).
@@ -85,11 +90,11 @@ savenewlabel(partinfo *lp, int nparts)
 		exit (1);
 	}
 	scripting_fprintf(f, "%s|NetBSD installation generated:\\\n", pm->bsddiskname);
-	scripting_fprintf(f, "\t:dt=%s:ty=winchester:\\\n", disktype);
+	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, doessf);
+	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)
diff --git a/distrib/utils/sysinst/target.c b/distrib/utils/sysinst/target.c
index fb85a8c..6b8aeb7 100644
--- a/distrib/utils/sysinst/target.c
+++ b/distrib/utils/sysinst/target.c
@@ -159,7 +159,7 @@ target_already_root(void)
 		 */
 		return 1;
 
-	return is_active_rootpart(pm->diskdev, rootpart);
+	return is_active_rootpart(pm->diskdev, pm->rootpart);
 }
 
 
diff --git a/distrib/utils/sysinst/util.c b/distrib/utils/sysinst/util.c
index acfdfe9..d1df210 100644
--- a/distrib/utils/sysinst/util.c
+++ b/distrib/utils/sysinst/util.c
@@ -489,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.
@@ -553,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,
@@ -1632,4 +1624,11 @@ do_coloring (unsigned int fg, unsigned int bg) {
 	wrefresh(stdscr);
 	wrefresh(mainwin);
 	return;
-}
\ No newline at end of file
+}
+
+int
+set_menu_select(menudesc *m, void *arg)
+{
+	*(int *)arg = m->cursel;
+	return 1;
+}
