Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Jun 2010 22:25:50 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r209077 - in stable/8: sbin/geom/class/part sys/sys
Message-ID:  <201006112225.o5BMPobc008092@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Fri Jun 11 22:25:50 2010
New Revision: 209077
URL: http://svn.freebsd.org/changeset/base/209077

Log:
  MFC: r208777
  
  - In gpart_bootfile_read() fix an off-by-one error preventing the bootstrap
    file to be of maximum size.
  - Add special handling required for SMI/VTOC8 disklabel partcode, i.e. avoid
    overwriting the label when writing the bootstrap code to the partition
    starting at 0 and install it to all partitions when the -i option is omitted
    just like geom_sunlabel(4) and sunlabel(8) do by default.
  - Add missing prototypes.
  - Add const where applicable.
  
  Reviewed by:	marcel
  Approved by:	re (kib)

Modified:
  stable/8/sbin/geom/class/part/geom_part.c
  stable/8/sys/sys/vtoc.h
Directory Properties:
  stable/8/sbin/geom/class/part/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/geom/sched/   (props changed)

Modified: stable/8/sbin/geom/class/part/geom_part.c
==============================================================================
--- stable/8/sbin/geom/class/part/geom_part.c	Fri Jun 11 22:01:58 2010	(r209076)
+++ stable/8/sbin/geom/class/part/geom_part.c	Fri Jun 11 22:25:50 2010	(r209077)
@@ -28,6 +28,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/stat.h>
+#include <sys/vtoc.h>
 
 #include <assert.h>
 #include <err.h>
@@ -59,13 +60,27 @@ static char autofill[] = "*";
 static char optional[] = "";
 static char flags[] = "C";
 
-static char bootcode_param[] = "bootcode";
-static char index_param[] = "index";
-static char partcode_param[] = "partcode";
-
+static const char const bootcode_param[] = "bootcode";
+static const char const index_param[] = "index";
+static const char const partcode_param[] = "partcode";
+
+static struct gclass *find_class(struct gmesh *, const char *);
+static struct ggeom * find_geom(struct gclass *, const char *);
+static const char *find_geomcfg(struct ggeom *, const char *);
+static const char *find_provcfg(struct gprovider *, const char *);
+static struct gprovider *find_provider(struct ggeom *,
+    unsigned long long);
+static const char *fmtsize(int64_t);
+static int gpart_autofill(struct gctl_req *);
+static int gpart_autofill_resize(struct gctl_req *);
 static void gpart_bootcode(struct gctl_req *, unsigned int);
+static void *gpart_bootfile_read(const char *, ssize_t *);
 static void gpart_issue(struct gctl_req *, unsigned int);
 static void gpart_show(struct gctl_req *, unsigned int);
+static void gpart_show_geom(struct ggeom *, const char *);
+static int gpart_show_hasopt(struct gctl_req *, const char *, const char *);
+static void gpart_write_partcode(struct ggeom *, int, void *, ssize_t);
+static void gpart_write_partcode_vtoc8(struct ggeom *, int, void *);
 
 struct g_command PUBSYM(class_commands)[] = {
 	{ "add", 0, gpart_issue, {
@@ -132,7 +147,7 @@ struct g_command PUBSYM(class_commands)[
 		{ 'f', "flags", flags, G_TYPE_STRING },
 		G_OPT_SENTINEL },
 	  "geom", NULL
-        },
+	},
 	G_CMD_SENTINEL
 };
 
