<literal>x86-64</literal>.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--offline=</option><arg>BOOL</arg></term>
+
+ <listitem><para>Instructs <command>systemd-repart</command> to build the image offline. Takes a
+ boolean or <literal>auto</literal>. Defaults to <literal>auto</literal>. If enabled, the image is
+ built without using loop devices. This is useful to build images unprivileged or when loop devices
+ are not available. If disabled, the image is always built using loop devices. If
+ <literal>auto</literal>, <command>systemd-repart</command> will build the image online if possible
+ and fall back to building the image offline if loop devices are not available or cannot be accessed
+ due to missing permissions.</para></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
<xi:include href="standard-options.xml" xpointer="no-pager" />
static uint64_t arg_sector_size = 0;
static ImagePolicy *arg_image_policy = NULL;
static Architecture arg_architecture = _ARCHITECTURE_INVALID;
+static int arg_offline = -1;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
/* Loopback block devices are not only useful to turn regular files into block devices, but
* also to cut out sections of block devices into new block devices. */
- r = loop_device_make(whole_fd, O_RDWR, p->offset, size, 0, 0, LOCK_EX, &d);
- if (r < 0 && r != -ENOENT && !ERRNO_IS_PRIVILEGE(r))
- return log_error_errno(r, "Failed to make loopback device of future partition %" PRIu64 ": %m", p->partno);
- if (r >= 0) {
- t->loop = TAKE_PTR(d);
- *ret = TAKE_PTR(t);
- return 0;
+ if (arg_offline <= 0) {
+ r = loop_device_make(whole_fd, O_RDWR, p->offset, size, 0, 0, LOCK_EX, &d);
+ if (r < 0 && (arg_offline == 0 || (r != -ENOENT && !ERRNO_IS_PRIVILEGE(r))))
+ return log_error_errno(r, "Failed to make loopback device of future partition %" PRIu64 ": %m", p->partno);
+ if (r >= 0) {
+ t->loop = TAKE_PTR(d);
+ *ret = TAKE_PTR(t);
+ return 0;
+ }
+
+ log_debug_errno(r, "No access to loop devices, falling back to a regular file");
}
/* If we can't allocate a loop device, let's write to a regular file that we copy into the final
* reflinking support, we can take advantage of this and just reflink the result into the image.
*/
- log_debug_errno(r, "No access to loop devices, falling back to a regular file");
-
r = prepare_temporary_file(t, size);
if (r < 0)
return r;
" but don't populate them yet\n"
" --sector-size=SIZE Set the logical sector size for the image\n"
" --architecture=ARCH Set the generic architecture for the image\n"
+ " --offline=BOOL Whether to build the image offline\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
ARG_SECTOR_SIZE,
ARG_SKIP_PARTITIONS,
ARG_ARCHITECTURE,
+ ARG_OFFLINE,
};
static const struct option options[] = {
{ "defer-partitions", required_argument, NULL, ARG_DEFER_PARTITIONS },
{ "sector-size", required_argument, NULL, ARG_SECTOR_SIZE },
{ "architecture", required_argument, NULL, ARG_ARCHITECTURE },
+ { "offline", required_argument, NULL, ARG_OFFLINE },
{}
};
arg_architecture = r;
break;
+ case ARG_OFFLINE:
+ if (streq(optarg, "auto"))
+ arg_offline = -1;
+ else {
+ r = parse_boolean_argument("--offline=", optarg, NULL);
+ if (r < 0)
+ return r;
+
+ arg_offline = r;
+ }
+
+ break;
+
case '?':
return -EINVAL;