summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-01-19 20:22:58 +0100
committerLennart Poettering <lennart@poettering.net>2015-01-19 20:24:10 +0100
commitf6c51a8136de3f27e28caea2003e18f4bc4cb9a8 (patch)
tree48f8364e24f87b4e4464dc3c29cdd3b15eec9d65 /src
parentec5cb56ee18f529a023deedd0806854f08499b6a (diff)
nspawn: support dissecting GPT images that contain only a single generic linux partition
This should allow running Ubuntu UEFI GPT Images with nspawn, unmodified.
Diffstat (limited to 'src')
-rw-r--r--src/nspawn/nspawn.c95
-rw-r--r--src/shared/gpt.h2
2 files changed, 58 insertions, 39 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index e71d9a88ad..efeba59665 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2618,7 +2618,8 @@ static int wait_for_block_device(struct udev *udev, dev_t devnum, struct udev_de
#define PARTITION_TABLE_BLURB \
"Note that the disk image needs to either contain only a single MBR partition of\n" \
- "type 0x83 that is marked bootable, or follow\n" \
+ "type 0x83 that is marked bootable, or a sinlge GPT partition of type" \
+ "0FC63DAF-8483-4772-8E79-3D69D8477DE4 or follow\n" \
" http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/\n" \
"to be bootable with systemd-nspawn."
@@ -2637,19 +2638,18 @@ static int dissect_image(
#ifdef GPT_ROOT_SECONDARY
int secondary_root_nr = -1;
#endif
-
- _cleanup_free_ char *home = NULL, *root = NULL, *secondary_root = NULL, *srv = NULL;
+ _cleanup_free_ char *home = NULL, *root = NULL, *secondary_root = NULL, *srv = NULL, *generic = NULL;
_cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
_cleanup_blkid_free_probe_ blkid_probe b = NULL;
_cleanup_udev_unref_ struct udev *udev = NULL;
struct udev_list_entry *first, *item;
- bool home_rw = true, root_rw = true, secondary_root_rw = true, srv_rw = true;
+ bool home_rw = true, root_rw = true, secondary_root_rw = true, srv_rw = true, generic_rw = true;
const char *pttype = NULL;
blkid_partlist pl;
struct stat st;
int r;
- bool is_gpt, is_mbr;
+ bool is_gpt, is_mbr, multiple_generic = false;
assert(fd >= 0);
assert(root_device);
@@ -2769,10 +2769,6 @@ static int dissect_image(
continue;
flags = blkid_partition_get_flags(pp);
- if (is_gpt && (flags & GPT_FLAG_NO_AUTO))
- continue;
- if (is_mbr && (flags != 0x80)) /* Bootable flag */
- continue;
nr = blkid_partition_get_partno(pp);
if (nr < 0)
@@ -2782,6 +2778,9 @@ static int dissect_image(
sd_id128_t type_id;
const char *stype;
+ if (flags & GPT_FLAG_NO_AUTO)
+ continue;
+
stype = blkid_partition_get_type_string(pp);
if (!stype)
continue;
@@ -2841,48 +2840,41 @@ static int dissect_image(
return log_oom();
}
#endif
+ else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) {
+
+ if (generic)
+ multiple_generic = true;
+ else {
+ generic_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+ r = free_and_strdup(&generic, node);
+ if (r < 0)
+ return log_oom();
+ }
+ }
} else if (is_mbr) {
int type;
+ if (flags != 0x80) /* Bootable flag */
+ continue;
+
type = blkid_partition_get_type(pp);
if (type != 0x83) /* Linux partition */
continue;
- /* Note that there's a certain, intended
- * asymmetry here: while for GPT we simply
- * take the first valid partition and ignore
- * all others of the same type, for MBR we
- * fail if there are multiple suitable
- * partitions. This is because the GPT
- * partition types are defined by us, and
- * hence we can define their lookup semantics,
- * while for the MBR logic we reuse existing
- * definitions, and simply don't want to make
- * out the situation. */
-
- if (root) {
- log_error("Identified multiple bootable Linux 0x83 partitions on\n"
- " %s\n"
- PARTITION_TABLE_BLURB, arg_image);
- return -EINVAL;
- }
-
- root_nr = nr;
+ if (generic)
+ multiple_generic = true;
+ else {
+ generic_rw = true;
- r = free_and_strdup(&root, node);
- if (r < 0)
- return log_oom();
+ r = free_and_strdup(&root, node);
+ if (r < 0)
+ return log_oom();
+ }
}
}
- if (!root && !secondary_root) {
- log_error("Failed to identify root partition in disk image\n"
- " %s\n"
- PARTITION_TABLE_BLURB, arg_image);
- return -EINVAL;
- }
-
if (root) {
*root_device = root;
root = NULL;
@@ -2895,6 +2887,31 @@ static int dissect_image(
*root_device_rw = secondary_root_rw;
*secondary = true;
+ } else if (generic) {
+
+ /* There were no partitions with precise meanings
+ * around, but we found generic partitions. In this
+ * case, if there's only one, we can go ahead and boot
+ * it, otherwise we bail out, because we really cannot
+ * make any sense of it. */
+
+ if (multiple_generic) {
+ log_error("Identified multiple bootable Linux partitions on\n"
+ " %s\n"
+ PARTITION_TABLE_BLURB, arg_image);
+ return -EINVAL;
+ }
+
+ *root_device = generic;
+ generic = NULL;
+
+ *root_device_rw = generic_rw;
+ *secondary = false;
+ } else {
+ log_error("Failed to identify root partition in disk image\n"
+ " %s\n"
+ PARTITION_TABLE_BLURB, arg_image);
+ return -EINVAL;
}
if (home) {
diff --git a/src/shared/gpt.h b/src/shared/gpt.h
index ef3444f6ea..87308b0d2b 100644
--- a/src/shared/gpt.h
+++ b/src/shared/gpt.h
@@ -57,3 +57,5 @@
* just because we saw no point in defining any other values here. */
#define GPT_FLAG_READ_ONLY (1ULL << 60)
#define GPT_FLAG_NO_AUTO (1ULL << 63)
+
+#define GPT_LINUX_GENERIC SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4)