@@ -502,7 +517,7 @@ gpart_bootfile_read(const char *bootfile
 		errx(EXIT_FAILURE, "%s: not a regular file", bootfile);
 	if (sb.st_size == 0)
 		errx(EXIT_FAILURE, "%s: empty file", bootfile);
-	if (*size > 0 && sb.st_size >= *size)
+	if (*size > 0 && sb.st_size > *size)
 		errx(EXIT_FAILURE, "%s: file too big (%zu limit)", bootfile,
 		    *size);
 
@@ -522,35 +537,14 @@ gpart_bootfile_read(const char *bootfile
 }
 
 static void
-gpart_write_partcode(struct gctl_req *req, int idx, void *code, ssize_t size)
+gpart_write_partcode(struct ggeom *gp, int idx, void *code, ssize_t size)
 {
 	char dsf[128];
-	struct gmesh mesh;
-	struct gclass *classp;
-	struct ggeom *gp;
 	struct gprovider *pp;
 	const char *s;
 	char *buf;
 	off_t bsize;
-	int error, fd;
-
-	s = gctl_get_ascii(req, "class");
-	if (s == NULL)
-		abort();
-	error = geom_gettree(&mesh);
-	if (error != 0)
-		errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
-	classp = find_class(&mesh, s);
-	if (classp == NULL) {
-		geom_deletetree(&mesh);
-		errx(EXIT_FAILURE, "Class %s not found.", s);
-	}
-	s = gctl_get_ascii(req, "geom");
-	if (s == NULL)
-		abort();
-	gp = find_geom(classp, s);
-	if (gp == NULL)
-		errx(EXIT_FAILURE, "No such geom: %s.", s);
+	int fd;
 
 	LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
 		s = find_provcfg(pp, "index");
@@ -587,18 +581,63 @@ gpart_write_partcode(struct gctl_req *re
 		close(fd);
 	} else
 		errx(EXIT_FAILURE, "invalid partition index");
+}
 
-	geom_deletetree(&mesh);
+static void
+gpart_write_partcode_vtoc8(struct ggeom *gp, int idx, void *code)
+{
+	char dsf[128];
+	struct gprovider *pp;
+	const char *s;
+	int installed, fd;
+
+	installed = 0;
+	LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+		s = find_provcfg(pp, "index");
+		if (s == NULL)
+			continue;
+		if (idx != 0 && atoi(s) != idx)
+			continue;
+		snprintf(dsf, sizeof(dsf), "/dev/%s", pp->lg_name);
+		if (pp->lg_sectorsize != sizeof(struct vtoc8))
+			errx(EXIT_FAILURE, "%s: unexpected sector "
+			    "size (%d)\n", dsf, pp->lg_sectorsize);
+		fd = open(dsf, O_WRONLY);
+		if (fd == -1)
+			err(EXIT_FAILURE, "%s", dsf);
+		if (lseek(fd, VTOC_BOOTSIZE, SEEK_SET) != VTOC_BOOTSIZE)
+			continue;
+		/*
+		 * We ignore the first VTOC_BOOTSIZE bytes of boot code in
+		 * order to avoid overwriting the label.
+		 */
+		if (lseek(fd, sizeof(struct vtoc8), SEEK_SET) !=
+		    sizeof(struct vtoc8))
+			err(EXIT_FAILURE, "%s", dsf);
+		if (write(fd, (caddr_t)code + sizeof(struct vtoc8),
+		    VTOC_BOOTSIZE - sizeof(struct vtoc8)) != VTOC_BOOTSIZE -
+		    sizeof(struct vtoc8))
+			err(EXIT_FAILURE, "%s", dsf);
+		installed++;
+		close(fd);
+		if (idx != 0 && atoi(s) == idx)
+			break;
+	}
+	if (installed == 0)
+		errx(EXIT_FAILURE, "%s: no partitions", gp->lg_name);
 }
 
 static void
 gpart_bootcode(struct gctl_req *req, unsigned int fl)
 {
+	struct gmesh mesh;
+	struct gclass *classp;
+	struct ggeom *gp;
 	const char *s;
 	char *sp;
 	void *bootcode, *partcode;
 	size_t bootsize, partsize;
-	int error, idx;
+	int error, idx, vtoc8;
 
 	if (gctl_has_param(req, bootcode_param)) {
 		s = gctl_get_ascii(req, bootcode_param);
@@ -613,9 +652,31 @@ gpart_bootcode(struct gctl_req *req, uns
 		bootsize = 0;
 	}
 
+	s = gctl_get_ascii(req, "class");
+	if (s == NULL)
+		abort();
+	error = geom_gettree(&mesh);
+	if (error != 0)
+		errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
+	classp = find_class(&mesh, s);
+	if (classp == NULL) {
+		geom_deletetree(&mesh);
+		errx(EXIT_FAILURE, "Class %s not found.", s);
+	}
+	s = gctl_get_ascii(req, "geom");
+	if (s == NULL)
+		abort();
+	gp = find_geom(classp, s);
+	if (gp == NULL)
+		errx(EXIT_FAILURE, "No such geom: %s.", s);
+	s = find_geomcfg(gp, "scheme");
+	vtoc8 = 0;
+	if (strcmp(s, "VTOC8") == 0)
+		vtoc8 = 1;
+
 	if (gctl_has_param(req, partcode_param)) {
 		s = gctl_get_ascii(req, partcode_param);
-		partsize = bootsize * 1024;
+		partsize = vtoc8 != 0 ? VTOC_BOOTSIZE : bootsize * 1024;
 		partcode = gpart_bootfile_read(s, &partsize);
 		error = gctl_delete_param(req, partcode_param);
 		if (error)
@@ -639,16 +700,20 @@ gpart_bootcode(struct gctl_req *req, uns
 		idx = 0;
 
 	if (partcode != NULL) {
-		if (idx == 0)
-			errx(EXIT_FAILURE, "missing -i option");
-		gpart_write_partcode(req, idx, partcode, partsize);
-	} else {
+		if (vtoc8 == 0) {
+			if (idx == 0)
+				errx(EXIT_FAILURE, "missing -i option");
+			gpart_write_partcode(gp, idx, partcode, partsize);
+		} else
+			gpart_write_partcode_vtoc8(gp, idx, partcode);
+	} else
 		if (bootcode == NULL)
 			errx(EXIT_FAILURE, "no -b nor -p");
-	}
 
 	if (bootcode != NULL)
 		gpart_issue(req, fl);
+
+	geom_deletetree(&mesh);
 }
 
 static void

Modified: stable/8/sys/sys/vtoc.h
==============================================================================
--- stable/8/sys/sys/vtoc.h	Fri Jun 11 22:01:58 2010	(r209076)
+++ stable/8/sys/sys/vtoc.h	Fri Jun 11 22:25:50 2010	(r209077)
@@ -53,9 +53,10 @@
 #define	VTOC_TAG_FREEBSD_ZFS	0x0904
 
 #define	VTOC_FLAG_UNMNT		0x01	/* unmountable partition */
-#define VTOC_FLAG_RDONLY	0x10    /* partition is read/only */
+#define	VTOC_FLAG_RDONLY	0x10    /* partition is read/only */
 
 #define	VTOC_ASCII_LEN	128
+#define	VTOC_BOOTSIZE	8192		/* 16 sectors */
 #define	VTOC_MAGIC	0xdabe
 #define	VTOC_RAW_PART	2
 #define	VTOC_SANITY	0x600ddeee



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006112225.o5BMPobc008092>