From 643f6b21a9179fc12913b959de6e7f8f7831347f Mon Sep 17 00:00:00 2001 From: ae Date: Wed, 16 Nov 2011 15:32:52 +0000 Subject: [PATCH] MFC r227231: To be in sync with GEOM_PART_BSD limit the maximum number of supported partitions to 20. MFC r227248: bsdlabel(8) could automatically fill many of disklabel's deprecated fields, but user could specify some of those fields when edits disklabel with `bsdlabel -e`. But without -A flag these fields might be overwritten with default values from the virgin disklabel. So, don't overwrite such fields if they are not zero. Also add checks to prevent creating disklabel with less than DEFPARTITIONS and more than MAXPARTITIONS partitions. PR: bin/162332 Tested by: Eugene Grosbein MFC r227262: Remove unneeded checks. MFC r227270: Add recommendation to use gpart(8) when user tries write disklabel or bootcode to already opened provider. MFC r227296: Fix multi-line comment formatting. Approved by: re (kib) git-svn-id: svn://svn.freebsd.org/base/releng/9.0@227557 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sbin/bsdlabel/bsdlabel.c | 69 ++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c index fbd978a1..ac83a41b 100644 --- a/sbin/bsdlabel/bsdlabel.c +++ b/sbin/bsdlabel/bsdlabel.c @@ -63,7 +63,7 @@ __FBSDID("$FreeBSD$"); #include #define DKTYPENAMES #define FSTYPENAMES -#define MAXPARTITIONS 26 +#define MAXPARTITIONS 20 #include #include @@ -80,7 +80,7 @@ __FBSDID("$FreeBSD$"); #include "pathnames.h" static void makelabel(const char *, struct disklabel *); -static int geom_bsd_available(void); +static int geom_class_available(const char *); static int writelabel(void); static int readlabel(int flag); static void display(FILE *, const struct disklabel *); @@ -355,7 +355,7 @@ readboot(void) } static int -geom_bsd_available(void) +geom_class_available(const char *name) { struct gclass *class; struct gmesh mesh; @@ -366,7 +366,7 @@ geom_bsd_available(void) errc(1, error, "Cannot get GEOM tree"); LIST_FOREACH(class, &mesh.lg_class, lg_class) { - if (strcmp(class->lg_name, "BSD") == 0) { + if (strcmp(class->lg_name, name) == 0) { geom_deletetree(&mesh); return (1); } @@ -411,8 +411,20 @@ writelabel(void) } else serrno = errno; + if (geom_class_available("PART") != 0) { + /* + * Since we weren't able open provider for + * writing, then recommend user to use gpart(8). + */ + warnc(serrno, + "cannot open provider %s for writing label", + specname); + warnx("Try to use gpart(8)."); + return (1); + } + /* Give up if GEOM_BSD is not available. */ - if (geom_bsd_available() == 0) { + if (geom_class_available("BSD") == 0) { warnc(serrno, "%s", specname); return (1); } @@ -831,11 +843,16 @@ getasciilabel(FILE *f, struct disklabel *lp) continue; } if (sscanf(cp, "%lu partitions", &v) == 1) { - if (v == 0 || v > MAXPARTITIONS) { + if (v > MAXPARTITIONS) { fprintf(stderr, "line %d: bad # of partitions\n", lineno); lp->d_npartitions = MAXPARTITIONS; errors++; + } else if (v < DEFPARTITIONS) { + fprintf(stderr, + "line %d: bad # of partitions\n", lineno); + lp->d_npartitions = DEFPARTITIONS; + errors++; } else lp->d_npartitions = v; continue; @@ -1149,23 +1166,41 @@ checklabel(struct disklabel *lp) errors++; } else if (lp->d_bbsize % lp->d_secsize) warnx("boot block size %% sector-size != 0"); - if (lp->d_npartitions > MAXPARTITIONS) + if (lp->d_npartitions > MAXPARTITIONS) { warnx("number of partitions (%lu) > MAXPARTITIONS (%d)", (u_long)lp->d_npartitions, MAXPARTITIONS); + errors++; + } + if (lp->d_npartitions < DEFPARTITIONS) { + warnx("number of partitions (%lu) < DEFPARTITIONS (%d)", + (u_long)lp->d_npartitions, DEFPARTITIONS); + errors++; + } } else { struct disklabel *vl; vl = getvirginlabel(); - lp->d_secsize = vl->d_secsize; - lp->d_nsectors = vl->d_nsectors; - lp->d_ntracks = vl->d_ntracks; - lp->d_ncylinders = vl->d_ncylinders; - lp->d_rpm = vl->d_rpm; - lp->d_interleave = vl->d_interleave; - lp->d_secpercyl = vl->d_secpercyl; - lp->d_secperunit = vl->d_secperunit; - lp->d_bbsize = vl->d_bbsize; - lp->d_npartitions = vl->d_npartitions; + if (lp->d_secsize == 0) + lp->d_secsize = vl->d_secsize; + if (lp->d_nsectors == 0) + lp->d_nsectors = vl->d_nsectors; + if (lp->d_ntracks == 0) + lp->d_ntracks = vl->d_ntracks; + if (lp->d_ncylinders == 0) + lp->d_ncylinders = vl->d_ncylinders; + if (lp->d_rpm == 0) + lp->d_rpm = vl->d_rpm; + if (lp->d_interleave == 0) + lp->d_interleave = vl->d_interleave; + if (lp->d_secpercyl == 0) + lp->d_secpercyl = vl->d_secpercyl; + if (lp->d_secperunit == 0) + lp->d_secperunit = vl->d_secperunit; + if (lp->d_bbsize == 0) + lp->d_bbsize = vl->d_bbsize; + if (lp->d_npartitions < DEFPARTITIONS || + lp->d_npartitions > MAXPARTITIONS) + lp->d_npartitions = vl->d_npartitions; } -- 2.42.0