Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/installboot/arch Ensure we use the target disklabel...
details: https://anonhg.NetBSD.org/src/rev/409dea9cc1e9
branches: trunk
changeset: 555165:409dea9cc1e9
user: dsl <dsl%NetBSD.org@localhost>
date: Mon Nov 10 10:48:30 2003 +0000
description:
Ensure we use the target disklabel.h, not the host one.
Read the disklabel directly from sector 2 instead of using DIOCGDINFO.
Expect the label to be big-endian.
Support -o append for real files.
diffstat:
usr.sbin/installboot/arch/hp300.c | 139 +++++++++++++++++++------------------
1 files changed, 73 insertions(+), 66 deletions(-)
diffs (207 lines):
diff -r 8fccfd48dbab -r 409dea9cc1e9 usr.sbin/installboot/arch/hp300.c
--- a/usr.sbin/installboot/arch/hp300.c Mon Nov 10 09:22:09 2003 +0000
+++ b/usr.sbin/installboot/arch/hp300.c Mon Nov 10 10:48:30 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: hp300.c,v 1.2 2003/11/08 22:39:07 uwe Exp $ */
+/* $NetBSD: hp300.c,v 1.3 2003/11/10 10:48:30 dsl Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -42,10 +42,18 @@
#include <sys/cdefs.h>
#if !defined(__lint)
-__RCSID("$NetBSD: hp300.c,v 1.2 2003/11/08 22:39:07 uwe Exp $");
+__RCSID("$NetBSD: hp300.c,v 1.3 2003/11/10 10:48:30 dsl Exp $");
#endif /* !__lint */
+/* We need the target disklabel.h, not the hosts one..... */
+#ifdef HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#undef __HAVE_OLD_DISKLABEL /* host's <machine/types.h> may define this */
+#include "../../sys/arch/hp300/include/disklabel.h"
+#include "../../sys/sys/disklabel.h"
+#else
#include <sys/disklabel.h>
+#endif
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
@@ -63,23 +71,20 @@
#include "installboot.h"
#include "hp300_volhdr.h"
-#define nelem(x) (sizeof (x)/sizeof *(x))
-
int
hp300_setboot(ib_params *params)
{
int retval;
uint8_t *bootstrap;
ssize_t rv;
- struct disklabel label;
struct partition *boot;
struct hp300_lifdir *lifdir;
- char ch, *cp;
- int bootfd = -1;
int offset;
- int max_ptn;
int i;
- struct stat sb;
+ uint secsize;
+ uint64_t boot_size, boot_offset;
+ char label_buf[DEV_BSIZE];
+ struct disklabel *label = (void *)label_buf;
assert(params != NULL);
assert(params->fsfd != -1);
@@ -90,36 +95,59 @@
retval = 0;
bootstrap = MAP_FAILED;
- /* The bootstrap can be well over 8k, and must go into a BOOT ptn. */
- if (ioctl(params->fsfd, DIOCGDINFO, &label) != 0) {
- warn("reading disklabel");
- goto done;
- }
-
- max_ptn = label.d_npartitions;
- if (max_ptn > nelem(label.d_partitions))
- max_ptn = nelem(label.d_partitions);
- for (boot = label.d_partitions; ; boot++) {
- if (--max_ptn < 0) {
- warnx("No BOOT partition");
+ if (params->flags & IB_APPEND) {
+ if (!S_ISREG(params->fsstat.st_mode)) {
+ warnx(
+ "`%s' must be a regular file to append a bootstrap",
+ params->filesystem);
+ goto done;
+ }
+ boot_offset = roundup(params->fsstat.st_size, HP300_SECTSIZE);
+ } else {
+ /*
+ * The bootstrap can be well over 8k, and must go into a BOOT
+ * partition. Read NetBSD label to locate BOOT partition.
+ */
+ if (pread(params->fsfd, label, DEV_BSIZE, 2 * DEV_BSIZE)
+ != DEV_BSIZE) {
+ warn("reading disklabel");
+ goto done;
+ }
+ /* And a quick validation - must be a big-endian label */
+ secsize = be32toh(label->d_secsize);
+ if (label->d_magic != be32toh(DISKMAGIC) ||
+ label->d_magic2 != be32toh(DISKMAGIC) ||
+ secsize == 0 || secsize & (secsize - 1) ||
+ be32toh(label->d_npartitions) > MAXMAXPARTITIONS) {
+ warnx("Invalid disklabel in %s", params->filesystem);
goto done;
}
- if (boot->p_fstype == FS_BOOT)
- break;
- }
+
+ i = be32toh(label->d_npartitions);
+ for (boot = label->d_partitions; ; boot++) {
+ if (--i < 0) {
+ warnx("No BOOT partition");
+ goto done;
+ }
+ if (boot->p_fstype == FS_BOOT)
+ break;
+ }
+ boot_size = be32toh(boot->p_size) * (uint64_t)secsize;
+ boot_offset = be32toh(boot->p_offset) * (uint64_t)secsize;
- /*
- * We put the entire LIF file into the BOOT partition even when
- * it doesn't start at the beginning of the disk.
- *
- * Maybe we ought to be able to take a binary file and add
- * it to the LIF filesystem.
- */
- if (boot->p_size * label.d_secsize < params->s1stat.st_size) {
- warn("BOOT partition too small (%d < %lld)",
- boot->p_size * label.d_secsize,
- (long long int)params->s1stat.st_size);
- goto done;
+ /*
+ * We put the entire LIF file into the BOOT partition even when
+ * it doesn't start at the beginning of the disk.
+ *
+ * Maybe we ought to be able to take a binary file and add
+ * it to the LIF filesystem.
+ */
+ if (boot_size < params->s1stat.st_size) {
+ warn("BOOT partition too small (%llu < %llu)",
+ (unsigned long long)boot_size,
+ (unsigned long long)params->s1stat.st_size);
+ goto done;
+ }
}
bootstrap = mmap(NULL, params->s1stat.st_size, PROT_READ | PROT_WRITE,
@@ -139,29 +167,9 @@
i, addr + be32toh(lifdir->dir_length), limit);
goto done;
}
- if (addr != 0 && boot->p_offset != 0)
- lifdir->dir_addr = htobe32(addr + boot->p_offset
- * (label.d_secsize / HP300_SECTSIZE));
- }
-
- /* Open boot partition itself */
- cp = strchr(params->filesystem, 0) - 1;
- ch = *cp;
- *cp = 'a' + (boot - label.d_partitions);
- bootfd = open(params->filesystem,
- params->flags & IB_NOWRITE ? O_RDONLY : O_RDWR, 0);
- if (bootfd == -1) {
- warn("Cannot open BOOT partition %s", params->filesystem);
- *cp = ch;
- goto done;
- }
- *cp = ch;
-
- /* stat as a slight sanity check */
- if (fstat(bootfd, &sb) == -1
- || sb.st_size != boot->p_size * label.d_secsize) {
- warnx("Opened BOOT partition size doesn't match disklabel");
- goto done;
+ if (addr != 0 && boot_offset != 0)
+ lifdir->dir_addr = htobe32(addr + boot_offset
+ / HP300_SECTSIZE);
}
if (params->flags & IB_NOWRITE) {
@@ -180,15 +188,16 @@
}
/* Write files to BOOT partition */
- offset = boot->p_offset <= HP300_SECTSIZE * 16 / label.d_secsize
- ? HP300_SECTSIZE * 16 : 0;
- rv = pwrite(bootfd, bootstrap + offset, params->s1stat.st_size - offset, offset);
- if (rv != params->s1stat.st_size - offset) {
+ offset = boot_offset <= HP300_SECTSIZE * 16 ? HP300_SECTSIZE * 16 : 0;
+ i = params->s1stat.st_size - offset;
+ rv = pwrite(params->fsfd, bootstrap + offset, i, boot_offset + offset);
+ if (rv != i) {
if (rv == -1)
warn("Writing boot filesystem of `%s'",
params->filesystem);
else
- warnx("Writing boot filesystem of `%s': short write", params->filesystem);
+ warnx("Writing boot filesystem of `%s': short write",
+ params->filesystem);
goto done;
}
@@ -197,7 +206,5 @@
done:
if (bootstrap != MAP_FAILED)
munmap(bootstrap, params->s1stat.st_size);
- if (bootfd != -1)
- close(bootfd);
return retval;
}
Home |
Main Index |
Thread Index |
Old Index