]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: show proper error strings for more errors
authorLennart Poettering <lennart@poettering.net>
Tue, 11 Aug 2020 13:59:44 +0000 (15:59 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 11 Aug 2020 20:29:50 +0000 (22:29 +0200)
Also, make inability to decrypt and EBUSY a non-fatal issue, since we
still are able to display the mount table then.

src/dissect/dissect.c
src/shared/dissect-image.c

index f575e1b28bce7b20718fc9100acff7107eb6d76e..d6b6303ee1f13e82badded150e3d963e0416169b 100644 (file)
@@ -323,14 +323,6 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
         assert(m);
         assert(d);
 
-        r = dissected_image_acquire_metadata(m);
-        if (r == -EMEDIUMTYPE)
-                return log_error_errno(r, "Not a valid OS image, no os-release file included.");
-        if (r == -ENXIO)
-                return log_error_errno(r, "No root partition discovered.");
-        if (r < 0)
-                return log_error_errno(r, "Failed to acquire image metadata: %m");
-
         printf("      Name: %s\n", basename(arg_image));
 
         if (ioctl(d->fd, BLKGETSIZE64, &size) < 0)
@@ -340,28 +332,45 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
                 printf("      Size: %s\n", format_bytes(s, sizeof(s), size));
         }
 
-        if (m->hostname)
-                printf("  Hostname: %s\n", m->hostname);
+        putc('\n', stdout);
+
+        r = dissected_image_acquire_metadata(m);
+        if (r == -ENXIO)
+                return log_error_errno(r, "No root partition discovered.");
+        if (r == -EMEDIUMTYPE)
+                return log_error_errno(r, "Not a valid OS image, no os-release file included.");
+        if (r == -EUCLEAN)
+                return log_error_errno(r, "File system check of image failed.");
+        if (r == -EUNATCH)
+                log_warning_errno(r, "OS image is encrypted, proceeding without showing OS image metadata.");
+        else if (r == -EBUSY)
+                log_warning_errno(r, "OS image is currently in use, proceeding without showing OS image metadata.");
+        else if (r < 0)
+                return log_error_errno(r, "Failed to acquire image metadata: %m");
+        else {
+                if (m->hostname)
+                        printf("  Hostname: %s\n", m->hostname);
 
-        if (!sd_id128_is_null(m->machine_id))
-                printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id));
+                if (!sd_id128_is_null(m->machine_id))
+                        printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id));
 
-        if (!strv_isempty(m->machine_info)) {
-                char **p, **q;
+                if (!strv_isempty(m->machine_info)) {
+                        char **p, **q;
 
-                STRV_FOREACH_PAIR(p, q, m->machine_info)
-                        printf("%s %s=%s\n",
-                               p == m->machine_info ? "Mach. Info:" : "           ",
-                               *p, *q);
-        }
+                        STRV_FOREACH_PAIR(p, q, m->machine_info)
+                                printf("%s %s=%s\n",
+                                       p == m->machine_info ? "Mach. Info:" : "           ",
+                                       *p, *q);
+                }
 
-        if (!strv_isempty(m->os_release)) {
-                char **p, **q;
+                if (!strv_isempty(m->os_release)) {
+                        char **p, **q;
 
-                STRV_FOREACH_PAIR(p, q, m->os_release)
-                        printf("%s %s=%s\n",
-                               p == m->os_release ? "OS Release:" : "           ",
-                               *p, *q);
+                        STRV_FOREACH_PAIR(p, q, m->os_release)
+                                printf("%s %s=%s\n",
+                                       p == m->os_release ? "OS Release:" : "           ",
+                                       *p, *q);
+                }
         }
 
         putc('\n', stdout);
index bab587ba132137ecca92397b84aa18bac4c0519e..8cbf4828b8a2a5ab9fe7f7535ac32bb93dbff5f4 100644 (file)
@@ -1772,12 +1772,14 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
         };
 
         _cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL;
+        _cleanup_close_pair_ int error_pipe[2] = { -1, -1 };
         _cleanup_(rmdir_and_freep) char *t = NULL;
         _cleanup_(sigkill_waitp) pid_t child = 0;
         sd_id128_t machine_id = SD_ID128_NULL;
         _cleanup_free_ char *hostname = NULL;
         unsigned n_meta_initialized = 0, k;
-        int fds[2 * _META_MAX], r;
+        int fds[2 * _META_MAX], r, v;
+        ssize_t n;
 
         BLOCK_SIGNALS(SIGCHLD);
 
@@ -1793,16 +1795,22 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
         if (r < 0)
                 goto finish;
 
+        if (pipe2(error_pipe, O_CLOEXEC) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
         r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, &child);
         if (r < 0)
                 goto finish;
         if (r == 0) {
+                error_pipe[0] = safe_close(error_pipe[0]);
+
                 r = dissected_image_mount(m, t, UID_INVALID, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_MOUNT_ROOT_ONLY|DISSECT_IMAGE_VALIDATE_OS);
-                if (r == -EMEDIUMTYPE) /* No /etc/os-release */
-                        _exit(EX_OSFILE);
-                if (r == -ENXIO) /* No root partition */
-                        _exit(EX_DATAERR);
                 if (r < 0) {
+                        /* Let parent know the error */
+                        (void) write(error_pipe[1], &r, sizeof(r));
+
                         log_debug_errno(r, "Failed to mount dissected image: %m");
                         _exit(EXIT_FAILURE);
                 }
@@ -1825,8 +1833,10 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
                         }
 
                         r = copy_bytes(fd, fds[2*k+1], (uint64_t) -1, 0);
-                        if (r < 0)
+                        if (r < 0) {
+                                (void) write(error_pipe[1], &r, sizeof(r));
                                 _exit(EXIT_FAILURE);
+                        }
 
                         fds[2*k+1] = safe_close(fds[2*k+1]);
                 }
@@ -1834,6 +1844,8 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
                 _exit(EXIT_SUCCESS);
         }
 
+        error_pipe[1] = safe_close(error_pipe[1]);
+
         for (k = 0; k < _META_MAX; k++) {
                 _cleanup_fclose_ FILE *f = NULL;
 
@@ -1891,11 +1903,16 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
         r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
         child = 0;
         if (r < 0)
-                goto finish;
-        if (r == EX_OSFILE)
-                return -EMEDIUMTYPE; /* No os-release file */
-        if (r == EX_DATAERR)
-                return -ENXIO; /* No root partition */
+                return r;
+
+        n = read(error_pipe[0], &v, sizeof(v));
+        if (n < 0)
+                return -errno;
+        if (n == sizeof(v))
+                return v; /* propagate error sent to us from child */
+        if (n != 0)
+                return -EIO;
+
         if (r != EXIT_SUCCESS)
                 return -EPROTO;