summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd-dissect.xml19
-rw-r--r--src/dissect/dissect.c25
2 files changed, 44 insertions, 0 deletions
diff --git a/man/systemd-dissect.xml b/man/systemd-dissect.xml
index 1d0532713d..06c57a22ec 100644
--- a/man/systemd-dissect.xml
+++ b/man/systemd-dissect.xml
@@ -386,6 +386,25 @@
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--loop-ref=</option></term>
+
+ <listitem><para>Configures the "reference" string the kernel shall report as backing file for the
+ loopback block device. While this is supposed to be a path or filename referencing the backing file,
+ this is not enforced and the kernel accepts arbitrary free-form strings, chosen by the user. Accepts
+ arbitrary strings up to a length of 63 characters. This sets the kernel's
+ <literal>.lo_file_name</literal> field for the block device. Note this is distinct from the
+ <filename>/sys/class/block/loopX/loop/backing_file</filename> attribute file that always reports a
+ path referring to the actual backing file. The latter is subject to mount namespace translation, the
+ former is not.</para>
+
+ <para>This setting is particularly useful in combination with the <option>--attach</option> command,
+ as it allows later referencing the allocated loop device via <filename>/dev/loop/by-ref/…</filename>
+ symlinks. Example: first, set up the loopback device via <command>systemd-dissect attach
+ --loop-ref=quux foo.raw</command>, and then reference it in a command via the specified filename:
+ <command>cfdisk /dev/loop/by-ref/quux</command>.</para></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="no-pager" />
<xi:include href="standard-options.xml" xpointer="no-legend" />
<xi:include href="standard-options.xml" xpointer="json" />
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 6f7b44f0aa..a688e6f32c 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -81,9 +81,11 @@ static bool arg_legend = true;
static bool arg_rmdir = false;
static bool arg_in_memory = false;
static char **arg_argv = NULL;
+static char *arg_loop_ref = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_verity_settings, verity_settings_done);
STATIC_DESTRUCTOR_REGISTER(arg_argv, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(arg_loop_ref, freep);
static int help(void) {
_cleanup_free_ char *link = NULL;
@@ -123,6 +125,7 @@ static int help(void) {
" not embedded in IMAGE\n"
" --json=pretty|short|off\n"
" Generate JSON output\n"
+ " --loop-ref=NAME Set reference string for loopback device\n"
"\n%3$sCommands:%4$s\n"
" -h --help Show this help\n"
" --version Show package version\n"
@@ -214,6 +217,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DISCOVER,
ARG_ATTACH,
ARG_DETACH,
+ ARG_LOOP_REF,
};
static const struct option options[] = {
@@ -242,6 +246,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "copy-to", no_argument, NULL, 'a' },
{ "json", required_argument, NULL, ARG_JSON },
{ "discover", no_argument, NULL, ARG_DISCOVER },
+ { "loop-ref", required_argument, NULL, ARG_LOOP_REF },
{}
};
@@ -435,6 +440,20 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_DISCOVER;
break;
+ case ARG_LOOP_REF:
+ if (isempty(optarg)) {
+ arg_loop_ref = mfree(arg_loop_ref);
+ break;
+ }
+
+ if (strlen(optarg) >= sizeof_field(struct loop_info64, lo_file_name))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Loop device ref string '%s' is too long.", optarg);
+
+ r = free_and_strdup_warn(&arg_loop_ref, optarg);
+ if (r < 0)
+ return r;
+ break;
+
case '?':
return -EINVAL;
@@ -1671,6 +1690,12 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return log_error_errno(r, "Failed to set up loopback device for %s: %m", arg_image);
+ if (arg_loop_ref) {
+ r = loop_device_set_filename(d, arg_loop_ref);
+ if (r < 0)
+ log_warning_errno(r, "Failed to set loop reference string to '%s', ignoring: %m", arg_loop_ref);
+ }
+
r = dissect_loop_device_and_warn(
d,
&arg_verity_settings,