Support mounted boot partitions in the installer. This allows the platform
layer, for example, to specify that the EFI boot partition should be mounted at /efi and formatted normally with newfs_msdos rather than splatted to from /boot/boot1.efifat. This commit adds only the API for this; actual platform use will come later.
This commit is contained in:
parent
92cef0bd26
commit
409ac0186b
@ -191,9 +191,7 @@ newfs_command(const char *fstype, char *command, int use_default)
|
|||||||
for (i = 0; i < (int)nitems(items); i++) {
|
for (i = 0; i < (int)nitems(items); i++) {
|
||||||
if (items[i].state == 0)
|
if (items[i].state == 0)
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(items[i].name, "FAT32") == 0)
|
if (strcmp(items[i].name, "FAT16") == 0)
|
||||||
strcat(command, "-F 32 ");
|
|
||||||
else if (strcmp(items[i].name, "FAT16") == 0)
|
|
||||||
strcat(command, "-F 16 ");
|
strcat(command, "-F 16 ");
|
||||||
else if (strcmp(items[i].name, "FAT12") == 0)
|
else if (strcmp(items[i].name, "FAT12") == 0)
|
||||||
strcat(command, "-F 12 ");
|
strcat(command, "-F 12 ");
|
||||||
@ -675,6 +673,7 @@ set_default_part_metadata(const char *name, const char *scheme,
|
|||||||
{
|
{
|
||||||
struct partition_metadata *md;
|
struct partition_metadata *md;
|
||||||
char *zpool_name = NULL;
|
char *zpool_name = NULL;
|
||||||
|
const char *default_bootmount = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Set part metadata */
|
/* Set part metadata */
|
||||||
@ -705,8 +704,12 @@ set_default_part_metadata(const char *name, const char *scheme,
|
|||||||
|
|
||||||
if (strcmp(type, "freebsd-swap") == 0)
|
if (strcmp(type, "freebsd-swap") == 0)
|
||||||
mountpoint = "none";
|
mountpoint = "none";
|
||||||
if (strcmp(type, bootpart_type(scheme)) == 0)
|
if (strcmp(type, bootpart_type(scheme, &default_bootmount)) == 0) {
|
||||||
md->bootcode = 1;
|
if (default_bootmount == NULL)
|
||||||
|
md->bootcode = 1;
|
||||||
|
else if (mountpoint == NULL || strlen(mountpoint) == 0)
|
||||||
|
mountpoint = default_bootmount;
|
||||||
|
}
|
||||||
|
|
||||||
/* VTOC8 needs partcode at the start of partitions */
|
/* VTOC8 needs partcode at the start of partitions */
|
||||||
if (strcmp(scheme, "VTOC8") == 0 && (strcmp(type, "freebsd-ufs") == 0
|
if (strcmp(scheme, "VTOC8") == 0 && (strcmp(type, "freebsd-ufs") == 0
|
||||||
@ -886,9 +889,79 @@ gpart_max_free(struct ggeom *geom, intmax_t *npartstart)
|
|||||||
return (maxsize);
|
return (maxsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
add_boot_partition(struct ggeom *geom, struct gprovider *pp,
|
||||||
|
const char *scheme, int interactive)
|
||||||
|
{
|
||||||
|
struct gconfig *gc;
|
||||||
|
struct gprovider *ppi;
|
||||||
|
int choice;
|
||||||
|
|
||||||
|
/* Check for existing freebsd-boot partition */
|
||||||
|
LIST_FOREACH(ppi, &geom->lg_provider, lg_provider) {
|
||||||
|
struct partition_metadata *md;
|
||||||
|
const char *bootmount = NULL;
|
||||||
|
|
||||||
|
LIST_FOREACH(gc, &ppi->lg_config, lg_config)
|
||||||
|
if (strcmp(gc->lg_name, "type") == 0)
|
||||||
|
break;
|
||||||
|
if (gc == NULL)
|
||||||
|
continue;
|
||||||
|
if (strcmp(gc->lg_val, bootpart_type(scheme, &bootmount)) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the boot partition is not mountable and needs partcode,
|
||||||
|
* but doesn't have it, it doesn't satisfy our requirements.
|
||||||
|
*/
|
||||||
|
md = get_part_metadata(ppi->lg_name, 0);
|
||||||
|
if (bootmount == NULL && (md == NULL || !md->bootcode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If it is mountable, but mounted somewhere else, remount */
|
||||||
|
if (bootmount != NULL && md != NULL && md->fstab != NULL
|
||||||
|
&& strlen(md->fstab->fs_file) > 0
|
||||||
|
&& strcmp(md->fstab->fs_file, bootmount) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* If it is mountable, but mountpoint is not set, mount it */
|
||||||
|
if (bootmount != NULL && md == NULL)
|
||||||
|
set_default_part_metadata(ppi->lg_name, scheme,
|
||||||
|
gc->lg_val, bootmount, NULL);
|
||||||
|
|
||||||
|
/* Looks good at this point, no added data needed */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interactive)
|
||||||
|
choice = dialog_yesno("Boot Partition",
|
||||||
|
"This partition scheme requires a boot partition "
|
||||||
|
"for the disk to be bootable. Would you like to "
|
||||||
|
"make one now?", 0, 0);
|
||||||
|
else
|
||||||
|
choice = 0;
|
||||||
|
|
||||||
|
if (choice == 0) { /* yes */
|
||||||
|
const char *bootmount = NULL;
|
||||||
|
char sizestr[7];
|
||||||
|
|
||||||
|
humanize_number(sizestr, 7,
|
||||||
|
bootpart_size(scheme), "B", HN_AUTOSCALE,
|
||||||
|
HN_NOSPACE | HN_DECIMAL);
|
||||||
|
|
||||||
|
gpart_create(pp, bootpart_type(scheme, &bootmount),
|
||||||
|
sizestr, bootmount, NULL, 0);
|
||||||
|
|
||||||
|
return (bootpart_size(scheme));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpart_create(struct gprovider *pp, char *default_type, char *default_size,
|
gpart_create(struct gprovider *pp, const char *default_type,
|
||||||
char *default_mountpoint, char **partname, int interactive)
|
const char *default_size, const char *default_mountpoint,
|
||||||
|
char **partname, int interactive)
|
||||||
{
|
{
|
||||||
struct gctl_req *r;
|
struct gctl_req *r;
|
||||||
struct gconfig *gc;
|
struct gconfig *gc;
|
||||||
@ -984,11 +1057,11 @@ gpart_create(struct gprovider *pp, char *default_type, char *default_size,
|
|||||||
nitems = scheme_supports_labels(scheme) ? 4 : 3;
|
nitems = scheme_supports_labels(scheme) ? 4 : 3;
|
||||||
|
|
||||||
if (default_type != NULL)
|
if (default_type != NULL)
|
||||||
items[0].text = default_type;
|
items[0].text = (char *)default_type;
|
||||||
if (default_size != NULL)
|
if (default_size != NULL)
|
||||||
items[1].text = default_size;
|
items[1].text = (char *)default_size;
|
||||||
if (default_mountpoint != NULL)
|
if (default_mountpoint != NULL)
|
||||||
items[2].text = default_mountpoint;
|
items[2].text = (char *)default_mountpoint;
|
||||||
|
|
||||||
/* Default options */
|
/* Default options */
|
||||||
strncpy(options_fstype, items[0].text,
|
strncpy(options_fstype, items[0].text,
|
||||||
@ -1105,61 +1178,21 @@ gpart_create(struct gprovider *pp, char *default_type, char *default_size,
|
|||||||
* the user to add one.
|
* the user to add one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Check for existing freebsd-boot partition */
|
|
||||||
LIST_FOREACH(pp, &geom->lg_provider, lg_provider) {
|
|
||||||
struct partition_metadata *md;
|
|
||||||
md = get_part_metadata(pp->lg_name, 0);
|
|
||||||
if (md == NULL || !md->bootcode)
|
|
||||||
continue;
|
|
||||||
LIST_FOREACH(gc, &pp->lg_config, lg_config)
|
|
||||||
if (strcmp(gc->lg_name, "type") == 0)
|
|
||||||
break;
|
|
||||||
if (gc != NULL && strcmp(gc->lg_val,
|
|
||||||
bootpart_type(scheme)) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there isn't one, and we need one, ask */
|
|
||||||
if ((strcmp(items[0].text, "freebsd") == 0 ||
|
if ((strcmp(items[0].text, "freebsd") == 0 ||
|
||||||
strcmp(items[2].text, "/") == 0) && bootpart_size(scheme) > 0 &&
|
strcmp(items[2].text, "/") == 0) && bootpart_size(scheme) > 0) {
|
||||||
pp == NULL) {
|
size_t bytes = add_boot_partition(geom, pp, scheme,
|
||||||
if (interactive)
|
interactive);
|
||||||
choice = dialog_yesno("Boot Partition",
|
|
||||||
"This partition scheme requires a boot partition "
|
|
||||||
"for the disk to be bootable. Would you like to "
|
|
||||||
"make one now?", 0, 0);
|
|
||||||
else
|
|
||||||
choice = 0;
|
|
||||||
|
|
||||||
if (choice == 0) { /* yes */
|
/* Now adjust the part we are really adding forward */
|
||||||
r = gctl_get_handle();
|
if (bytes > 0) {
|
||||||
gctl_ro_param(r, "class", -1, "PART");
|
firstfree += bytes / sector;
|
||||||
gctl_ro_param(r, "arg0", -1, geom->lg_name);
|
size -= (bytes + stripe)/sector;
|
||||||
gctl_ro_param(r, "flags", -1, GPART_FLAGS);
|
|
||||||
gctl_ro_param(r, "verb", -1, "add");
|
|
||||||
gctl_ro_param(r, "type", -1, bootpart_type(scheme));
|
|
||||||
snprintf(sizestr, sizeof(sizestr), "%jd",
|
|
||||||
bootpart_size(scheme) / sector);
|
|
||||||
gctl_ro_param(r, "size", -1, sizestr);
|
|
||||||
snprintf(startstr, sizeof(startstr), "%jd", firstfree);
|
|
||||||
gctl_ro_param(r, "start", -1, startstr);
|
|
||||||
gctl_rw_param(r, "output", sizeof(output), output);
|
|
||||||
errstr = gctl_issue(r);
|
|
||||||
if (errstr != NULL && errstr[0] != '\0')
|
|
||||||
gpart_show_error("Error", NULL, errstr);
|
|
||||||
gctl_free(r);
|
|
||||||
|
|
||||||
get_part_metadata(strtok(output, " "), 1)->bootcode = 1;
|
|
||||||
|
|
||||||
/* Now adjust the part we are really adding forward */
|
|
||||||
firstfree += bootpart_size(scheme) / sector;
|
|
||||||
size -= (bootpart_size(scheme) + stripe)/sector;
|
|
||||||
if (stripe > 0 && (firstfree*sector % stripe) != 0)
|
if (stripe > 0 && (firstfree*sector % stripe) != 0)
|
||||||
firstfree += (stripe - ((firstfree*sector) %
|
firstfree += (stripe - ((firstfree*sector) %
|
||||||
stripe)) / sector;
|
stripe)) / sector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = gctl_get_handle();
|
r = gctl_get_handle();
|
||||||
gctl_ro_param(r, "class", -1, "PART");
|
gctl_ro_param(r, "class", -1, "PART");
|
||||||
gctl_ro_param(r, "arg0", -1, geom->lg_name);
|
gctl_ro_param(r, "arg0", -1, geom->lg_name);
|
||||||
@ -1197,9 +1230,8 @@ gpart_create(struct gprovider *pp, char *default_type, char *default_size,
|
|||||||
gctl_issue(r); /* Error usually expected and non-fatal */
|
gctl_issue(r); /* Error usually expected and non-fatal */
|
||||||
gctl_free(r);
|
gctl_free(r);
|
||||||
|
|
||||||
if (strcmp(items[0].text, bootpart_type(scheme)) == 0)
|
|
||||||
get_part_metadata(newpartname, 1)->bootcode = 1;
|
if (strcmp(items[0].text, "freebsd") == 0)
|
||||||
else if (strcmp(items[0].text, "freebsd") == 0)
|
|
||||||
gpart_partition(newpartname, "BSD");
|
gpart_partition(newpartname, "BSD");
|
||||||
else
|
else
|
||||||
set_default_part_metadata(newpartname, scheme,
|
set_default_part_metadata(newpartname, scheme,
|
||||||
|
@ -65,8 +65,9 @@ int wizard_makeparts(struct gmesh *mesh, const char *disk, const char *fstype,
|
|||||||
void gpart_delete(struct gprovider *pp);
|
void gpart_delete(struct gprovider *pp);
|
||||||
void gpart_destroy(struct ggeom *lg_geom);
|
void gpart_destroy(struct ggeom *lg_geom);
|
||||||
void gpart_edit(struct gprovider *pp);
|
void gpart_edit(struct gprovider *pp);
|
||||||
void gpart_create(struct gprovider *pp, char *default_type, char *default_size,
|
void gpart_create(struct gprovider *pp, const char *default_type,
|
||||||
char *default_mountpoint, char **output, int interactive);
|
const char *default_size, const char *default_mountpoint,
|
||||||
|
char **output, int interactive);
|
||||||
intmax_t gpart_max_free(struct ggeom *gp, intmax_t *start);
|
intmax_t gpart_max_free(struct ggeom *gp, intmax_t *start);
|
||||||
void gpart_revert(struct gprovider *pp);
|
void gpart_revert(struct gprovider *pp);
|
||||||
void gpart_revert_all(struct gmesh *mesh);
|
void gpart_revert_all(struct gmesh *mesh);
|
||||||
@ -78,12 +79,29 @@ void gpart_set_root(const char *lg_name, const char *attribute);
|
|||||||
const char *choose_part_type(const char *def_scheme);
|
const char *choose_part_type(const char *def_scheme);
|
||||||
|
|
||||||
/* machine-dependent bootability checks */
|
/* machine-dependent bootability checks */
|
||||||
const char *default_scheme(void);
|
const char *default_scheme(void); /* Default partition scheme */
|
||||||
int is_scheme_bootable(const char *scheme);
|
int is_scheme_bootable(const char *scheme); /* Non-zero if scheme boots */
|
||||||
int is_fs_bootable(const char *scheme, const char *fs);
|
int is_fs_bootable(const char *scheme, const char *fs); /* Ditto if FS boots */
|
||||||
|
|
||||||
|
/* Size of boot partition in bytes. Zero if no boot partition */
|
||||||
size_t bootpart_size(const char *scheme);
|
size_t bootpart_size(const char *scheme);
|
||||||
const char *bootpart_type(const char *scheme);
|
|
||||||
|
/*
|
||||||
|
* Type and mountpoint of boot partition for given scheme. If boot partition
|
||||||
|
* should not be mounted, set mountpoint to NULL or leave it unchanged.
|
||||||
|
* Note that mountpoint non-NULL implies partcode_path() will be ignored.
|
||||||
|
* Do *NOT* set both!
|
||||||
|
*/
|
||||||
|
const char *bootpart_type(const char *scheme, const char **mountpoint);
|
||||||
|
|
||||||
|
/* Path to bootcode that goes in the scheme (e.g. disk MBR). NULL if none */
|
||||||
const char *bootcode_path(const char *scheme);
|
const char *bootcode_path(const char *scheme);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Path to boot blocks to be dd'ed into the partition suggested by bootpart_*
|
||||||
|
* for the given scheme and root filesystem type. If the boot partition should
|
||||||
|
* be mounted rather than dd'ed to, return NULL here.
|
||||||
|
*/
|
||||||
const char *partcode_path(const char *scheme, const char *fs_type);
|
const char *partcode_path(const char *scheme, const char *fs_type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -77,7 +77,7 @@ bootpart_size(const char *scheme)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
bootpart_type(const char *scheme)
|
bootpart_type(const char *scheme, const char **mountpoint)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Only EFI is supported as boot partition */
|
/* Only EFI is supported as boot partition */
|
||||||
|
@ -65,7 +65,7 @@ bootpart_size(const char *part_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
bootpart_type(const char *scheme) {
|
bootpart_type(const char *scheme, const char **mountpoint) {
|
||||||
return ("freebsd-boot");
|
return ("freebsd-boot");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ bootpart_size(const char *part_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
bootpart_type(const char *scheme) {
|
bootpart_type(const char *scheme, const char **mountpoint) {
|
||||||
size_t platlen = sizeof(platform);
|
size_t platlen = sizeof(platform);
|
||||||
if (strlen(platform) == 0)
|
if (strlen(platform) == 0)
|
||||||
sysctlbyname("hw.platform", platform, &platlen, NULL, -1);
|
sysctlbyname("hw.platform", platform, &platlen, NULL, -1);
|
||||||
|
@ -61,7 +61,7 @@ bootpart_size(const char *part_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
bootpart_type(const char *scheme) {
|
bootpart_type(const char *scheme, const char **mountpoint) {
|
||||||
return ("freebsd-boot");
|
return ("freebsd-boot");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ bootpart_size(const char *scheme)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
bootpart_type(const char *scheme)
|
bootpart_type(const char *scheme, const char **mountpoint)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (strcmp(x86_bootmethod(), "UEFI") == 0)
|
if (strcmp(x86_bootmethod(), "UEFI") == 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user