Port-xen archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
NetBSD support in pygrub
Hi,
I patched tools/pygrub and tools/libfsimage to support NetBSD and FFSv2,
see attachment for a git diff against xen.
It doesn't provide a fancy GUI, but it provides minimal support for the
/boot.cfg file to retrieve the kernel and arguments.
I use it with xen-unstable and the xl toolstack, and "it works for me"
with netbsd-current and a ufs2 root filesystem.
There's just one minor nuisance (well, besides the code being rather
hackish) after pygrub finishes: I have to manually send a Control+] to
the VM console to force the boot to continue.
I'm not sure if this is a problem with my xen-unstable installation or
something I broke ...
Any feedback or pointers on how to resolve the console/boot issue would
be welcome.
diff --git a/tools/libfsimage/ufs/fsys_ufs.c b/tools/libfsimage/ufs/fsys_ufs.c
index be51411..41f2984 100644
--- a/tools/libfsimage/ufs/fsys_ufs.c
+++ b/tools/libfsimage/ufs/fsys_ufs.c
@@ -30,30 +30,42 @@
/* These are the pools of buffers, etc. */
#define SUPERBLOCK ((struct fs *)(FSYS_BUF + 0x2000))
-#define INODE ((struct icommon *)(FSYS_BUF + 0x1000))
+#define FS_IS_UFS2 (SUPERBLOCK->fs_magic == UFS2_MAGIC)
+#define INODE ((struct icommon *)(FSYS_BUF + 0x1000))
+#define UFS2_INODE ((struct ufs2_dinode *)(FSYS_BUF + 0x1000))
+#define INODE_SIZE ((FS_IS_UFS2) ? sizeof(struct ufs2_dinode) : sizeof(struct
icommon))
#define DIRENT (FSYS_BUF + 0x4000)
#define MAXBSIZE ((FSYS_BUFLEN - 0x4000) / 2)
#define INDIRBLK1 ((grub_daddr32_t *)(FSYS_BUF + 0x4000)) /* 2+ indir blk */
-#define INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x4000 + MAXBSIZE)) /*
1st indirect blk */
+#define INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x4000 + MAXBSIZE)) /* 1st
indirect blk */
+#define UFS2_INDIRBLK1 ((int64_t *)(FSYS_BUF + 0x4000)) /* 2+ indir blk */
+#define UFS2_INDIRBLK0 ((int64_t *)(FSYS_BUF+ 0x4000 + MAXBSIZE)) /* 1st
indirect blk */
#define indirblk0 (*fsig_int1(ffi))
#define indirblk1 (*fsig_int2(ffi))
static int openi(fsi_file_t *, grub_ino_t);
static grub_ino_t dlook(fsi_file_t *, grub_ino_t, char *);
-static grub_daddr32_t sbmap(fsi_file_t *, grub_daddr32_t);
+static int64_t sbmap(fsi_file_t *, int64_t);
/* read superblock and check fs magic */
static int
ufs_mount(fsi_file_t *ffi, const char *options)
{
- if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */
- !devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) ||
- SUPERBLOCK->fs_magic != UFS_MAGIC ||
- MAXBSIZE < SUPERBLOCK->fs_bsize)
- return 0;
-
- return 1;
+ const int sblocksearch[] = {0, UFS_SBLOCK, UFS2_SBLOCK, UFS2_PIGGY};
+ int i;
+ int found=0;
+ for (i = 0; i < (sizeof(sblocksearch)/sizeof(int)); i++)
+ {
+ if (devread(ffi, sblocksearch[i], 0, UFS_SBSIZE, (char
*)SUPERBLOCK) &&
+ ( SUPERBLOCK->fs_magic == UFS_MAGIC ||
+ SUPERBLOCK->fs_magic == UFS2_MAGIC ) &&
+ MAXBSIZE >= SUPERBLOCK->fs_bsize) {
+ found=1;
+ break;
+ }
+ }
+ return found;
}
@@ -95,8 +107,13 @@ ufs_dir(fsi_file_t *ffi, char *dirname)
if (! openi(ffi, inode))
return (0);
filepos = 0;
- filemax = INODE->ic_sizelo;
- return (inode && ((INODE->ic_smode & IFMT) == IFREG));
+ if (FS_IS_UFS2) {
+ filemax = UFS2_INODE->di_size;
+ return (inode && ((UFS2_INODE->di_mode & IFMT) == IFREG));
+ } else {
+ filemax = INODE->ic_sizelo;
+ return (inode && ((INODE->ic_smode & IFMT) == IFREG));
+ }
}
/*
@@ -105,11 +122,13 @@ ufs_dir(fsi_file_t *ffi, char *dirname)
static int
ufs_read(fsi_file_t *ffi, char *buf, int len)
{
- int off, size, ret = 0, ok;
- grub_daddr32_t lblk, dblk;
-
- while (len) {
- off = blkoff(SUPERBLOCK, filepos);
+ int64_t off, size, ret = 0, ok;
+ int64_t lblk, dblk;
+ while (len) {
+ if (FS_IS_UFS2)
+ off = ufs2_blkoff(SUPERBLOCK, filepos);
+ else
+ off = blkoff(SUPERBLOCK, filepos);
lblk = lblkno(SUPERBLOCK, filepos);
size = SUPERBLOCK->fs_bsize;
size -= off;
@@ -152,12 +171,17 @@ openi(fsi_file_t *ffi, grub_ino_t inode)
{
grub_daddr32_t dblk;
int off;
+ grub_uint32_t size;
/* get block and byte offset into the block */
dblk = fsbtodb(SUPERBLOCK, itod(SUPERBLOCK, inode));
- off = itoo(SUPERBLOCK, inode) * sizeof (struct icommon);
+ if (FS_IS_UFS2)
+ size = sizeof(struct ufs2_dinode);
+ else
+ size = sizeof(struct icommon);
+ off = itoo(SUPERBLOCK, inode) * size;
- return (devread(ffi, dblk, off, sizeof (struct icommon), (char
*)INODE));
+ return (devread(ffi, dblk, off, size, (char *)INODE));
}
/*
@@ -165,16 +189,21 @@ openi(fsi_file_t *ffi, grub_ino_t inode)
* Returns 0 when block doesn't exist and <0 when block isn't initialized
* (i.e belongs to a hole in the file).
*/
-grub_daddr32_t
-sbmap(fsi_file_t *ffi, grub_daddr32_t bn)
+int64_t
+sbmap(fsi_file_t *ffi, int64_t bn)
{
- int level, bound, i, index;
- grub_daddr32_t nb, blkno;
+ int level, bound, i, index;
+ int64_t nb, blkno;
grub_daddr32_t *db = INODE->ic_db;
+ int64_t *db2 = UFS2_INODE->di_db;
+ char *ib_ptr;
/* blocks 0..UFS_NDADDR are direct blocks */
if (bn < UFS_NDADDR) {
- return db[bn];
+ if (FS_IS_UFS2)
+ return db2[bn];
+ else
+ return db[bn];
}
/* determine how many levels of indirection. */
@@ -187,41 +216,59 @@ sbmap(fsi_file_t *ffi, grub_daddr32_t bn)
bound *= UFS_NINDIR(SUPERBLOCK);
}
if (level >= UFS_NIADDR) /* bn too big */
- return ((grub_daddr32_t)0);
+ return ((int64_t)0);
/* fetch the first indirect block */
- nb = INODE->ic_ib[level];
+ if (FS_IS_UFS2)
+ nb = UFS2_INODE->di_ib[level];
+ else
+ nb = INODE->ic_ib[level];
+
if (nb == 0) {
- return ((grub_daddr32_t)0);
+ return ((int64_t)0);
}
if (indirblk0 != nb) {
+ if (FS_IS_UFS2)
+ ib_ptr = (char *)UFS2_INDIRBLK0;
+ else
+ ib_ptr = (char *)INDIRBLK0;
indirblk0 = 0;
blkno = fsbtodb(SUPERBLOCK, nb);
if (!devread(ffi, blkno, 0, SUPERBLOCK->fs_bsize,
- (char *)INDIRBLK0))
+ ib_ptr))
return (0);
indirblk0 = nb;
}
bound /= UFS_NINDIR(SUPERBLOCK);
index = (bn / bound) % UFS_NINDIR(SUPERBLOCK);
- nb = INDIRBLK0[index];
+ if (FS_IS_UFS2)
+ nb = UFS2_INDIRBLK0[index];
+ else
+ nb = INDIRBLK0[index];
/* fetch through the indirect blocks */
for (i = 1; i <= level; i++) {
if (indirblk1 != nb) {
+ if (FS_IS_UFS2)
+ ib_ptr = (char *)UFS2_INDIRBLK1;
+ else
+ ib_ptr = (char *)INDIRBLK1;
+
blkno = fsbtodb(SUPERBLOCK, nb);
if (!devread(ffi, blkno, 0, SUPERBLOCK->fs_bsize,
- (char *)INDIRBLK1))
+ ib_ptr))
return (0);
indirblk1 = nb;
}
bound /= UFS_NINDIR(SUPERBLOCK);
index = (bn / bound) % UFS_NINDIR(SUPERBLOCK);
- nb = INDIRBLK1[index];
+ if (FS_IS_UFS2)
+ nb = UFS2_INDIRBLK1[index];
+ else
+ nb = INDIRBLK1[index];
if (nb == 0)
- return ((grub_daddr32_t)0);
+ return ((int64_t)0);
}
-
return (nb);
}
@@ -232,19 +279,24 @@ dlook(fsi_file_t *ffi, grub_ino_t dir_ino, char *name)
int loc, off;
grub_daddr32_t lbn, dbn, dblk;
struct direct *dp;
+ int64_t size;
if ((INODE->ic_smode & IFMT) != IFDIR)
return 0;
loc = 0;
- while (loc < INODE->ic_sizelo) {
+ if (FS_IS_UFS2)
+ size = UFS2_INODE->di_size;
+ else
+ size = INODE->ic_sizelo;
+ while (loc < size) {
/* offset into block */
off = blkoff(SUPERBLOCK, loc);
if (off == 0) { /* need to read in a new block */
/* get logical block number */
lbn = lblkno(SUPERBLOCK, loc);
/* resolve indrect blocks */
- dbn = sbmap(ffi, lbn);
+ dbn = sbmap(ffi, lbn);
if (dbn == 0)
return (0);
diff --git a/tools/libfsimage/ufs/ufs.h b/tools/libfsimage/ufs/ufs.h
index 4e7c736..b250cca 100644
--- a/tools/libfsimage/ufs/ufs.h
+++ b/tools/libfsimage/ufs/ufs.h
@@ -2,17 +2,65 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+/*
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and Network Associates Laboratories, the Security
+ * Research Division of Network Associates, Inc. under DARPA/SPAWAR
+ * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
+ * research program
+ *
+ * Copyright (c) 1982, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * @(#)dinode.h 8.9 (Berkeley) 3/29/95
+ */
#ifndef _GRUB_UFS_H
#define _GRUB_UFS_H_
/* ufs specific constants */
#define UFS_SBLOCK 16
+#define UFS2_SBLOCK (65536 / 512)
+#define UFS2_PIGGY 262144
#define UFS_SBSIZE 8192
#define UFS_MAGIC 0x011954
+#define UFS2_MAGIC 0x19540119
#define ROOTINO 2 /* i number of all roots */
#define UFS_NDADDR 12 /* direct blocks */
#define UFS_NIADDR 3 /* indirect blocks */
+#define UFS_NXADDR 2
#define MAXMNTLEN 512
#define MAXCSBUFS 32
#define MAXNAMELEN 256
@@ -173,6 +221,33 @@ struct fs {
grub_uchar_t fs_space[1]; /* list of blocks for each rotation */
/* actually longer */
};
+/* UFS2 on-disk format */
+struct ufs2_dinode {
+ u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
+ int16_t di_nlink; /* 2: File link count. */
+ u_int32_t di_uid; /* 4: File owner. */
+ u_int32_t di_gid; /* 8: File group. */
+ u_int32_t di_blksize; /* 12: Inode blocksize. */
+ u_int64_t di_size; /* 16: File byte count. */
+ u_int64_t di_blocks; /* 24: Bytes actually held. */
+ int64_t di_atime; /* 32: Last access time. */
+ int64_t di_mtime; /* 40: Last modified time. */
+ int64_t di_ctime; /* 48: Last inode change time. */
+ int64_t di_birthtime; /* 56: Inode creation time. */
+ int32_t di_mtimensec; /* 64: Last modified time. */
+ int32_t di_atimensec; /* 68: Last access time. */
+ int32_t di_ctimensec; /* 72: Last inode change time. */
+ int32_t di_birthnsec; /* 76: Inode creation time. */
+ int32_t di_gen; /* 80: Generation number. */
+ u_int32_t di_kernflags; /* 84: Kernel flags. */
+ u_int32_t di_flags; /* 88: Status flags (chflags). */
+ int32_t di_extsize; /* 92: External attributes block. */
+ int64_t di_extb[UFS_NXADDR];/* 96: External attributes block. */
+ int64_t di_db[UFS_NDADDR]; /* 112: Direct disk blocks. */
+ int64_t di_ib[UFS_NIADDR]; /* 208: Indirect disk blocks. */
+ u_int64_t di_modrev; /* 232: i_modrev for NFSv4 */
+ int64_t di_spare[2]; /* 240: Reserved; currently unused */
+};
struct icommon {
grub_o_mode_t ic_smode; /* 0: mode and type of file */
@@ -214,15 +289,18 @@ struct direct {
/* block conversion macros */
#define UFS_NINDIR(fs) ((fs)->fs_nindir) /* # of indirects */
#define blkoff(fs, loc) ((int)((loc & ~(fs)->fs_bmask)))
+#define ufs2_blkoff(fs, loc) ((int64_t)(loc & *((int64_t
*)(&((fs)->fs_qbmask)))))
#define lblkno(fs, loc) ((grub_int32_t)((loc) >> (fs)->fs_bshift))
/* frag to blk */
-#define fsbtodb(fs, b) (((grub_daddr32_t)(b)) << (fs)->fs_fsbtodb)
+#define fsbtodb(fs, b) (((b)) << (fs)->fs_fsbtodb)
#define blkstofrags(fs, b) ((b) << (fs)->fs_fragshift)
/* cynlinder group macros */
#define cgbase(fs, c) ((grub_daddr32_t)((fs)->fs_fpg * (c)))
#define cgimin(fs, c) (cgstart(fs, c) + (fs)->fs_iblkno) /* inode
block */
-#define cgstart(fs, c) \
+#define cgstart(fs, c) ((fs)->fs_magic == UFS2_MAGIC \
+ ?
cgstart_ufs2((fs),(c)) : cgstart_ufs1((fs),(c)))
+#define cgstart_ufs1(fs, c) \
(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
-
+#define cgstart_ufs2(fs, c) cgbase((fs), (c))
#endif /* !_GRUB_UFS_H */
diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub
old mode 100644
new mode 100755
index 363fbc7..2c618be
--- a/tools/pygrub/src/pygrub
+++ b/tools/pygrub/src/pygrub
@@ -80,7 +80,85 @@ def get_solaris_slice(file, offset):
if slicetag == V_ROOT:
return slicesect * SECTOR_SIZE
- raise RuntimeError, "No root slice found"
+ raise RuntimeError, "No root slice found"
+
+
+NETBSD_DISKLABEL_MAGIC=0x82564557
+NETBSD_DISKLABEL_MAXPARTITIONS=22
+NETBSD_FSTYPE_UNUSED, NETBSD_FSTYPE_SWAP, NETBSD_FSTYPE_BSDFFS = 0, 1, 7
+
+from collections import namedtuple
+NBDisklabel = namedtuple("NBDisklabel", '\
+ d_magic \
+ d_type \
+ d_subtype \
+ d_typename \
+ d_un \
+ d_un_pad \
+ d_secsize \
+ d_nsectors \
+ d_ntracks \
+ d_ncylinders \
+ d_secpercyl \
+ d_secperunit \
+ d_sparespertrack \
+ d_sparespercyl \
+ d_acylinders \
+ d_rpm \
+ d_interleave \
+ d_trackskew \
+ d_cylskew \
+ d_headswitch \
+ d_trkseek \
+ d_flags \
+ d_drivedata0 \
+ d_drivedata1 \
+ d_drivedata2 \
+ d_drivedata3 \
+ d_drivedata4 \
+ d_spare0 \
+ d_spare1 \
+ d_spare2 \
+ d_spare3 \
+ d_spare4 \
+ d_magic2 \
+ d_checksum \
+ d_npartitions \
+ d_bbsize \
+ d_sbsize')
+NBPartition = namedtuple("NBPartition", '\
+ p_size \
+ p_offset \
+ p_u2_fsize_cdsession \
+ p_fstype \
+ p_frag \
+ p_u1_cpg_sgs')
+def get_netbsd_partition(file, offset):
+ """find the root partion in a NetBSD disklabel"""
+ #see sys/sys/disklabel.h
+ struct_partition="<IIIBBH"
+ struct_disklabel="<IHH16sQQIIIIIIHHIHHHHIII5I5IIHHII"
+ dkl_size = struct.calcsize(struct_disklabel)
+ part_size = struct.calcsize(struct_partition)
+
+ fd=os.open(file, os.O_RDONLY)
+ os.lseek(fd, offset + SECTOR_SIZE, 0)
+ buf = os.read(fd, SECTOR_SIZE)
+ os.close(fd)
+
+ rawdat = struct.unpack(struct_disklabel, buf[0 : dkl_size])
+ dkl = NBDisklabel._make(rawdat)
+ if dkl.d_magic != NETBSD_DISKLABEL_MAGIC \
+ or dkl.d_magic2 != NETBSD_DISKLABEL_MAGIC:
+ raise RuntimeError, "Invalid NetBSD disklabel magic"
+ for i in range(dkl.d_npartitions):
+ part_off = dkl_size + i * part_size
+ rawdat = struct.unpack(struct_partition, buf[part_off : part_off +
part_size])
+ part = NBPartition._make(rawdat)
+ if part.p_fstype == NETBSD_FSTYPE_BSDFFS and part.p_size > 0:
+ if part.p_size > dkl.d_secperunit:
+ print "get_netbsd_partition: warning: # of partition sectors
exceeds disklabel sectors"
+ return part.p_offset * dkl.d_secsize
def get_fs_offset_gpt(file):
fd = os.open(file, os.O_RDONLY)
@@ -100,13 +178,26 @@ def get_fs_offset_gpt(file):
FDISK_PART_SOLARIS=0xbf
FDISK_PART_SOLARIS_OLD=0x82
FDISK_PART_GPT=0xee
+FDISK_PART_NETBSD=0xa9
def get_partition_offsets(file):
image_type = identify_disk_image(file)
if image_type == DISK_TYPE_RAW:
- # No MBR: assume whole disk filesystem, which is like a
+ # No MBR: assume whole disk filesystem, which is like a
# single partition starting at 0
- return [0]
+ try:
+ # NetBSD 6.1 doesn't bother to add a valid MBR, check if there's a
disklabel
+ # in the second sector
+ fd=os.open(file, os.O_RDONLY)
+ os.lseek(fd, SECTOR_SIZE, 0)
+ buf = os.read(fd, SECTOR_SIZE)
+ os.close(fd)
+ dkl_magic = struct.unpack("<L", buf[0:4])[0]
+ if dkl_magic != NETBSD_DISKLABEL_MAGIC:
+ raise
+ return [ get_netbsd_partition(file, 0)]
+ except:
+ return [0]
elif image_type == DISK_TYPE_HYBRIDISO:
# A HybridISO contains an ISO filesystem at 0 in addition
# to the DOS partition table
@@ -114,7 +205,7 @@ def get_partition_offsets(file):
elif image_type == DISK_TYPE_DOS:
part_offs = []
else:
- raise ValueError('Unhandled image type returnd by
identify_disk_image(): %d' % (image_type,))
+ raise ValueError('Unhandled image type returned by
identify_disk_image(): %d' % (image_type,))
fd = os.open(file, os.O_RDONLY)
buf = os.read(fd, 512)
@@ -136,6 +227,11 @@ def get_partition_offsets(file):
except RuntimeError:
continue # no solaris magic at that offset, ignore partition
+ if type == FDISK_PART_NETBSD:
+ try:
+ offset = get_netbsd_partition(file, offset)
+ except RuntimeError:
+ continue # ignore partition
if type == FDISK_PART_GPT:
for offset in get_fs_offset_gpt(file):
part_offs.append(offset)
@@ -690,6 +786,82 @@ def sniff_netware(fs, cfg):
cfg["kernel"] = "/nwserver/xnloader.sys"
return cfg
+def netbsd_parse_bootcfg(cfgbuf, cfg):
+ """ parse NetBSD's boot.cfg and return a dictionary with appropriate keys:
kernel, ramdisk and args """
+ lines = cfgbuf.split("\n")
+ kernel=""
+ args=""
+ ramdisk=""
+ menus=[]
+ default=None
+
+ for l in lines:
+ l = l.strip()
+ if len(l) > 0:
+ #ignore comments
+ if l.startswith('#'):
+ continue
+ entry = l.split("=", 1)
+ #new menu entry
+ if entry[0] == "menu":
+ text_cmds = entry[1].split(":")
+ cmds = text_cmds[1]
+ menus.append(cmds)
+ #default menu entry
+ if entry[0] == "default":
+ default = int(entry[1].strip())
+ #always load given kernel module
+ if entry[0] == "load":
+ ramdisk = entry[1].strip()
+ if default is None:
+ return False
+
+ cmds = menus[default - 1]
+ #parse the default boot command sequence
+ for c in cmds.split(";"):
+ #e.g.: boot -as, or netbsd -12s
+ if c.startswith("boot"):
+ boot_args = c.replace("boot", '', 1).strip()
+ for arg in boot_args.split(" "):
+ if arg.startswith("-"):
+ args += arg + " "
+ else:
+ kernel = arg
+ if c.startswith("load"):
+ ramdisk = c.replace("load", '', 1).strip()
+ if kernel != "":
+ cfg["kernel"] = kernel
+ if ramdisk != "":
+ cfg["ramdisk"] = ramdisk
+ if args != "":
+ #XXX we need to keep root=xbd0a
+ cfg["args"] += " " + args
+ return True
+
+def sniff_netbsd(fs, cfg):
+ default_kernel="/netbsd"
+ default_args="root=xbd0 " #XXX should we get this from the MBR/disklabel ?
+ if not fs.file_exists("/boot.cfg"):
+ if not fs.file_exists("/netbsd"):
+ return cfg
+ cfg["kernel"] = default_kernel
+ cfg["args"] = default_args
+ return cfg
+ else:
+ cfg["kernel"] = default_kernel
+ cfg["args"] = default_args
+ bootf = fs.open_file("/boot.cfg")
+ offset = 0
+ boot_cfg = ""
+ while True:
+ buf = bootf.read(FS_READ_MAX, offset)
+ if len(buf) == 0:
+ del bootf
+ break
+ offset += len(buf)
+ boot_cfg += buf
+ cfg_ok = netbsd_parse_bootcfg(boot_cfg, cfg)
+ return cfg
def format_sxp(kernel, ramdisk, args):
s = "linux (kernel %s)" % kernel
@@ -858,6 +1030,9 @@ if __name__ == "__main__":
chosencfg = sniff_solaris(fs, incfg)
if not chosencfg["kernel"]:
+ chosencfg = sniff_netbsd(fs, incfg)
+
+ if not chosencfg["kernel"]:
chosencfg = sniff_netware(fs, incfg)
if not chosencfg["kernel"]:
Home |
Main Index |
Thread Index |
Old Index