aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
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 /sys/geom
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
Diffstat (limited to 'sys/geom')
-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
3 files changed, 10 insertions, 1 deletions
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);
}