aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2018-11-27 14:58:19 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2018-11-27 14:58:19 +0000
commitcdd2df880d0a7796608acc93d68c38cef9818a8d (patch)
tree2de4f693a6d30f0f7e9fa5d628b31d7bcc46c678
parent9361c4ad4e909cc8756294f99f128df7a41b9a5d (diff)
downloadsrc-cdd2df880d0a7796608acc93d68c38cef9818a8d.tar.gz
src-cdd2df880d0a7796608acc93d68c38cef9818a8d.zip
Add a “skip_dsn” option to g_part's bootcode verb to prevent g_part_mbr
from setting the volume serial number. This unbreaks older boot blocks that don't support serial numbers, and allows boot0cfg to set the serial number itself if requested by the user. Submitted by: lev@, yuripv@ MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D17386
Notes
Notes: svn path=/head/; revision=341067
-rw-r--r--lib/geom/part/geom_part.c4
-rw-r--r--lib/geom/part/gpart.89
-rw-r--r--sys/geom/part/g_part.c7
-rw-r--r--sys/geom/part/g_part.h2
-rw-r--r--sys/geom/part/g_part_mbr.c2
-rw-r--r--usr.sbin/boot0cfg/boot0cfg.c12
6 files changed, 30 insertions, 6 deletions
diff --git a/lib/geom/part/geom_part.c b/lib/geom/part/geom_part.c
index 29c066c4714f..b21ebf7ef8d8 100644
--- a/lib/geom/part/geom_part.c
+++ b/lib/geom/part/geom_part.c
@@ -72,6 +72,7 @@ volatile sig_atomic_t undo_restore;
#define GPART_PARAM_BOOTCODE "bootcode"
#define GPART_PARAM_INDEX "index"
#define GPART_PARAM_PARTCODE "partcode"
+#define GPART_PARAM_SKIP_DSN "skip_dsn"
static struct gclass *find_class(struct gmesh *, const char *);
static struct ggeom * find_geom(struct gclass *, const char *);
@@ -115,8 +116,9 @@ struct g_command PUBSYM(class_commands)[] = {
{ 'p', GPART_PARAM_PARTCODE, G_VAL_OPTIONAL, G_TYPE_STRING },
{ 'i', GPART_PARAM_INDEX, G_VAL_OPTIONAL, G_TYPE_NUMBER },
{ 'f', "flags", GPART_FLAGS, G_TYPE_STRING },
+ { 'N', GPART_PARAM_SKIP_DSN, NULL, G_TYPE_BOOL },
G_OPT_SENTINEL },
- "[-b bootcode] [-p partcode -i index] [-f flags] geom"
+ "[-N] [-b bootcode] [-p partcode -i index] [-f flags] geom"
},
{ "commit", 0, gpart_issue, G_NULL_OPTS,
"geom"
diff --git a/lib/geom/part/gpart.8 b/lib/geom/part/gpart.8
index 76177892ceb1..80ea0a317d3a 100644
--- a/lib/geom/part/gpart.8
+++ b/lib/geom/part/gpart.8
@@ -49,6 +49,7 @@
.\" ==== BOOTCODE ====
.Nm
.Cm bootcode
+.Op Fl N
.Op Fl b Ar bootcode
.Op Fl p Ar partcode Fl i Ar index
.Op Fl f Ar flags
@@ -214,6 +215,14 @@ The
.Cm bootcode
command accepts these options:
.Bl -tag -width 10n
+.It Fl N
+Don't preserve the Volume Serial Number for MBR.
+MBR bootcode contains Volume Serial Number by default, and
+.Nm
+tries to preserve it when installing new bootstrap code.
+This option allows to skip the preservation to help with some versions of
+.Xr boot0 8
+that don't support Volume Serial Number.
.It Fl b Ar bootcode
Embed bootstrap code from the file
.Ar bootcode
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c
index 0148f4ebb740..3b8fe3916aec 100644
--- a/sys/geom/part/g_part.c
+++ b/sys/geom/part/g_part.c
@@ -1627,6 +1627,7 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
if (!strcmp(verb, "bootcode")) {
ctlreq = G_PART_CTL_BOOTCODE;
mparms |= G_PART_PARM_GEOM | G_PART_PARM_BOOTCODE;
+ oparms |= G_PART_PARM_SKIP_DSN;
}
break;
case 'c':
@@ -1744,6 +1745,8 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
parm = G_PART_PARM_SIZE;
else if (!strcmp(ap->name, "start"))
parm = G_PART_PARM_START;
+ else if (!strcmp(ap->name, "skip_dsn"))
+ parm = G_PART_PARM_SKIP_DSN;
break;
case 't':
if (!strcmp(ap->name, "type"))
@@ -1804,6 +1807,10 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
case G_PART_PARM_SIZE:
error = g_part_parm_quad(req, ap->name, &gpp.gpp_size);
break;
+ case G_PART_PARM_SKIP_DSN:
+ error = g_part_parm_uint32(req, ap->name,
+ &gpp.gpp_skip_dsn);
+ break;
case G_PART_PARM_START:
error = g_part_parm_quad(req, ap->name,
&gpp.gpp_start);
diff --git a/sys/geom/part/g_part.h b/sys/geom/part/g_part.h
index acf318466bf8..6e9a9463ccc9 100644
--- a/sys/geom/part/g_part.h
+++ b/sys/geom/part/g_part.h
@@ -202,6 +202,7 @@ enum g_part_ctl {
#define G_PART_PARM_BOOTCODE 0x1000
#define G_PART_PARM_ATTRIB 0x2000
#define G_PART_PARM_FORCE 0x4000
+#define G_PART_PARM_SKIP_DSN 0x8000
struct g_part_parms {
unsigned int gpp_parms;
@@ -220,6 +221,7 @@ struct g_part_parms {
unsigned int gpp_codesize;
const char *gpp_attrib;
unsigned int gpp_force;
+ unsigned int gpp_skip_dsn;
};
void g_part_geometry_heads(off_t, u_int, off_t *, u_int *);
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 8b4da964367a..a442e25c94d0 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -274,7 +274,7 @@ g_part_mbr_bootcode(struct g_part_table *basetable, struct g_part_parms *gpp)
table = (struct g_part_mbr_table *)basetable;
dsn = *(uint32_t *)(table->mbr + DOSDSNOFF);
bcopy(gpp->gpp_codeptr, table->mbr, DOSPARTOFF);
- if (dsn != 0)
+ if (dsn != 0 && !gpp->gpp_skip_dsn)
*(uint32_t *)(table->mbr + DOSDSNOFF) = dsn;
return (0);
}
diff --git a/usr.sbin/boot0cfg/boot0cfg.c b/usr.sbin/boot0cfg/boot0cfg.c
index 501283d28471..f6f12c0bd58b 100644
--- a/usr.sbin/boot0cfg/boot0cfg.c
+++ b/usr.sbin/boot0cfg/boot0cfg.c
@@ -100,7 +100,7 @@ static const char fmt1[] = "%d 0x%02x %4u:%3u:%2u 0x%02x"
static int geom_class_available(const char *);
static int read_mbr(const char *, u_int8_t **, int);
-static void write_mbr(const char *, int, u_int8_t *, int);
+static void write_mbr(const char *, int, u_int8_t *, int, int);
static void display_mbr(u_int8_t *);
static int boot0version(const u_int8_t *);
static int boot0bs(const u_int8_t *);
@@ -200,7 +200,7 @@ main(int argc, char *argv[])
/* save the existing MBR if we are asked to do so */
if (fpath)
- write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size);
+ write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size, 0);
/*
* If we are installing the boot loader, read it from disk and copy the
@@ -256,7 +256,7 @@ main(int argc, char *argv[])
}
/* write the MBR back to disk */
if (up)
- write_mbr(disk, 0, boot0, boot0_size);
+ write_mbr(disk, 0, boot0, boot0_size, vol_id[4] || b0_ver == 1);
/* display the MBR */
if (v_flag)
@@ -372,7 +372,8 @@ geom_class_available(const char *name)
* Write out the mbr to the specified file.
*/
static void
-write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
+write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size,
+ int disable_dsn)
{
struct gctl_req *grq;
const char *errmsg;
@@ -417,6 +418,9 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size)
gctl_ro_param(grq, "verb", -1, "bootcode");
gctl_ro_param(grq, "bootcode", mbr_size, mbr);
gctl_ro_param(grq, "flags", -1, "C");
+ if (disable_dsn)
+ gctl_ro_param(grq, "skip_dsn", sizeof(int),
+ &disable_dsn);
errmsg = gctl_issue(grq);
if (errmsg != NULL && errmsg[0] != '\0')
errx(1, "GEOM_PART: write bootcode to %s failed: %s",