From owner-svn-src-all@FreeBSD.ORG Fri Jun 11 22:25:51 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 11884106564A; Fri, 11 Jun 2010 22:25:51 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (unknown [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id F29B68FC16; Fri, 11 Jun 2010 22:25:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o5BMPoR7008095; Fri, 11 Jun 2010 22:25:50 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o5BMPobc008092; Fri, 11 Jun 2010 22:25:50 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201006112225.o5BMPobc008092@svn.freebsd.org> From: Marius Strobl Date: Fri, 11 Jun 2010 22:25:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r209077 - in stable/8: sbin/geom/class/part sys/sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jun 2010 22:25:51 -0000 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 +#include #include #include @@ -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