dissect: optionally mkdir directory to overmount

This commit is contained in:
Lennart Poettering 2020-07-28 18:50:17 +02:00
parent 1ffd93683b
commit 5c05f06264
3 changed files with 53 additions and 13 deletions

View File

@ -13,8 +13,10 @@
#include "main-func.h"
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "user-util.h"
#include "util.h"
@ -37,15 +39,21 @@ STATIC_DESTRUCTOR_REGISTER(arg_verity_data, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_hash_sig_path, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_hash_sig, freep);
static void help(void) {
printf("%s [OPTIONS...] IMAGE\n"
"%s [OPTIONS...] --mount IMAGE PATH\n"
"Dissect a file system OS image.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" -m --mount Mount the image to the specified directory\n"
static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
r = terminal_urlify_man("systemd-dissect", "1", &link);
if (r < 0)
return log_oom();
printf("%1$s [OPTIONS...] IMAGE\n"
"%1$s [OPTIONS...] --mount IMAGE PATH\n\n"
"%5$sDissect a file system OS image.%6$s\n\n"
"%3$sOptions:%4$s\n"
" -r --read-only Mount read-only\n"
" --fsck=BOOL Run fsck before mounting\n"
" --mkdir Make mount directory before mounting, if missing\n"
" --discard=MODE Choose 'discard' mode (disabled, loop, all, crypto)\n"
" --root-hash=HASH Specify root hash for verity\n"
" --root-hash-sig=SIG Specify pkcs7 signature of root hash for verity\n"
@ -53,9 +61,19 @@ static void help(void) {
" or as an ASCII base64 encoded string prefixed by\n"
" 'base64:'\n"
" --verity-data=PATH Specify data file with hash tree for verity if it is\n"
" not embedded in IMAGE\n",
program_invocation_short_name,
program_invocation_short_name);
" not embedded in IMAGE\n"
"\n%3$sCommands:%4$s\n"
" -h --help Show this help\n"
" --version Show package version\n"
" -m --mount Mount the image to the specified directory\n"
" -M Shortcut for --mount --mkdir\n"
"\nSee the %2$s for details.\n"
, program_invocation_short_name
, link
, ansi_underline(), ansi_normal()
, ansi_highlight(), ansi_normal());
return 0;
}
static int parse_argv(int argc, char *argv[]) {
@ -67,6 +85,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_FSCK,
ARG_VERITY_DATA,
ARG_ROOT_HASH_SIG,
ARG_MKDIR,
};
static const struct option options[] = {
@ -79,6 +98,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "fsck", required_argument, NULL, ARG_FSCK },
{ "verity-data", required_argument, NULL, ARG_VERITY_DATA },
{ "root-hash-sig", required_argument, NULL, ARG_ROOT_HASH_SIG },
{ "mkdir", no_argument, NULL, ARG_MKDIR },
{}
};
@ -87,13 +107,12 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "hmr", options, NULL)) >= 0) {
while ((c = getopt_long(argc, argv, "hmrM", options, NULL)) >= 0) {
switch (c) {
case 'h':
help();
return 0;
return help();
case ARG_VERSION:
return version();
@ -102,6 +121,16 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_MOUNT;
break;
case ARG_MKDIR:
arg_flags |= DISSECT_IMAGE_MKDIR;
break;
case 'M':
/* Shortcut combination of the above two */
arg_action = ACTION_MOUNT;
arg_flags |= DISSECT_IMAGE_MKDIR;
break;
case 'r':
arg_flags |= DISSECT_IMAGE_READ_ONLY;
break;

View File

@ -1047,6 +1047,12 @@ static int mount_partition(
if (!strextend_with_separator(&options, ",", m->mount_options, NULL))
return -ENOMEM;
if (FLAGS_SET(flags, DISSECT_IMAGE_MKDIR)) {
r = mkdir_p(p, 0755);
if (r < 0)
return r;
}
r = mount_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
if (r < 0)
return r;
@ -1080,6 +1086,10 @@ int dissected_image_mount(DissectedImage *m, const char *where, uid_t uid_shift,
if (flags & DISSECT_IMAGE_MOUNT_ROOT_ONLY)
return 0;
/* Mask DISSECT_IMAGE_MKDIR for all subdirs: the idea is that only the top-level mount point is
* created if needed, but the image itself not modified. */
flags &= ~DISSECT_IMAGE_MKDIR;
r = mount_partition(m->partitions + PARTITION_HOME, where, "/home", uid_shift, flags);
if (r < 0)
return r;

View File

@ -69,6 +69,7 @@ typedef enum DissectImageFlags {
DISSECT_IMAGE_FSCK = 1 << 11, /* File system check the partition before mounting (no effect when combined with DISSECT_IMAGE_READ_ONLY) */
DISSECT_IMAGE_NO_PARTITION_TABLE = 1 << 12, /* Only recognize single file system images */
DISSECT_IMAGE_VERITY_SHARE = 1 << 13, /* When activating a verity device, reuse existing one if already open */
DISSECT_IMAGE_MKDIR = 1 << 14, /* Make directory to mount right before mounting, if missing */
} DissectImageFlags;
struct DissectedImage {