aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit.c39
-rwxr-xr-xusr.sbin/bsdinstall/scripts/script30
2 files changed, 61 insertions, 8 deletions
diff --git a/usr.sbin/bsdinstall/partedit/partedit.c b/usr.sbin/bsdinstall/partedit/partedit.c
index c5fa28e73582..6d045428dd32 100644
--- a/usr.sbin/bsdinstall/partedit/partedit.c
+++ b/usr.sbin/bsdinstall/partedit/partedit.c
@@ -324,6 +324,22 @@ validate_setup(void)
}
static int
+mountpoint_sorter(const void *xa, const void *xb)
+{
+ struct partition_metadata *a = *(struct partition_metadata **)xa;
+ struct partition_metadata *b = *(struct partition_metadata **)xb;
+
+ if (a->fstab == NULL && b->fstab == NULL)
+ return 0;
+ if (a->fstab == NULL)
+ return 1;
+ if (b->fstab == NULL)
+ return -1;
+
+ return strcmp(a->fstab->fs_file, b->fstab->fs_file);
+}
+
+static int
apply_changes(struct gmesh *mesh)
{
struct partition_metadata *md;
@@ -386,6 +402,29 @@ apply_changes(struct gmesh *mesh)
free(__DECONST(char *, items[i*2]));
free(items);
+ /* Sort filesystems for fstab so that mountpoints are ordered */
+ {
+ struct partition_metadata **tobesorted;
+ struct partition_metadata *tmp;
+ int nparts = 0;
+ TAILQ_FOREACH(md, &part_metadata, metadata)
+ nparts++;
+ tobesorted = malloc(sizeof(struct partition_metadata *)*nparts);
+ nparts = 0;
+ TAILQ_FOREACH_SAFE(md, &part_metadata, metadata, tmp) {
+ tobesorted[nparts++] = md;
+ TAILQ_REMOVE(&part_metadata, md, metadata);
+ }
+ qsort(tobesorted, nparts, sizeof(tobesorted[0]),
+ mountpoint_sorter);
+
+ /* Now re-add everything */
+ while (nparts-- > 0)
+ TAILQ_INSERT_HEAD(&part_metadata,
+ tobesorted[nparts], metadata);
+ free(tobesorted);
+ }
+
if (getenv("PATH_FSTAB") != NULL)
fstab_path = getenv("PATH_FSTAB");
else
diff --git a/usr.sbin/bsdinstall/scripts/script b/usr.sbin/bsdinstall/scripts/script
index 4d0a91833644..1d8e52a9d6d3 100755
--- a/usr.sbin/bsdinstall/scripts/script
+++ b/usr.sbin/bsdinstall/scripts/script
@@ -116,14 +116,28 @@ fi
# Unpack distributions
bsdinstall checksum
-for set in $DISTRIBUTIONS; do
- f_dprintf "Extracting $BSDINSTALL_DISTDIR/$set"
- # XXX: this will fail if any mountpoints are FAT, due to inability to
- # set ctime/mtime on the root of FAT partitions. tar has no option to
- # ignore this. We probably need to switch back to distextract here
- # to properly support EFI.
- tar -xf "$BSDINSTALL_DISTDIR/$set" -C $BSDINSTALL_CHROOT
-done
+if [ -t 0 ]; then
+ # If install is a tty, use distextract as normal
+ bsdinstall distextract
+else
+ # Otherwise, we need to use tar (see https://reviews.freebsd.org/D10736)
+ for set in $DISTRIBUTIONS; do
+ f_dprintf "Extracting $BSDINSTALL_DISTDIR/$set"
+ # XXX: The below fails if any mountpoints are FAT, due to
+ # inability to set ctime/mtime on the root of FAT partitions,
+ # which is needed to support e.g. EFI system partitions. tar has
+ # no option to ignore this (distextract ignores them internally
+ # through a hack), and returns 1 on any warning or error,
+ # effectively turning all warnings into fatal errors.
+ #
+ # Work around this in an extremely lame way for the specific
+ # case of EFI system partitions only. This *ONLY WORKS* if
+ # /boot/efi is empty and does not handle analagous problems on
+ # other systems (ARM, PPC64).
+ tar -xf "$BSDINSTALL_DISTDIR/$set" -C $BSDINSTALL_CHROOT --exclude boot/efi
+ mkdir -p $BSDINSTALL_CHROOT/boot/efi
+ done
+fi
# Configure bootloader if needed
bsdinstall bootconfig