Author: nwhitehorn
Date: Fri Dec  8 00:57:13 2017
New Revision: 326674
URL: https://svnweb.freebsd.org/changeset/base/326674

Log:
  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.

Modified:
  head/usr.sbin/bsdinstall/partedit/gpart_ops.c
  head/usr.sbin/bsdinstall/partedit/partedit.h
  head/usr.sbin/bsdinstall/partedit/partedit_arm64.c
  head/usr.sbin/bsdinstall/partedit/partedit_generic.c
  head/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
  head/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
  head/usr.sbin/bsdinstall/partedit/partedit_x86.c

Modified: head/usr.sbin/bsdinstall/partedit/gpart_ops.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/gpart_ops.c       Thu Dec  7 22:36:58 
2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/gpart_ops.c       Fri Dec  8 00:57:13 
2017        (r326674)
@@ -191,9 +191,7 @@ newfs_command(const char *fstype, char *command, int u
                for (i = 0; i < (int)nitems(items); i++) {
                        if (items[i].state == 0)
                                continue;
-                       if (strcmp(items[i].name, "FAT32") == 0)
-                               strcat(command, "-F 32 ");
-                       else if (strcmp(items[i].name, "FAT16") == 0)
+                       if (strcmp(items[i].name, "FAT16") == 0)
                                strcat(command, "-F 16 ");
                        else if (strcmp(items[i].name, "FAT12") == 0)
                                strcat(command, "-F 12 ");
@@ -675,6 +673,7 @@ set_default_part_metadata(const char *name, const char
 {
        struct partition_metadata *md;
        char *zpool_name = NULL;
+       const char *default_bootmount = NULL;
        int i;
 
        /* Set part metadata */
@@ -705,8 +704,12 @@ set_default_part_metadata(const char *name, const char
 
        if (strcmp(type, "freebsd-swap") == 0)
                mountpoint = "none";
-       if (strcmp(type, bootpart_type(scheme)) == 0)
-               md->bootcode = 1;
+       if (strcmp(type, bootpart_type(scheme, &default_bootmount)) == 0) {
+               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 */
        if (strcmp(scheme, "VTOC8") == 0 && (strcmp(type, "freebsd-ufs") == 0
@@ -886,9 +889,79 @@ gpart_max_free(struct ggeom *geom, intmax_t *npartstar
        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
-gpart_create(struct gprovider *pp, char *default_type, char *default_size,
-     char *default_mountpoint, char **partname, int interactive)
+gpart_create(struct gprovider *pp, const char *default_type,
+    const char *default_size, const char *default_mountpoint,
+    char **partname, int interactive)
 {
        struct gctl_req *r;
        struct gconfig *gc;
@@ -984,11 +1057,11 @@ gpart_create(struct gprovider *pp, char *default_type,
        nitems = scheme_supports_labels(scheme) ? 4 : 3;
 
        if (default_type != NULL)
-               items[0].text = default_type;
+               items[0].text = (char *)default_type;
        if (default_size != NULL)
-               items[1].text = default_size;
+               items[1].text = (char *)default_size;
        if (default_mountpoint != NULL)
-               items[2].text = default_mountpoint;
+               items[2].text = (char *)default_mountpoint;
 
        /* Default options */
        strncpy(options_fstype, items[0].text,
@@ -1105,61 +1178,21 @@ addpartform:
         * 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 ||
-           strcmp(items[2].text, "/") == 0) && bootpart_size(scheme) > 0 &&
-           pp == NULL) {
-               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;
+           strcmp(items[2].text, "/") == 0) && bootpart_size(scheme) > 0) {
+               size_t bytes = add_boot_partition(geom, pp, scheme,
+                   interactive);
 
-               if (choice == 0) { /* yes */
-                       r = gctl_get_handle();
-                       gctl_ro_param(r, "class", -1, "PART");
-                       gctl_ro_param(r, "arg0", -1, geom->lg_name);
-                       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;
+               /* Now adjust the part we are really adding forward */
+               if (bytes > 0) {
+                       firstfree += bytes / sector;
+                       size -= (bytes + stripe)/sector;
                        if (stripe > 0 && (firstfree*sector % stripe) != 0) 
                                firstfree += (stripe - ((firstfree*sector) %
                                    stripe)) / sector;
                }
        }
-       
+
        r = gctl_get_handle();
        gctl_ro_param(r, "class", -1, "PART");
        gctl_ro_param(r, "arg0", -1, geom->lg_name);
@@ -1197,9 +1230,8 @@ addpartform:
        gctl_issue(r); /* Error usually expected and non-fatal */
        gctl_free(r);
 
-       if (strcmp(items[0].text, bootpart_type(scheme)) == 0)
-               get_part_metadata(newpartname, 1)->bootcode = 1;
-       else if (strcmp(items[0].text, "freebsd") == 0)
+
+       if (strcmp(items[0].text, "freebsd") == 0)
                gpart_partition(newpartname, "BSD");
        else
                set_default_part_metadata(newpartname, scheme,

Modified: head/usr.sbin/bsdinstall/partedit/partedit.h
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit.h        Thu Dec  7 22:36:58 
2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/partedit.h        Fri Dec  8 00:57:13 
2017        (r326674)
@@ -65,8 +65,9 @@ int wizard_makeparts(struct gmesh *mesh, const char *d
 void gpart_delete(struct gprovider *pp);
 void gpart_destroy(struct ggeom *lg_geom);
 void gpart_edit(struct gprovider *pp);
-void gpart_create(struct gprovider *pp, char *default_type, char *default_size,
-    char *default_mountpoint, char **output, int interactive);
+void gpart_create(struct gprovider *pp, const char *default_type,
+    const char *default_size, const char *default_mountpoint,
+    char **output, int interactive);
 intmax_t gpart_max_free(struct ggeom *gp, intmax_t *start);
 void gpart_revert(struct gprovider *pp);
 void gpart_revert_all(struct gmesh *mesh);
@@ -78,12 +79,29 @@ void gpart_set_root(const char *lg_name, const char *a
 const char *choose_part_type(const char *def_scheme);
 
 /* machine-dependent bootability checks */
-const char *default_scheme(void);
-int is_scheme_bootable(const char *scheme);
-int is_fs_bootable(const char *scheme, const char *fs);
+const char *default_scheme(void);              /* Default partition scheme */
+int is_scheme_bootable(const char *scheme);    /* Non-zero if scheme boots */
+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);
-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);
+
+/*
+ * 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);
 
 #endif

Modified: head/usr.sbin/bsdinstall/partedit/partedit_arm64.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_arm64.c  Thu Dec  7 22:36:58 
2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/partedit_arm64.c  Fri Dec  8 00:57:13 
2017        (r326674)
@@ -77,7 +77,7 @@ bootpart_size(const char *scheme)
 }
 
 const char *
-bootpart_type(const char *scheme)
+bootpart_type(const char *scheme, const char **mountpoint)
 {
 
        /* Only EFI is supported as boot partition */

Modified: head/usr.sbin/bsdinstall/partedit/partedit_generic.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_generic.c        Thu Dec  7 
22:36:58 2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/partedit_generic.c        Fri Dec  8 
00:57:13 2017        (r326674)
@@ -65,7 +65,7 @@ bootpart_size(const char *part_type) {
 }
 
 const char *
-bootpart_type(const char *scheme) {
+bootpart_type(const char *scheme, const char **mountpoint) {
        return ("freebsd-boot");
 }
 

Modified: head/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_powerpc.c        Thu Dec  7 
22:36:58 2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/partedit_powerpc.c        Fri Dec  8 
00:57:13 2017        (r326674)
@@ -92,7 +92,7 @@ bootpart_size(const char *part_type) {
 }
 
 const char *
-bootpart_type(const char *scheme) {
+bootpart_type(const char *scheme, const char **mountpoint) {
        size_t platlen = sizeof(platform);
        if (strlen(platform) == 0)
                sysctlbyname("hw.platform", platform, &platlen, NULL, -1);

Modified: head/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_sparc64.c        Thu Dec  7 
22:36:58 2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/partedit_sparc64.c        Fri Dec  8 
00:57:13 2017        (r326674)
@@ -61,7 +61,7 @@ bootpart_size(const char *part_type) {
 }
 
 const char *
-bootpart_type(const char *scheme) {
+bootpart_type(const char *scheme, const char **mountpoint) {
        return ("freebsd-boot");
 }
 

Modified: head/usr.sbin/bsdinstall/partedit/partedit_x86.c
==============================================================================
--- head/usr.sbin/bsdinstall/partedit/partedit_x86.c    Thu Dec  7 22:36:58 
2017        (r326673)
+++ head/usr.sbin/bsdinstall/partedit/partedit_x86.c    Fri Dec  8 00:57:13 
2017        (r326674)
@@ -111,7 +111,7 @@ bootpart_size(const char *scheme)
 }
 
 const char *
-bootpart_type(const char *scheme)
+bootpart_type(const char *scheme, const char **mountpoint)
 {
 
        if (strcmp(x86_bootmethod(), "UEFI") == 0)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to