From 6dea58b239501ec67cd62528890e95d3fa17c90a Mon Sep 17 00:00:00 2001 From: des Date: Tue, 27 Nov 2018 14:58:19 +0000 Subject: [PATCH] =?utf8?q?Add=20a=20=E2=80=9Cskip=5Fdsn=E2=80=9D=20option?= =?utf8?q?=20to=20g=5Fpart's=20bootcode=20verb=20to=20prevent=20g=5Fpart?= =?utf8?q?=5Fmbr=20from=20setting=20the=20volume=20serial=20number.=20=20T?= =?utf8?q?his=20unbreaks=20older=20boot=20blocks=20that=20don't=20support?= =?utf8?q?=20serial=20numbers,=20and=20allows=20boot0cfg=20to=20set=20the?= =?utf8?q?=20serial=20number=20itself=20if=20requested=20by=20the=20user.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Submitted by: lev@, yuripv@ MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D17386 --- lib/geom/part/geom_part.c | 4 +++- lib/geom/part/gpart.8 | 9 +++++++++ sys/geom/part/g_part.c | 7 +++++++ sys/geom/part/g_part.h | 2 ++ sys/geom/part/g_part_mbr.c | 2 +- usr.sbin/boot0cfg/boot0cfg.c | 12 ++++++++---- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/geom/part/geom_part.c b/lib/geom/part/geom_part.c index 29c066c4714..b21ebf7ef8d 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 76177892ceb..80ea0a317d3 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 0148f4ebb74..3b8fe3916ae 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 acf318466bf..6e9a9463ccc 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 8b4da964367..a442e25c94d 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 501283d2847..f6f12c0bd58 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", -- 2.45.0