]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: if an ESP is part of the disk image to operate on, mount it to /efi or /boot
authorLennart Poettering <lennart@poettering.net>
Tue, 19 Jul 2016 16:36:04 +0000 (18:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 21 Jul 2016 09:10:35 +0000 (11:10 +0200)
Matching the behaviour of gpt-auto-generator, if we find an ESP while
dissecting a container image, mount it to /efi or /boot if those dirs exist and
are empty.

This should enable us to run "bootctl" inside a container and do the right
thing.

src/nspawn/nspawn.c

index e4be0a225139e7fc01a49cbfd24fa433ed02821f..befe342b02264d2d64376652d2915217bad4d7ec 100644 (file)
@@ -1803,17 +1803,18 @@ static int dissect_image(
                 char **root_device, bool *root_device_rw,
                 char **home_device, bool *home_device_rw,
                 char **srv_device, bool *srv_device_rw,
+                char **esp_device,
                 bool *secondary) {
 
 #ifdef HAVE_BLKID
-        int home_nr = -1, srv_nr = -1;
+        int home_nr = -1, srv_nr = -1, esp_nr = -1;
 #ifdef GPT_ROOT_NATIVE
         int root_nr = -1;
 #endif
 #ifdef GPT_ROOT_SECONDARY
         int secondary_root_nr = -1;
 #endif
-        _cleanup_free_ char *home = NULL, *root = NULL, *secondary_root = NULL, *srv = NULL, *generic = NULL;
+        _cleanup_free_ char *home = NULL, *root = NULL, *secondary_root = NULL, *srv = NULL, *esp = 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;
@@ -1831,6 +1832,7 @@ static int dissect_image(
         assert(root_device);
         assert(home_device);
         assert(srv_device);
+        assert(esp_device);
         assert(secondary);
         assert(arg_image);
 
@@ -2044,6 +2046,16 @@ static int dissect_image(
                                 r = free_and_strdup(&srv, node);
                                 if (r < 0)
                                         return log_oom();
+                        } else if (sd_id128_equal(type_id, GPT_ESP)) {
+
+                                if (esp && nr >= esp_nr)
+                                        continue;
+
+                                esp_nr = nr;
+
+                                r = free_and_strdup(&esp, node);
+                                if (r < 0)
+                                        return log_oom();
                         }
 #ifdef GPT_ROOT_NATIVE
                         else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
@@ -2161,6 +2173,11 @@ static int dissect_image(
                 *srv_device_rw = srv_rw;
         }
 
+        if (esp) {
+                *esp_device = esp;
+                esp = NULL;
+        }
+
         return 0;
 #else
         log_error("--image= is not supported, compiled without blkid support.");
@@ -2289,7 +2306,8 @@ static int mount_devices(
                 const char *where,
                 const char *root_device, bool root_device_rw,
                 const char *home_device, bool home_device_rw,
-                const char *srv_device, bool srv_device_rw) {
+                const char *srv_device, bool srv_device_rw,
+                const char *esp_device) {
         int r;
 
         assert(where);
@@ -2312,6 +2330,27 @@ static int mount_devices(
                         return log_error_errno(r, "Failed to mount server data directory: %m");
         }
 
+        if (esp_device) {
+                const char *mp, *x;
+
+                /* Mount the ESP to /efi if it exists and is empty. If it doesn't exist, use /boot instead. */
+
+                mp = "/efi";
+                x = strjoina(arg_directory, mp);
+                r = dir_is_empty(x);
+                if (r == -ENOENT) {
+                        mp = "/boot";
+                        x = strjoina(arg_directory, mp);
+                        r = dir_is_empty(x);
+                }
+
+                if (r > 0) {
+                        r = mount_device(esp_device, arg_directory, mp, true);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to  mount ESP: %m");
+                }
+        }
+
         return 0;
 }
 
@@ -2785,6 +2824,7 @@ static int outer_child(
                 const char *root_device, bool root_device_rw,
                 const char *home_device, bool home_device_rw,
                 const char *srv_device, bool srv_device_rw,
+                const char *esp_device,
                 bool interactive,
                 bool secondary,
                 int pid_socket,
@@ -2846,7 +2886,8 @@ static int outer_child(
         r = mount_devices(directory,
                           root_device, root_device_rw,
                           home_device, home_device_rw,
-                          srv_device, srv_device_rw);
+                          srv_device, srv_device_rw,
+                          esp_device);
         if (r < 0)
                 return r;
 
@@ -3449,7 +3490,7 @@ static int load_settings(void) {
 
 int main(int argc, char *argv[]) {
 
-        _cleanup_free_ char *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL, *console = NULL;
+        _cleanup_free_ char *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL, *esp_device = NULL, *console = NULL;
         bool root_device_rw = true, home_device_rw = true, srv_device_rw = true;
         _cleanup_close_ int master = -1, image_fd = -1;
         _cleanup_fdset_free_ FDSet *fds = NULL;
@@ -3631,6 +3672,7 @@ int main(int argc, char *argv[]) {
                                   &root_device, &root_device_rw,
                                   &home_device, &home_device_rw,
                                   &srv_device, &srv_device_rw,
+                                  &esp_device,
                                   &secondary);
                 if (r < 0)
                         goto finish;
@@ -3805,6 +3847,7 @@ int main(int argc, char *argv[]) {
                                         root_device, root_device_rw,
                                         home_device, home_device_rw,
                                         srv_device, srv_device_rw,
+                                        esp_device,
                                         interactive,
                                         secondary,
                                         pid_socket_pair[1],