Subject: Installboot changes for RAID boot
To: None <tech-install@netbsd.org,>
From: Julian Coleman <jdc@coris.org.uk>
List: tech-install
Date: 06/17/2006 11:26:19
--pWyiEgJYm5f9v55/
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

In oder to add support for RAID 1 boot on sparc, installboot needs to know
how to find files on RAID filesystems.  This is so that it can find the
block list of the 2nd stage boot loader and add those blocks to the first
stage boot loader.

I've attached a set of patches that does this, adding a `raid' type and an
offset when searching the disk for filesystem information.  Can anyone see
any problem with these changes?

Thanks,

J

-- 
  My other computer also runs NetBSD    /        Sailing at Newbiggin
        http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/

--pWyiEgJYm5f9v55/
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="installboot.diffs"

diff -ur /usr/src/usr.sbin/installboot/ffs.c ./ffs.c
--- /usr/src/usr.sbin/installboot/ffs.c	2006-02-19 23:32:29.000000000 +0000
+++ ./ffs.c	2006-05-19 07:29:13.000000000 +0100
@@ -63,6 +63,8 @@
 
 #include "installboot.h"
 
+#include <dev/raidframe/raidframevar.h>
+
 #undef DIRBLKSIZ
 
 #include <ufs/ufs/dinode.h>
@@ -77,6 +79,7 @@
 #define	ffs_dinode2_swap(inode_a, inode_b)
 #endif
 
+static int	ffs_match_common(ib_params *, off_t);
 static int	ffs_read_disk_block(ib_params *, uint64_t, int, char *);
 static int	ffs_find_disk_blocks_ufs1(ib_params *, ino_t,
 		    int (*)(ib_params *, void *, uint64_t, uint32_t), void *);
@@ -160,8 +163,9 @@
 	}
 
 	/* Read the inode. */
-	if (! ffs_read_disk_block(params, fsbtodb(fs, ino_to_fsba(fs, ino)),
-		fs->fs_bsize, inodebuf))
+	if (! ffs_read_disk_block(params,
+	    fsbtodb(fs, ino_to_fsba(fs, ino)) + params->fstype->offset,
+	    fs->fs_bsize, inodebuf))
 		return (0);
 	inode = (struct ufs1_dinode *)inodebuf;
 	inode += ino_to_fsbo(fs, ino);
@@ -215,7 +219,7 @@
 			if (blk == 0)
 				memset(level[level_i].diskbuf, 0, MAXBSIZE);
 			else if (! ffs_read_disk_block(params, 
-				fsbtodb(fs, blk),
+				fsbtodb(fs, blk) + params->fstype->offset,
 				fs->fs_bsize, level[level_i].diskbuf))
 				return (0);
 			/* XXX ondisk32 */
@@ -231,7 +235,8 @@
 		    fsbtodb(fs, blk), sblksize(fs, inode->di_size, lblk));
 #endif
 		rv = (*callback)(params, state, 
-		    fsbtodb(fs, blk), sblksize(fs, inode->di_size, lblk));
+		    fsbtodb(fs, blk) + params->fstype->offset,
+		    sblksize(fs, inode->di_size, lblk));
 		lblk++;
 		nblk--;
 		if (rv != 1)
