[systemd-commits] 2 commits - src/nspawn

Lennart Poettering lennart at kemper.freedesktop.org
Wed Jan 14 15:53:24 PST 2015


 src/nspawn/nspawn.c |  156 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 102 insertions(+), 54 deletions(-)

New commits:
commit 5e4074aa3188ff439c0509908284469807d2749e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 15 00:51:54 2015 +0100

    spawn: downgrade loopback detach errors to debug
    
    Sometimes udev or some other background daemon might keep the loopback
    devices busy while we already want to detach them. Downgrade the warning
    about it.
    
    Given that we use autodetach downgrading these messages should be with
    little risk.

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 9fe040c..2783c97 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2963,7 +2963,7 @@ static void loop_remove(int nr, int *image_fd) {
         if (image_fd && *image_fd >= 0) {
                 r = ioctl(*image_fd, LOOP_CLR_FD);
                 if (r < 0)
-                        log_warning_errno(errno, "Failed to close loop image: %m");
+                        log_debug_errno(errno, "Failed to close loop image: %m");
                 *image_fd = safe_close(*image_fd);
         }
 
@@ -2975,7 +2975,7 @@ static void loop_remove(int nr, int *image_fd) {
 
         r = ioctl(control, LOOP_CTL_REMOVE, nr);
         if (r < 0)
-                log_warning_errno(errno, "Failed to remove loop %d: %m", nr);
+                log_debug_errno(errno, "Failed to remove loop %d: %m", nr);
 }
 
 static int spawn_getent(const char *database, const char *key, pid_t *rpid) {

commit ada4799ac5ad2e6c0fe11dc5c096faca8a85876b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jan 15 00:47:10 2015 +0100

    nspawn: add support for limited dissecting of MBR disk images with nspawn
    
    With this change nspawn's -i switch now can now make sense of MBR disk
    images too - however only if there's only a single, bootable partition
    of type 0x83 on the image. For all other cases we cannot really make
    sense from the partition table alone.
    
    The big benefit of this change is that upstream Fedora Cloud Images can
    now be booted unmodified with systemd-nspawn:
    
     # wget http://download.fedoraproject.org/pub/fedora/linux/releases/21/Cloud/Images/x86_64/Fedora-Cloud-Base-20141203-21.x86_64.raw.xz
     # unxz Fedora-Cloud-Base-20141203-21.x86_64.raw.xz
     # systemd-nspawn -i Fedora-Cloud-Base-20141203-21.x86_64.raw -b
    
    Next stop: teach the import logic to automatically download these
    images, uncompress and verify them.

diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 2bda27e..9fe040c 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2557,6 +2557,12 @@ static int setup_image(char **device_path, int *loop_nr) {
         return r;
 }
 
+#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" \
+        "    http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/\n" \
+        "to be bootable with systemd-nspawn."
+
 static int dissect_image(
                 int fd,
                 char **root_device, bool *root_device_rw,
@@ -2584,6 +2590,7 @@ static int dissect_image(
         blkid_partlist pl;
         struct stat st;
         int r;
+        bool is_gpt, is_mbr;
 
         assert(fd >= 0);
         assert(root_device);
@@ -2612,8 +2619,9 @@ static int dissect_image(
         errno = 0;
         r = blkid_do_safeprobe(b);
         if (r == -2 || r == 1) {
-                log_error("Failed to identify any partition table on %s.\n"
-                          "Note that the disk image needs to follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ to be supported by systemd-nspawn.", arg_image);
+                log_error("Failed to identify any partition table on\n"
+                          "    %s\n"
+                          PARTITION_TABLE_BLURB, arg_image);
                 return -EINVAL;
         } else if (r != 0) {
                 if (errno == 0)
@@ -2623,9 +2631,14 @@ static int dissect_image(
         }
 
         blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
-        if (!streq_ptr(pttype, "gpt")) {
-                log_error("Image %s does not carry a GUID Partition Table.\n"
-                          "Note that the disk image needs to follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ to be supported by systemd-nspawn.", arg_image);
+
+        is_gpt = streq_ptr(pttype, "gpt");
+        is_mbr = streq_ptr(pttype, "dos");
+
+        if (!is_gpt && !is_mbr) {
+                log_error("No GPT or MBR partition table discovered on\n"
+                          "    %s\n"
+                          PARTITION_TABLE_BLURB, arg_image);
                 return -EINVAL;
         }
 
@@ -2665,9 +2678,8 @@ static int dissect_image(
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
                 _cleanup_udev_device_unref_ struct udev_device *q;
-                const char *stype, *node;
+                const char *node;
                 unsigned long long flags;
-                sd_id128_t type_id;
                 blkid_partition pp;
                 dev_t qn;
                 int nr;
@@ -2698,81 +2710,117 @@ static int dissect_image(
                         continue;
 
                 flags = blkid_partition_get_flags(pp);
-                if (flags & GPT_FLAG_NO_AUTO)
+                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)
                         continue;
 
-                stype = blkid_partition_get_type_string(pp);
-                if (!stype)
-                        continue;
-
-                if (sd_id128_from_string(stype, &type_id) < 0)
-                        continue;
+                if (is_gpt) {
+                        sd_id128_t type_id;
+                        const char *stype;
 
-                if (sd_id128_equal(type_id, GPT_HOME)) {
+                        stype = blkid_partition_get_type_string(pp);
+                        if (!stype)
+                                continue;
 
-                        if (home && nr >= home_nr)
+                        if (sd_id128_from_string(stype, &type_id) < 0)
                                 continue;
 
-                        home_nr = nr;
-                        home_rw = !(flags & GPT_FLAG_READ_ONLY);
+                        if (sd_id128_equal(type_id, GPT_HOME)) {
 
-                        free(home);
-                        home = strdup(node);
-                        if (!home)
-                                return log_oom();
-                } else if (sd_id128_equal(type_id, GPT_SRV)) {
+                                if (home && nr >= home_nr)
+                                        continue;
 
-                        if (srv && nr >= srv_nr)
-                                continue;
+                                home_nr = nr;
+                                home_rw = !(flags & GPT_FLAG_READ_ONLY);
 
-                        srv_nr = nr;
-                        srv_rw = !(flags & GPT_FLAG_READ_ONLY);
+                                r = free_and_strdup(&home, node);
+                                if (r < 0)
+                                        return log_oom();
 
-                        free(srv);
-                        srv = strdup(node);
-                        if (!srv)
-                                return log_oom();
-                }
+                        } else if (sd_id128_equal(type_id, GPT_SRV)) {
+
+                                if (srv && nr >= srv_nr)
+                                        continue;
+
+                                srv_nr = nr;
+                                srv_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+                                r = free_and_strdup(&srv, node);
+                                if (r < 0)
+                                        return log_oom();
+                        }
 #ifdef GPT_ROOT_NATIVE
-                else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
+                        else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
 
-                        if (root && nr >= root_nr)
-                                continue;
+                                if (root && nr >= root_nr)
+                                        continue;
 
-                        root_nr = nr;
-                        root_rw = !(flags & GPT_FLAG_READ_ONLY);
+                                root_nr = nr;
+                                root_rw = !(flags & GPT_FLAG_READ_ONLY);
 
-                        free(root);
-                        root = strdup(node);
-                        if (!root)
-                                return log_oom();
-                }
+                                r = free_and_strdup(&root, node);
+                                if (r < 0)
+                                        return log_oom();
+                        }
 #endif
 #ifdef GPT_ROOT_SECONDARY
-                else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
+                        else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
+
+                                if (secondary_root && nr >= secondary_root_nr)
+                                        continue;
+
+                                secondary_root_nr = nr;
+                                secondary_root_rw = !(flags & GPT_FLAG_READ_ONLY);
+
+                                r = free_and_strdup(&secondary_root, node);
+                                if (r < 0)
+                                        return log_oom();
+                        }
+#endif
+
+                } else if (is_mbr) {
+                        int type;
 
-                        if (secondary_root && nr >= secondary_root_nr)
+                        type = blkid_partition_get_type(pp);
+                        if (type != 0x83) /* Linux partition */
                                 continue;
 
-                        secondary_root_nr = nr;
-                        secondary_root_rw = !(flags & GPT_FLAG_READ_ONLY);
+                        /* 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;
 
-                        free(secondary_root);
-                        secondary_root = strdup(node);
-                        if (!secondary_root)
+                        r = free_and_strdup(&root, node);
+                        if (r < 0)
                                 return log_oom();
                 }
-#endif
         }
 
         if (!root && !secondary_root) {
-                log_error("Failed to identify root partition in disk image %s.\n"
-                          "Note that the disk image needs to follow http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/ to be supported by systemd-nspawn.", arg_image);
+                log_error("Failed to identify root partition in disk image\n"
+                          "    %s\n"
+                          PARTITION_TABLE_BLURB, arg_image);
                 return -EINVAL;
         }
 



More information about the systemd-commits mailing list