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.
This commit is contained in:
Lennart Poettering 2020-08-11 15:59:44 +02:00
parent af187ab237
commit af8219d562
2 changed files with 62 additions and 36 deletions

View file

@ -323,14 +323,6 @@ static int action_dissect(DissectedImage *m, LoopDevice *d) {
assert(m); assert(m);
assert(d); 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)); printf(" Name: %s\n", basename(arg_image));
if (ioctl(d->fd, BLKGETSIZE64, &size) < 0) 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)); printf(" Size: %s\n", format_bytes(s, sizeof(s), size));
} }
if (m->hostname) putc('\n', stdout);
printf(" Hostname: %s\n", m->hostname);
if (!sd_id128_is_null(m->machine_id)) r = dissected_image_acquire_metadata(m);
printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id)); 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)) { if (!sd_id128_is_null(m->machine_id))
char **p, **q; printf("Machine ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(m->machine_id));
STRV_FOREACH_PAIR(p, q, m->machine_info) if (!strv_isempty(m->machine_info)) {
printf("%s %s=%s\n", char **p, **q;
p == m->machine_info ? "Mach. Info:" : " ",
*p, *q);
}
if (!strv_isempty(m->os_release)) { STRV_FOREACH_PAIR(p, q, m->machine_info)
char **p, **q; printf("%s %s=%s\n",
p == m->machine_info ? "Mach. Info:" : " ",
*p, *q);
}
STRV_FOREACH_PAIR(p, q, m->os_release) if (!strv_isempty(m->os_release)) {
printf("%s %s=%s\n", char **p, **q;
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); putc('\n', stdout);

View file

@ -1772,12 +1772,14 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
}; };
_cleanup_strv_free_ char **machine_info = NULL, **os_release = NULL; _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_(rmdir_and_freep) char *t = NULL;
_cleanup_(sigkill_waitp) pid_t child = 0; _cleanup_(sigkill_waitp) pid_t child = 0;
sd_id128_t machine_id = SD_ID128_NULL; sd_id128_t machine_id = SD_ID128_NULL;
_cleanup_free_ char *hostname = NULL; _cleanup_free_ char *hostname = NULL;
unsigned n_meta_initialized = 0, k; 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); BLOCK_SIGNALS(SIGCHLD);
@ -1793,16 +1795,22 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
if (r < 0) if (r < 0)
goto finish; 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); r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, &child);
if (r < 0) if (r < 0)
goto finish; goto finish;
if (r == 0) { 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); 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) { 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"); log_debug_errno(r, "Failed to mount dissected image: %m");
_exit(EXIT_FAILURE); _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); 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); _exit(EXIT_FAILURE);
}
fds[2*k+1] = safe_close(fds[2*k+1]); fds[2*k+1] = safe_close(fds[2*k+1]);
} }
@ -1834,6 +1844,8 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
error_pipe[1] = safe_close(error_pipe[1]);
for (k = 0; k < _META_MAX; k++) { for (k = 0; k < _META_MAX; k++) {
_cleanup_fclose_ FILE *f = NULL; _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); r = wait_for_terminate_and_check("(sd-dissect)", child, 0);
child = 0; child = 0;
if (r < 0) if (r < 0)
goto finish; return r;
if (r == EX_OSFILE)
return -EMEDIUMTYPE; /* No os-release file */ n = read(error_pipe[0], &v, sizeof(v));
if (r == EX_DATAERR) if (n < 0)
return -ENXIO; /* No root partition */ return -errno;
if (n == sizeof(v))
return v; /* propagate error sent to us from child */
if (n != 0)
return -EIO;
if (r != EXIT_SUCCESS) if (r != EXIT_SUCCESS)
return -EPROTO; return -EPROTO;