@@ -461,6 +466,23 @@
 int
 ffs_match(ib_params *params)
 {
+	return ffs_match_common(params, (off_t) 0);
+}
+
+int
+raid_match(ib_params *params)
+{
+	/* XXX Assumes 512 bytes / sector */
+	if (DEV_BSIZE != 512) {
+		warnx("RAID only supported on 512 bytes/sector media.");
+		return 0;
+	}
+	return ffs_match_common(params, (off_t) RF_PROTECTED_SECTORS);
+}
+
+int
+ffs_match_common(ib_params *params, off_t offset)
+{
 	char		sbbuf[SBLOCKSIZE];
 	struct fs	*fs;
 	int i;
@@ -471,7 +493,7 @@
 
 	fs = (struct fs *)sbbuf;
 	for (i = 0; sblock_try[i] != -1; i++) {
-		loc = sblock_try[i] / DEV_BSIZE;
+		loc = sblock_try[i] / DEV_BSIZE + offset;
 		if (!ffs_read_disk_block(params, loc, SBLOCKSIZE, sbbuf))
 			continue;
 		switch (fs->fs_magic) {
@@ -482,6 +504,7 @@
 			params->fstype->needswap = 0;
 			params->fstype->blocksize = fs->fs_bsize;
 			params->fstype->sblockloc = loc;
+			params->fstype->offset = offset;
 			break;
 #ifndef FFS_NO_SWAP
 		case FS_UFS2_MAGIC_SWAPPED:
@@ -491,6 +514,7 @@
 			params->fstype->needswap = 1;
 			params->fstype->blocksize = bswap32(fs->fs_bsize);
 			params->fstype->sblockloc = loc;
+			params->fstype->offset = offset;
 			break;
 #endif
 		default:
diff -ur /usr/src/usr.sbin/installboot/fstypes.c ./fstypes.c
--- /usr/src/usr.sbin/installboot/fstypes.c	2006-02-19 23:32:29.000000000 +0000
+++ ./fstypes.c	2006-05-19 07:28:04.000000000 +0100
@@ -56,6 +56,7 @@
 struct ib_fs fstypes[] = {
 #ifndef NO_STAGE2
 	{ "ffs",	ffs_match,	ffs_findstage2	},
+	{ "raid",	raid_match,	ffs_findstage2	},
 	{ "raw",	raw_match,	raw_findstage2	},
 #endif
 	{ 0, 0, 0 }
diff -ur /usr/src/usr.sbin/installboot/installboot.8 ./installboot.8
--- /usr/src/usr.sbin/installboot/installboot.8	2006-01-22 15:58:54.000000000 +0000
+++ ./installboot.8	2006-05-19 09:53:31.000000000 +0100
@@ -34,7 +34,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd January 13, 2006
+.Dd May 19, 2006
 .Dt INSTALLBOOT 8
 .Os
 .Sh NAME
@@ -310,12 +310,15 @@
 The following file system types are currently supported by
 .Nm :
 .
-.Bl -tag -offset indent -width ffs
+.Bl -tag -offset indent -width raid
 .
 .It Sy ffs
 .Bx
 Fast File System.
 .
+.It Sy raid
+Mirrored RAIDframe File System.
+.
 .It Sy raw
 .Sq Raw
 image.
@@ -372,7 +375,7 @@
 .It macppc Ta ffs, raw
 .It news68k Ta ffs, raw
 .It newsmips Ta ffs, raw
-.It sparc Ta ffs, raw
+.It sparc Ta ffs, raid, raw
 .It sun2 Ta ffs, raw
 .It sun3 Ta ffs, raw
 .El
@@ -687,6 +690,18 @@
 .Sh BUGS
 There are not currently primary bootstraps to support all file systems
 types which are capable of being the root file system.
+.Pp
+If a disk has been converted from
+.Sy FFS
+to
+.Sy RAID
+without the contents of the disk erased, then the original
+.Sy FFS
+installation may be auto-detected instead of the
+.Sy RAID
+installation.  In this case, the
+.Fl t Ar raid
+option must be provided.
 .
 .Ss Nx Ns Tn /alpha
 The
diff -ur /usr/src/usr.sbin/installboot/installboot.h ./installboot.h
--- /usr/src/usr.sbin/installboot/installboot.h	2006-02-19 23:32:29.000000000 +0000
+++ ./installboot.h	2006-05-17 22:39:42.000000000 +0100
@@ -118,6 +118,7 @@
 	uint32_t	 blocksize;
 	uint32_t	 needswap;
 	off_t		sblockloc;	/* location of superblock */
+	off_t		offset;		/* file system offset (e.g. RAID) */
 };
 
 typedef enum {
@@ -157,6 +158,7 @@
 int		hardcode_stage2(ib_params *, uint32_t *, ib_block *);
 int		ffs_match(ib_params *);
 int		ffs_findstage2(ib_params *, uint32_t *, ib_block *);
+int		raid_match(ib_params *);
 int		raw_match(ib_params *);
 int		raw_findstage2(ib_params *, uint32_t *, ib_block *);
 

--pWyiEgJYm5f9v55/--