mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-29 08:08:37 +00:00
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
This commit is contained in:
parent
9361c4ad4e
commit
cdd2df880d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=341067
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user