From af8219d5620e53e867a371641dd07185e90f2e18 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Aug 2020 15:59:44 +0200 Subject: [PATCH] dissect: show proper error strings for more errors 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 | 59 ++++++++++++++++++++++---------------- src/shared/dissect-image.c | 39 ++++++++++++++++++------- 2 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index f575e1b28b..d6b6303ee1 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -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); - if (!sd_id128_is_null(m->machine_id)) - printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id)); + 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 (!strv_isempty(m->machine_info)) { - char **p, **q; + if (!sd_id128_is_null(m->machine_id)) + printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id)); - 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->machine_info)) { + char **p, **q; - if (!strv_isempty(m->os_release)) { - 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->os_release) - printf("%s %s=%s\n", - p == m->os_release ? "OS Release:" : " ", - *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); + } } putc('\n', stdout); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index bab587ba13..8cbf4828b8 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -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;