Sun Jan 29 16:01:37 2012 UTC ()
Add support for RDB-partitioned disks.
When an RDB block was found on the disk we cannot change the disk layout,
and everything which has to do with MBR partitioning will be skipped.


(phx)
diff -r1.10 -r1.11 src/distrib/utils/sysinst/arch/ofppc/md.c
diff -r1.6 -r1.7 src/distrib/utils/sysinst/arch/ofppc/md.h

cvs diff -r1.10 -r1.11 src/distrib/utils/sysinst/arch/ofppc/Attic/md.c (expand / switch to context diff)
--- src/distrib/utils/sysinst/arch/ofppc/Attic/md.c 2011/11/04 11:27:04 1.10
+++ src/distrib/utils/sysinst/arch/ofppc/Attic/md.c 2012/01/29 16:01:36 1.11
@@ -1,4 +1,4 @@
-/*	$NetBSD: md.c,v 1.10 2011/11/04 11:27:04 martin Exp $	*/
+/*	$NetBSD: md.c,v 1.11 2012/01/29 16:01:36 phx Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -36,6 +36,7 @@
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
+#include <sys/disklabel_rdb.h>
 #include <stdio.h>
 #include <util.h>
 #include <machine/cpu.h>
@@ -46,12 +47,16 @@
 #include "menu_defs.h"
 #include "endian.h"
 
+static int check_rdb(void);
+static uint32_t rdbchksum(void *);
+
 /* We use MBR_PTYPE_PREP like port-prep does. */
 static int nonewfsmsdos = 0, nobootfix = 0, noprepfix=0;
 static int bootpart_fat12 = PART_BOOT_FAT12;
 static int bootpart_binfo = PART_BOOT_BINFO;
 static int bootpart_prep = PART_BOOT_PREP;
 static int bootinfo_mbr = 1;
+static int rdb_found = 0;
 
 /* bootstart/bootsize are for the fat */
 int binfostart, binfosize, bprepstart, bprepsize;
@@ -64,12 +69,17 @@
 void
 md_init_set_status(int flags)
 {
+
 	(void)flags;
 }
 
 int
 md_get_info(void)
 {
+
+	if (check_rdb())
+		return 1;
+
 	return set_bios_geom_with_mbr_guess();
 }
 
@@ -88,6 +98,41 @@
 	int no_swap = 0;
 	partinfo *p;
 
+	if (rdb_found) {
+		/*
+		 * We found RDB partitions on the disk, which cannot be
+		 * modified by rewriting the disklabel.
+		 * So just use what we have got.
+		 */
+		for (part = 0; part < maxpart; part++) {
+			if (PI_ISBSDFS(&bsdlabel[part])) {
+				bsdlabel[part].pi_flags |=
+				    PIF_NEWFS | PIF_MOUNT;
+
+				if (part == PART_A)
+					strcpy(bsdlabel[part].pi_mount, "/");
+			}
+		}
+
+		part_bsd = part_raw = getrawpartition();
+		if (part_raw == -1)
+			part_raw = PART_C;	/* for sanity... */
+		bsdlabel[part_raw].pi_offset = 0;
+		bsdlabel[part_raw].pi_size = dlsize;
+
+		set_sizemultname_meg();
+rdb_edit_check:
+		if (edit_and_check_label(bsdlabel, maxpart, part_raw,
+		    part_bsd) == 0) {
+			msg_display(MSG_abort);
+			return 0;
+		}
+		if (md_check_partitions() == 0)
+			goto rdb_edit_check;
+
+		return 1;
+	}
+
 	/*
 	 * Initialize global variables that track space used on this disk.
 	 * Standard 4.4BSD 8-partition labels always cover whole disk.
@@ -223,6 +268,9 @@
 {
 	int part, fprep=0, ffat=0;
 
+	if (rdb_found)
+		return 1;
+
 	/* we need to find a boot partition, otherwise we can't create
 	 * our msdos fs boot partition.  We make the assumption that
 	 * the user hasn't done something stupid, like move it away
@@ -259,6 +307,10 @@
 int
 md_pre_disklabel(void)
 {
+
+	if (rdb_found)
+		return 0;
+
 	msg_display(MSG_dofdisk);
 
 	/* write edited MBR onto disk. */
@@ -278,7 +330,7 @@
 {
 	char bootdev[100];
 
-	if (bootstart == 0 || bootsize == 0)
+	if (bootstart == 0 || bootsize == 0 || rdb_found)
 		return 0;
 
 	snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", diskdev,
@@ -307,7 +359,7 @@
 	char bootdev[100], bootbdev[100], version[64];
 
 	/* if we can't make it bootable, just punt */
-	if (nobootfix && noprepfix)
+	if ((nobootfix && noprepfix) || rdb_found)
 		return 0;
 
 	snprintf(version, sizeof version, "NetBSD/%s %s", MACH, REL);
@@ -353,6 +405,7 @@
 void
 md_cleanup_install(void)
 {
+
 #ifndef DEBUG
 	enable_rc_conf();
 #endif
@@ -365,6 +418,9 @@
 	mbr_info_t *ext;
 	int i;
 
+	if (check_rdb())
+		return 1;
+
 	read_mbr(diskdev, &mbr);
 	/* do a sanity check of the partition table */
 	for (ext = &mbr; ext; ext = ext->extended) {
@@ -400,6 +456,7 @@
 int
 md_update(void)
 {
+
 	nonewfsmsdos = 1;
 	md_post_newfs();
 	return 1;
@@ -543,8 +600,56 @@
 	return 1;
 }
 
+const char *md_disklabel_cmd(void)
+{
+
+	/* we cannot rewrite an RDB disklabel */
+	if (rdb_found)
+		return "echo No disklabel";
+
+	return "disklabel -w -r";
+}
+
+static int
+check_rdb(void)
+{
+	char buf[512], diskpath[MAXPATHLEN];
+	struct rdblock *rdb;
+	off_t blk;
+	int fd;
+
+	/* Find out if this disk has a valid RDB, before continuing. */
+	rdb = (struct rdblock *)buf;
+	fd = opendisk(diskdev, O_RDONLY, diskpath, sizeof(diskpath), 0);
+	if (fd < 0)
+		return 0;
+	for (blk = 0; blk < RDB_MAXBLOCKS; blk++) {
+		if (pread(fd, rdb, 512, blk * 512) != 512)
+			return 0;
+		if (rdb->id == RDBLOCK_ID && rdbchksum(rdb) == 0) {
+			rdb_found = 1;	/* do not repartition! */
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static uint32_t
+rdbchksum(void *bdata)
+{
+	uint32_t *blp, cnt, val;
+
+	blp = bdata;
+	cnt = blp[1];
+	val = 0;
+	while (cnt--)
+		val += *blp++;
+	return val;
+}
+
 int
 md_pre_mount()
 {
+
 	return 0;
 }

cvs diff -r1.6 -r1.7 src/distrib/utils/sysinst/arch/ofppc/Attic/md.h (expand / switch to context diff)
--- src/distrib/utils/sysinst/arch/ofppc/Attic/md.h 2011/08/21 15:21:46 1.6
+++ src/distrib/utils/sysinst/arch/ofppc/Attic/md.h 2012/01/29 16:01:37 1.7
@@ -1,4 +1,4 @@
-/*	$NetBSD: md.h,v 1.6 2011/08/21 15:21:46 phx Exp $	*/
+/*	$NetBSD: md.h,v 1.7 2012/01/29 16:01:37 phx Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -100,4 +100,5 @@
  *
  * On ofppc, do what the 1.2 install scripts did.
  */
-#define DISKLABEL_CMD "disklabel -w -r"
+const char *md_disklabel_cmd(void);
+#define DISKLABEL_CMD md_disklabel_cmd()