Compare commits
No commits in common. "992aa67231ea1fbf94374c821f523fda694f2fcb" and "fdc6c4f49c808baafb9bb0e01b617b4f3471f46b" have entirely different histories.
992aa67231
...
fdc6c4f49c
9
TODO
9
TODO
|
@ -120,9 +120,9 @@ Features:
|
||||||
this, it's useful to have one that can dump contents of them, too.
|
this, it's useful to have one that can dump contents of them, too.
|
||||||
|
|
||||||
* All tools that support --root= should also learn --image= so that they can
|
* All tools that support --root= should also learn --image= so that they can
|
||||||
operate on disk images directly. Specifically: bootctl, systemctl,
|
operate on disk images directly. Specifically: bootctl, tmpfiles, sysusers,
|
||||||
coredumpctl. (Already done: systemd-nspawn, systemd-firstboot,
|
systemctl, repart, journalctl, coredumpctl. (Already done: systemd-nspawn,
|
||||||
systemd-repart, systemd-tmpfiles, systemd-sysusers, journalctl)
|
systemd-firstboot)
|
||||||
|
|
||||||
* seccomp: by default mask x32 ABI system wide on x86-64. it's on its way out
|
* seccomp: by default mask x32 ABI system wide on x86-64. it's on its way out
|
||||||
|
|
||||||
|
@ -337,6 +337,9 @@ Features:
|
||||||
right) become genuine first class citizens, and we gain automatic, sane JSON
|
right) become genuine first class citizens, and we gain automatic, sane JSON
|
||||||
output for them.
|
output for them.
|
||||||
|
|
||||||
|
* systemd-firstboot: teach it dissector magic, so that you can point it to some
|
||||||
|
disk image and it will just set everything in it all behind the scenes.
|
||||||
|
|
||||||
* We should probably replace /var/log/README, /etc/rc.d/README with symlinks
|
* We should probably replace /var/log/README, /etc/rc.d/README with symlinks
|
||||||
that are linked to these places instead of copied. After all they are
|
that are linked to these places instead of copied. After all they are
|
||||||
constant vendor data.
|
constant vendor data.
|
||||||
|
|
|
@ -756,29 +756,16 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--root=<replaceable>ROOT</replaceable></option></term>
|
<term><option>--root=<replaceable>ROOT</replaceable></option></term>
|
||||||
|
|
||||||
<listitem><para>Takes a directory path as an argument. If specified, <command>journalctl</command>
|
<listitem><para>Takes a directory path as an argument. If
|
||||||
will operate on journal directories and catalog file hierarchy underneath the specified directory
|
specified, journalctl will operate on journal directories and catalog file hierarchy
|
||||||
instead of the root directory (e.g. <option>--update-catalog</option> will create
|
underneath the specified directory instead of the root
|
||||||
<filename><replaceable>ROOT</replaceable>/var/lib/systemd/catalog/database</filename>, and journal
|
directory (e.g. <option>--update-catalog</option> will create
|
||||||
files under <filename><replaceable>ROOT</replaceable>/run/journal/</filename> or
|
<filename><replaceable>ROOT</replaceable>/var/lib/systemd/catalog/database</filename>,
|
||||||
<filename><replaceable>ROOT</replaceable>/var/log/journal/</filename> will be displayed).
|
and journal files under <filename><replaceable>ROOT</replaceable>/run/journal/</filename>
|
||||||
|
or <filename><replaceable>ROOT</replaceable>/var/log/journal/</filename> will be displayed).
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>--image=<replaceable>IMAGE</replaceable></option></term>
|
|
||||||
|
|
||||||
<listitem><para>Takes a path to a disk image file or block device node. If specified,
|
|
||||||
<command>journalctl</command> will operate on the file system in the indicated disk image. This is
|
|
||||||
similar to <option>--root=</option> but operates on file systems stored in disk images or block
|
|
||||||
devices, thus providing an easy way to extract log data from disk images. The disk image should
|
|
||||||
either contain just a file system or a set of file systems within a GPT partition table, following
|
|
||||||
the <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions
|
|
||||||
Specification</ulink>. For further information on supported disk images, see
|
|
||||||
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
|
||||||
switch of the same name.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--namespace=<replaceable>NAMESPACE</replaceable></option></term>
|
<term><option>--namespace=<replaceable>NAMESPACE</replaceable></option></term>
|
||||||
|
|
||||||
|
|
|
@ -68,19 +68,6 @@
|
||||||
paths. </para></listitem>
|
paths. </para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>--image=<replaceable>image</replaceable></option></term>
|
|
||||||
|
|
||||||
<listitem><para>Takes a path to a disk image file or block device node. If specified all operations
|
|
||||||
are applied to file system in the indicated disk image. This is similar to <option>--root=</option>
|
|
||||||
but operates on file systems stored in disk images or block devices. The disk image should either
|
|
||||||
contain just a file system or a set of file systems within a GPT partition table, following the
|
|
||||||
<ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions
|
|
||||||
Specification</ulink>. For further information on supported disk images, see
|
|
||||||
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
|
||||||
switch of the same name.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--replace=<replaceable>PATH</replaceable></option></term>
|
<term><option>--replace=<replaceable>PATH</replaceable></option></term>
|
||||||
<listitem><para>When this option is given, one ore more positional arguments
|
<listitem><para>When this option is given, one ore more positional arguments
|
||||||
|
|
|
@ -149,7 +149,6 @@
|
||||||
the specified prefix. This option can be specified multiple
|
the specified prefix. This option can be specified multiple
|
||||||
times.</para></listitem>
|
times.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--exclude-prefix=<replaceable>path</replaceable></option></term>
|
<term><option>--exclude-prefix=<replaceable>path</replaceable></option></term>
|
||||||
<listitem><para>Ignore rules with paths that start with the
|
<listitem><para>Ignore rules with paths that start with the
|
||||||
|
@ -157,16 +156,6 @@
|
||||||
times.</para></listitem>
|
times.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>-E</option></term>
|
|
||||||
<listitem><para>A shortcut for <literal>--exclude-prefix=/dev --exclude-prefix=/proc
|
|
||||||
--exclude-prefix=/run --exclude-prefix=/sys</literal>, i.e. exclude the hierarchies typically backed
|
|
||||||
by virtual or memory file systems. This is useful in combination with <option>--root=</option>, if
|
|
||||||
the specified directory tree contains an OS tree without these virtual/memory file systems mounted
|
|
||||||
in, as it is typically not desirable to create any files and directories below these subdirectories
|
|
||||||
if they are supposed to be overmounted during runtime.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--root=<replaceable>root</replaceable></option></term>
|
<term><option>--root=<replaceable>root</replaceable></option></term>
|
||||||
<listitem><para>Takes a directory path as an argument. All paths will be prefixed with the given alternate
|
<listitem><para>Takes a directory path as an argument. All paths will be prefixed with the given alternate
|
||||||
|
@ -175,26 +164,7 @@
|
||||||
<para>When this option is used, the libc Name Service Switch (NSS) is bypassed for resolving users
|
<para>When this option is used, the libc Name Service Switch (NSS) is bypassed for resolving users
|
||||||
and groups. Instead the files <filename>/etc/passwd</filename> and <filename>/etc/group</filename>
|
and groups. Instead the files <filename>/etc/passwd</filename> and <filename>/etc/group</filename>
|
||||||
inside the alternate root are read directly. This means that users/groups not listed in these files
|
inside the alternate root are read directly. This means that users/groups not listed in these files
|
||||||
will not be resolved, i.e. LDAP NIS and other complex databases are not considered.</para>
|
will not be resolved, i.e. LDAP NIS and other complex databases are not considered.</para></listitem>
|
||||||
|
|
||||||
<para>Consider combining this with <option>-E</option> to ensure the invocation does not create files
|
|
||||||
or directories below mount points in the OS image operated on that are typically overmounted during
|
|
||||||
runtime.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><option>--image=<replaceable>image</replaceable></option></term>
|
|
||||||
|
|
||||||
<listitem><para>Takes a path to a disk image file or block device node. If specified all operations
|
|
||||||
are applied to file system in the indicated disk image. This is similar to <option>--root=</option>
|
|
||||||
but operates on file systems stored in disk images or block devices. The disk image should either
|
|
||||||
contain just a file system or a set of file systems within a GPT partition table, following the
|
|
||||||
<ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions
|
|
||||||
Specification</ulink>. For further information on supported disk images, see
|
|
||||||
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
|
||||||
switch of the same name.</para>
|
|
||||||
|
|
||||||
<para>Implies <option>-E</option>.</para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "kbd-util.h"
|
#include "kbd-util.h"
|
||||||
#include "libcrypt-util.h"
|
#include "libcrypt-util.h"
|
||||||
#include "locale-util.h"
|
#include "locale-util.h"
|
||||||
|
#include "loop-util.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
|
@ -906,6 +907,75 @@ static int process_kernel_cmdline(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setup_image(char **ret_mount_dir, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image) {
|
||||||
|
DissectImageFlags f = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK;
|
||||||
|
_cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
|
||||||
|
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
||||||
|
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
||||||
|
_cleanup_(rmdir_and_freep) char *mount_dir = NULL;
|
||||||
|
_cleanup_free_ char *temp = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!arg_image) {
|
||||||
|
*ret_mount_dir = NULL;
|
||||||
|
*ret_decrypted_image = NULL;
|
||||||
|
*ret_loop_device = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!arg_root);
|
||||||
|
|
||||||
|
r = tempfn_random_child(NULL, "firstboot", &temp);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to generate temporary mount directory: %m");
|
||||||
|
|
||||||
|
r = loop_device_make_by_path(arg_image, O_RDWR, LO_FLAGS_PARTSCAN, &d);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to set up loopback device: %m");
|
||||||
|
|
||||||
|
r = dissect_image_and_warn(d->fd, arg_image, NULL, 0, NULL, NULL, f, &dissected_image);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = dissected_image_decrypt_interactively(dissected_image, NULL, NULL, 0, NULL, NULL, NULL, 0, f, &decrypted_image);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = detach_mount_namespace();
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to detach mount namespace: %m");
|
||||||
|
|
||||||
|
mount_dir = strdup(temp);
|
||||||
|
if (!mount_dir)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
r = mkdir_p(mount_dir, 0700);
|
||||||
|
if (r < 0) {
|
||||||
|
mount_dir = mfree(mount_dir);
|
||||||
|
return log_error_errno(r, "Failed to create mount point: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dissected_image_mount(dissected_image, mount_dir, UID_INVALID, f);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to mount image: %m");
|
||||||
|
|
||||||
|
if (decrypted_image) {
|
||||||
|
r = decrypted_image_relinquish(decrypted_image);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to relinquish DM devices: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_device_relinquish(d);
|
||||||
|
|
||||||
|
arg_root = TAKE_PTR(temp);
|
||||||
|
|
||||||
|
*ret_mount_dir = TAKE_PTR(mount_dir);
|
||||||
|
*ret_decrypted_image = TAKE_PTR(decrypted_image);
|
||||||
|
*ret_loop_device = TAKE_PTR(d);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int help(void) {
|
static int help(void) {
|
||||||
_cleanup_free_ char *link = NULL;
|
_cleanup_free_ char *link = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -1283,22 +1353,9 @@ static int run(int argc, char *argv[]) {
|
||||||
return 0; /* disabled */
|
return 0; /* disabled */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg_image) {
|
r = setup_image(&unlink_dir, &loop_device, &decrypted_image);
|
||||||
assert(!arg_root);
|
if (r < 0)
|
||||||
|
return r;
|
||||||
r = mount_image_privately_interactively(
|
|
||||||
arg_image,
|
|
||||||
DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
|
|
||||||
&unlink_dir,
|
|
||||||
&loop_device,
|
|
||||||
&decrypted_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
arg_root = strdup(unlink_dir);
|
|
||||||
if (!arg_root)
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
r = process_locale();
|
r = process_locale();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "chattr-util.h"
|
#include "chattr-util.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "device-private.h"
|
#include "device-private.h"
|
||||||
#include "dissect-image.h"
|
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
|
@ -52,7 +51,6 @@
|
||||||
#include "logs-show.h"
|
#include "logs-show.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "mount-util.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
|
@ -123,7 +121,6 @@ static bool arg_reverse = false;
|
||||||
static int arg_journal_type = 0;
|
static int arg_journal_type = 0;
|
||||||
static int arg_namespace_flags = 0;
|
static int arg_namespace_flags = 0;
|
||||||
static char *arg_root = NULL;
|
static char *arg_root = NULL;
|
||||||
static char *arg_image = NULL;
|
|
||||||
static const char *arg_machine = NULL;
|
static const char *arg_machine = NULL;
|
||||||
static const char *arg_namespace = NULL;
|
static const char *arg_namespace = NULL;
|
||||||
static uint64_t arg_vacuum_size = 0;
|
static uint64_t arg_vacuum_size = 0;
|
||||||
|
@ -378,7 +375,6 @@ static int help(void) {
|
||||||
" -D --directory=PATH Show journal files from directory\n"
|
" -D --directory=PATH Show journal files from directory\n"
|
||||||
" --file=PATH Show journal file\n"
|
" --file=PATH Show journal file\n"
|
||||||
" --root=ROOT Operate on files below a root directory\n"
|
" --root=ROOT Operate on files below a root directory\n"
|
||||||
" --image=IMAGE Operate on files in filesystem image\n"
|
|
||||||
" --namespace=NAMESPACE Show journal data from specified namespace\n"
|
" --namespace=NAMESPACE Show journal data from specified namespace\n"
|
||||||
" --interval=TIME Time interval for changing the FSS sealing key\n"
|
" --interval=TIME Time interval for changing the FSS sealing key\n"
|
||||||
" --verify-key=KEY Specify FSS verification key\n"
|
" --verify-key=KEY Specify FSS verification key\n"
|
||||||
|
@ -426,7 +422,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_USER,
|
ARG_USER,
|
||||||
ARG_SYSTEM,
|
ARG_SYSTEM,
|
||||||
ARG_ROOT,
|
ARG_ROOT,
|
||||||
ARG_IMAGE,
|
|
||||||
ARG_HEADER,
|
ARG_HEADER,
|
||||||
ARG_FACILITY,
|
ARG_FACILITY,
|
||||||
ARG_SETUP_KEYS,
|
ARG_SETUP_KEYS,
|
||||||
|
@ -483,7 +478,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
{ "directory", required_argument, NULL, 'D' },
|
{ "directory", required_argument, NULL, 'D' },
|
||||||
{ "file", required_argument, NULL, ARG_FILE },
|
{ "file", required_argument, NULL, ARG_FILE },
|
||||||
{ "root", required_argument, NULL, ARG_ROOT },
|
{ "root", required_argument, NULL, ARG_ROOT },
|
||||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
|
||||||
{ "header", no_argument, NULL, ARG_HEADER },
|
{ "header", no_argument, NULL, ARG_HEADER },
|
||||||
{ "identifier", required_argument, NULL, 't' },
|
{ "identifier", required_argument, NULL, 't' },
|
||||||
{ "priority", required_argument, NULL, 'p' },
|
{ "priority", required_argument, NULL, 'p' },
|
||||||
|
@ -719,13 +713,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_ROOT:
|
case ARG_ROOT:
|
||||||
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ true, &arg_root);
|
r = parse_path_argument_and_warn(optarg, true, &arg_root);
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARG_IMAGE:
|
|
||||||
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_image);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
@ -1055,8 +1043,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
|
if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
|
||||||
arg_lines = 10;
|
arg_lines = 10;
|
||||||
|
|
||||||
if (!!arg_directory + !!arg_file + !!arg_machine + !!arg_root + !!arg_image > 1) {
|
if (!!arg_directory + !!arg_file + !!arg_machine + !!arg_root > 1) {
|
||||||
log_error("Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root=, --image=.");
|
log_error("Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root.");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2096,9 +2084,6 @@ static int wait_for_change(sd_journal *j, int poll_fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
|
||||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
|
||||||
_cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
|
|
||||||
bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false;
|
bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false;
|
||||||
bool use_cursor = false, after_cursor = false;
|
bool use_cursor = false, after_cursor = false;
|
||||||
_cleanup_(sd_journal_closep) sd_journal *j = NULL;
|
_cleanup_(sd_journal_closep) sd_journal *j = NULL;
|
||||||
|
@ -2116,24 +2101,6 @@ int main(int argc, char *argv[]) {
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
if (arg_image) {
|
|
||||||
assert(!arg_root);
|
|
||||||
|
|
||||||
r = mount_image_privately_interactively(
|
|
||||||
arg_image,
|
|
||||||
DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|
|
|
||||||
(arg_action == ACTION_UPDATE_CATALOG ? DISSECT_IMAGE_FSCK : DISSECT_IMAGE_READ_ONLY),
|
|
||||||
&unlink_dir,
|
|
||||||
&loop_device,
|
|
||||||
&decrypted_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
arg_root = strdup(unlink_dir);
|
|
||||||
if (!arg_root)
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
signal(SIGWINCH, columns_lines_cache_reset);
|
signal(SIGWINCH, columns_lines_cache_reset);
|
||||||
sigbus_install();
|
sigbus_install();
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,8 @@
|
||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
#include "id128-util.h"
|
#include "id128-util.h"
|
||||||
#include "mkdir.h"
|
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "namespace-util.h"
|
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
#include "os-util.h"
|
#include "os-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
@ -1942,84 +1940,9 @@ const char* mount_options_from_part(const MountOptions *options, unsigned int pa
|
||||||
LIST_FOREACH(mount_options, m, (MountOptions *)options)
|
LIST_FOREACH(mount_options, m, (MountOptions *)options)
|
||||||
if (partition_number == m->partition_number && !isempty(m->options))
|
if (partition_number == m->partition_number && !isempty(m->options))
|
||||||
return m->options;
|
return m->options;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mount_image_privately_interactively(
|
|
||||||
const char *image,
|
|
||||||
DissectImageFlags flags,
|
|
||||||
char **ret_directory,
|
|
||||||
LoopDevice **ret_loop_device,
|
|
||||||
DecryptedImage **ret_decrypted_image) {
|
|
||||||
|
|
||||||
_cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
|
|
||||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
|
||||||
_cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
|
|
||||||
_cleanup_(rmdir_and_freep) char *created_dir = NULL;
|
|
||||||
_cleanup_free_ char *temp = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Mounts an OS image at a temporary place, inside a newly created mount namespace of our own. This
|
|
||||||
* is used by tools such as systemd-tmpfiles or systemd-firstboot to operate on some disk image
|
|
||||||
* easily. */
|
|
||||||
|
|
||||||
assert(image);
|
|
||||||
assert(ret_directory);
|
|
||||||
assert(ret_loop_device);
|
|
||||||
assert(ret_decrypted_image);
|
|
||||||
|
|
||||||
r = tempfn_random_child(NULL, program_invocation_short_name, &temp);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to generate temporary mount directory: %m");
|
|
||||||
|
|
||||||
r = loop_device_make_by_path(
|
|
||||||
image,
|
|
||||||
FLAGS_SET(flags, DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : O_RDWR,
|
|
||||||
FLAGS_SET(flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
|
|
||||||
&d);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to set up loopback device: %m");
|
|
||||||
|
|
||||||
r = dissect_image_and_warn(d->fd, image, NULL, 0, NULL, NULL, flags, &dissected_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = dissected_image_decrypt_interactively(dissected_image, NULL, NULL, 0, NULL, NULL, NULL, 0, flags, &decrypted_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = detach_mount_namespace();
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to detach mount namespace: %m");
|
|
||||||
|
|
||||||
r = mkdir_p(temp, 0700);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to create mount point: %m");
|
|
||||||
|
|
||||||
created_dir = TAKE_PTR(temp);
|
|
||||||
|
|
||||||
r = dissected_image_mount(dissected_image, created_dir, UID_INVALID, flags);
|
|
||||||
if (r == -EUCLEAN)
|
|
||||||
return log_error_errno(r, "File system check on image failed: %m");
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to mount image: %m");
|
|
||||||
|
|
||||||
if (decrypted_image) {
|
|
||||||
r = decrypted_image_relinquish(decrypted_image);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to relinquish DM devices: %m");
|
|
||||||
}
|
|
||||||
|
|
||||||
loop_device_relinquish(d);
|
|
||||||
|
|
||||||
*ret_directory = TAKE_PTR(created_dir);
|
|
||||||
*ret_loop_device = TAKE_PTR(d);
|
|
||||||
*ret_decrypted_image = TAKE_PTR(decrypted_image);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *const partition_designator_table[] = {
|
static const char *const partition_designator_table[] = {
|
||||||
[PARTITION_ROOT] = "root",
|
[PARTITION_ROOT] = "root",
|
||||||
[PARTITION_ROOT_SECONDARY] = "root-secondary",
|
[PARTITION_ROOT_SECONDARY] = "root-secondary",
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "loop-util.h"
|
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
|
||||||
typedef struct DissectedImage DissectedImage;
|
typedef struct DissectedImage DissectedImage;
|
||||||
|
@ -118,5 +117,3 @@ int partition_designator_from_string(const char *name) _pure_;
|
||||||
int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data, char **ret_roothashsig);
|
int verity_metadata_load(const char *image, const char *root_hash_path, void **ret_roothash, size_t *ret_roothash_size, char **ret_verity_data, char **ret_roothashsig);
|
||||||
bool dissected_image_can_do_verity(const DissectedImage *image, unsigned partition_designator);
|
bool dissected_image_can_do_verity(const DissectedImage *image, unsigned partition_designator);
|
||||||
bool dissected_image_has_verity(const DissectedImage *image, unsigned partition_designator);
|
bool dissected_image_has_verity(const DissectedImage *image, unsigned partition_designator);
|
||||||
|
|
||||||
int mount_image_privately_interactively(const char *path, DissectImageFlags flags, char **ret_directory, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image);
|
|
||||||
|
|
|
@ -168,12 +168,8 @@ typedef struct ParseFieldVec {
|
||||||
size_t *target_len;
|
size_t *target_len;
|
||||||
} ParseFieldVec;
|
} ParseFieldVec;
|
||||||
|
|
||||||
#define PARSE_FIELD_VEC_ENTRY(_field, _target, _target_len) { \
|
#define PARSE_FIELD_VEC_ENTRY(_field, _target, _target_len) \
|
||||||
.field = _field, \
|
{ .field = _field, .field_len = strlen(_field), .target = _target, .target_len = _target_len }
|
||||||
.field_len = strlen(_field), \
|
|
||||||
.target = _target, \
|
|
||||||
.target_len = _target_len \
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_fieldv(const void *data, size_t length, const ParseFieldVec *fields, unsigned n_fields) {
|
static int parse_fieldv(const void *data, size_t length, const ParseFieldVec *fields, unsigned n_fields) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
@ -1126,17 +1122,19 @@ static int output_cat_field(
|
||||||
FILE *f,
|
FILE *f,
|
||||||
sd_journal *j,
|
sd_journal *j,
|
||||||
OutputFlags flags,
|
OutputFlags flags,
|
||||||
int prio,
|
|
||||||
const char *field,
|
const char *field,
|
||||||
const size_t highlight[2]) {
|
const size_t highlight[2]) {
|
||||||
|
|
||||||
const char *color_on = "", *color_off = "", *highlight_on = "";
|
const char *highlight_on, *highlight_off;
|
||||||
const void *data;
|
const void *data;
|
||||||
size_t l, fl;
|
size_t l, fl;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (FLAGS_SET(flags, OUTPUT_COLOR))
|
if (FLAGS_SET(flags, OUTPUT_COLOR)) {
|
||||||
get_log_colors(prio, &color_on, &color_off, &highlight_on);
|
highlight_on = ANSI_HIGHLIGHT_RED;
|
||||||
|
highlight_off = ANSI_NORMAL;
|
||||||
|
} else
|
||||||
|
highlight_on = highlight_off = "";
|
||||||
|
|
||||||
r = sd_journal_get_data(j, field, &data, &l);
|
r = sd_journal_get_data(j, field, &data, &l);
|
||||||
if (r == -EBADMSG) {
|
if (r == -EBADMSG) {
|
||||||
|
@ -1155,23 +1153,15 @@ static int output_cat_field(
|
||||||
data = (const uint8_t*) data + fl + 1;
|
data = (const uint8_t*) data + fl + 1;
|
||||||
l -= fl + 1;
|
l -= fl + 1;
|
||||||
|
|
||||||
if (FLAGS_SET(flags, OUTPUT_COLOR)) {
|
if (highlight && FLAGS_SET(flags, OUTPUT_COLOR)) {
|
||||||
if (highlight) {
|
assert(highlight[0] <= highlight[1]);
|
||||||
assert(highlight[0] <= highlight[1]);
|
assert(highlight[1] <= l);
|
||||||
assert(highlight[1] <= l);
|
|
||||||
|
|
||||||
fputs(color_on, f);
|
fwrite((const char*) data, 1, highlight[0], f);
|
||||||
fwrite((const char*) data, 1, highlight[0], f);
|
fwrite(highlight_on, 1, strlen(highlight_on), f);
|
||||||
fputs(highlight_on, f);
|
fwrite((const char*) data + highlight[0], 1, highlight[1] - highlight[0], f);
|
||||||
fwrite((const char*) data + highlight[0], 1, highlight[1] - highlight[0], f);
|
fwrite(highlight_off, 1, strlen(highlight_off), f);
|
||||||
fputs(color_on, f);
|
fwrite((const char*) data + highlight[1], 1, l - highlight[1], f);
|
||||||
fwrite((const char*) data + highlight[1], 1, l - highlight[1], f);
|
|
||||||
fputs(color_off, f);
|
|
||||||
} else {
|
|
||||||
fputs(color_on, f);
|
|
||||||
fwrite((const char*) data, 1, l, f);
|
|
||||||
fputs(color_off, f);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
fwrite((const char*) data, 1, l, f);
|
fwrite((const char*) data, 1, l, f);
|
||||||
|
|
||||||
|
@ -1188,44 +1178,20 @@ static int output_cat(
|
||||||
const Set *output_fields,
|
const Set *output_fields,
|
||||||
const size_t highlight[2]) {
|
const size_t highlight[2]) {
|
||||||
|
|
||||||
int r, prio = LOG_INFO;
|
|
||||||
const char *field;
|
const char *field;
|
||||||
Iterator iterator;
|
Iterator iterator;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(j);
|
assert(j);
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
(void) sd_journal_set_data_threshold(j, 0);
|
(void) sd_journal_set_data_threshold(j, 0);
|
||||||
|
|
||||||
if (FLAGS_SET(flags, OUTPUT_COLOR)) {
|
|
||||||
const void *data;
|
|
||||||
size_t l;
|
|
||||||
|
|
||||||
/* Determine priority of this entry, so that we can color it nicely */
|
|
||||||
|
|
||||||
r = sd_journal_get_data(j, "PRIORITY", &data, &l);
|
|
||||||
if (r == -EBADMSG) {
|
|
||||||
log_debug_errno(r, "Skipping message we can't read: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (r < 0) {
|
|
||||||
if (r != -ENOENT)
|
|
||||||
return log_error_errno(r, "Failed to get data: %m");
|
|
||||||
|
|
||||||
/* An entry without PRIORITY */
|
|
||||||
} else if (l == 10 && memcmp(data, "PRIORITY=", 9) == 0) {
|
|
||||||
char c = ((char*) data)[9];
|
|
||||||
|
|
||||||
if (c >= '0' && c <= '7')
|
|
||||||
prio = c - '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set_isempty(output_fields))
|
if (set_isempty(output_fields))
|
||||||
return output_cat_field(f, j, flags, prio, "MESSAGE", highlight);
|
return output_cat_field(f, j, flags, "MESSAGE", highlight);
|
||||||
|
|
||||||
SET_FOREACH(field, output_fields, iterator) {
|
SET_FOREACH(field, output_fields, iterator) {
|
||||||
r = output_cat_field(f, j, flags, prio, field, streq(field, "MESSAGE") ? highlight : NULL);
|
r = output_cat_field(f, j, flags, field, streq(field, "MESSAGE") ? highlight : NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,19 +7,17 @@
|
||||||
#include "conf-files.h"
|
#include "conf-files.h"
|
||||||
#include "copy.h"
|
#include "copy.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "dissect-image.h"
|
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "mount-util.h"
|
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
#include "selinux-util.h"
|
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
|
#include "selinux-util.h"
|
||||||
#include "smack-util.h"
|
#include "smack-util.h"
|
||||||
#include "specifier.h"
|
#include "specifier.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
@ -65,7 +63,6 @@ typedef struct Item {
|
||||||
} Item;
|
} Item;
|
||||||
|
|
||||||
static char *arg_root = NULL;
|
static char *arg_root = NULL;
|
||||||
static char *arg_image = NULL;
|
|
||||||
static bool arg_cat_config = false;
|
static bool arg_cat_config = false;
|
||||||
static const char *arg_replace = NULL;
|
static const char *arg_replace = NULL;
|
||||||
static bool arg_inline = false;
|
static bool arg_inline = false;
|
||||||
|
@ -96,7 +93,6 @@ STATIC_DESTRUCTOR_REGISTER(database_by_groupname, hashmap_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(database_groups, set_free_freep);
|
STATIC_DESTRUCTOR_REGISTER(database_groups, set_free_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(uid_range, freep);
|
STATIC_DESTRUCTOR_REGISTER(uid_range, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
|
||||||
|
|
||||||
static int errno_is_not_exists(int code) {
|
static int errno_is_not_exists(int code) {
|
||||||
/* See getpwnam(3) and getgrnam(3): those codes and others can be returned if the user or group are
|
/* See getpwnam(3) and getgrnam(3): those codes and others can be returned if the user or group are
|
||||||
|
@ -1743,7 +1739,6 @@ static int help(void) {
|
||||||
" --version Show package version\n"
|
" --version Show package version\n"
|
||||||
" --cat-config Show configuration files\n"
|
" --cat-config Show configuration files\n"
|
||||||
" --root=PATH Operate on an alternate filesystem root\n"
|
" --root=PATH Operate on an alternate filesystem root\n"
|
||||||
" --image=PATH Operate on disk image as filesystem root\n"
|
|
||||||
" --replace=PATH Treat arguments as replacement for PATH\n"
|
" --replace=PATH Treat arguments as replacement for PATH\n"
|
||||||
" --inline Treat arguments as configuration lines\n"
|
" --inline Treat arguments as configuration lines\n"
|
||||||
" --no-pager Do not pipe output into a pager\n"
|
" --no-pager Do not pipe output into a pager\n"
|
||||||
|
@ -1761,7 +1756,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_VERSION = 0x100,
|
ARG_VERSION = 0x100,
|
||||||
ARG_CAT_CONFIG,
|
ARG_CAT_CONFIG,
|
||||||
ARG_ROOT,
|
ARG_ROOT,
|
||||||
ARG_IMAGE,
|
|
||||||
ARG_REPLACE,
|
ARG_REPLACE,
|
||||||
ARG_INLINE,
|
ARG_INLINE,
|
||||||
ARG_NO_PAGER,
|
ARG_NO_PAGER,
|
||||||
|
@ -1772,7 +1766,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
{ "version", no_argument, NULL, ARG_VERSION },
|
{ "version", no_argument, NULL, ARG_VERSION },
|
||||||
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
|
||||||
{ "root", required_argument, NULL, ARG_ROOT },
|
{ "root", required_argument, NULL, ARG_ROOT },
|
||||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
|
||||||
{ "replace", required_argument, NULL, ARG_REPLACE },
|
{ "replace", required_argument, NULL, ARG_REPLACE },
|
||||||
{ "inline", no_argument, NULL, ARG_INLINE },
|
{ "inline", no_argument, NULL, ARG_INLINE },
|
||||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||||
|
@ -1804,12 +1797,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_IMAGE:
|
|
||||||
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARG_REPLACE:
|
case ARG_REPLACE:
|
||||||
if (!path_is_absolute(optarg) ||
|
if (!path_is_absolute(optarg) ||
|
||||||
!endswith(optarg, ".conf"))
|
!endswith(optarg, ".conf"))
|
||||||
|
@ -1842,9 +1829,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"When --replace= is given, some configuration items must be specified");
|
"When --replace= is given, some configuration items must be specified");
|
||||||
|
|
||||||
if (arg_image && arg_root)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1896,9 +1880,6 @@ static int read_config_files(char **args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run(int argc, char *argv[]) {
|
static int run(int argc, char *argv[]) {
|
||||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
|
||||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
|
||||||
_cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
|
|
||||||
_cleanup_close_ int lock = -1;
|
_cleanup_close_ int lock = -1;
|
||||||
Iterator iterator;
|
Iterator iterator;
|
||||||
Item *i;
|
Item *i;
|
||||||
|
@ -1919,23 +1900,6 @@ static int run(int argc, char *argv[]) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (arg_image) {
|
|
||||||
assert(!arg_root);
|
|
||||||
|
|
||||||
r = mount_image_privately_interactively(
|
|
||||||
arg_image,
|
|
||||||
DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
|
|
||||||
&unlink_dir,
|
|
||||||
&loop_device,
|
|
||||||
&decrypted_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
arg_root = strdup(unlink_dir);
|
|
||||||
if (!arg_root)
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If command line arguments are specified along with --replace, read all
|
/* If command line arguments are specified along with --replace, read all
|
||||||
* configuration files and insert the positional arguments at the specified
|
* configuration files and insert the positional arguments at the specified
|
||||||
* place. Otherwise, if command line arguments are specified, execute just
|
* place. Otherwise, if command line arguments are specified, execute just
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "copy.h"
|
#include "copy.h"
|
||||||
#include "def.h"
|
#include "def.h"
|
||||||
#include "dirent-util.h"
|
#include "dirent-util.h"
|
||||||
#include "dissect-image.h"
|
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
@ -39,7 +38,6 @@
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "mkdir.h"
|
#include "mkdir.h"
|
||||||
#include "mount-util.h"
|
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "offline-passwd.h"
|
#include "offline-passwd.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
|
@ -166,7 +164,6 @@ static PagerFlags arg_pager_flags = 0;
|
||||||
static char **arg_include_prefixes = NULL;
|
static char **arg_include_prefixes = NULL;
|
||||||
static char **arg_exclude_prefixes = NULL;
|
static char **arg_exclude_prefixes = NULL;
|
||||||
static char *arg_root = NULL;
|
static char *arg_root = NULL;
|
||||||
static char *arg_image = NULL;
|
|
||||||
static char *arg_replace = NULL;
|
static char *arg_replace = NULL;
|
||||||
|
|
||||||
#define MAX_DEPTH 256
|
#define MAX_DEPTH 256
|
||||||
|
@ -180,7 +177,6 @@ STATIC_DESTRUCTOR_REGISTER(unix_sockets, set_free_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_include_prefixes, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_include_prefixes, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_exclude_prefixes, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_exclude_prefixes, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
|
||||||
|
|
||||||
static int specifier_machine_id_safe(char specifier, const void *data, const void *userdata, char **ret);
|
static int specifier_machine_id_safe(char specifier, const void *data, const void *userdata, char **ret);
|
||||||
static int specifier_directory(char specifier, const void *data, const void *userdata, char **ret);
|
static int specifier_directory(char specifier, const void *data, const void *userdata, char **ret);
|
||||||
|
@ -2888,27 +2884,6 @@ static int cat_config(char **config_dirs, char **args) {
|
||||||
return cat_files(NULL, files, 0);
|
return cat_files(NULL, files, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exclude_default_prefixes(void) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Provide an easy way to exclude virtual/memory file systems from what we do here. Useful in
|
|
||||||
* combination with --root= where we probably don't want to apply stuff to these dirs as they are
|
|
||||||
* likely over-mounted if the root directory is actually used, and it wouldbe less than ideal to have
|
|
||||||
* all kinds of files created/adjusted underneath these mount points. */
|
|
||||||
|
|
||||||
r = strv_extend_strv(
|
|
||||||
&arg_exclude_prefixes,
|
|
||||||
STRV_MAKE("/dev",
|
|
||||||
"/proc",
|
|
||||||
"/run",
|
|
||||||
"/sys"),
|
|
||||||
true);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int help(void) {
|
static int help(void) {
|
||||||
_cleanup_free_ char *link = NULL;
|
_cleanup_free_ char *link = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -2929,9 +2904,7 @@ static int help(void) {
|
||||||
" --boot Execute actions only safe at boot\n"
|
" --boot Execute actions only safe at boot\n"
|
||||||
" --prefix=PATH Only apply rules with the specified prefix\n"
|
" --prefix=PATH Only apply rules with the specified prefix\n"
|
||||||
" --exclude-prefix=PATH Ignore rules with the specified prefix\n"
|
" --exclude-prefix=PATH Ignore rules with the specified prefix\n"
|
||||||
" -E Ignore rules prefixed with /dev, /proc, /run, /sys\n"
|
|
||||||
" --root=PATH Operate on an alternate filesystem root\n"
|
" --root=PATH Operate on an alternate filesystem root\n"
|
||||||
" --image=PATH Operate on disk image as filesystem root\n"
|
|
||||||
" --replace=PATH Treat arguments as replacement for PATH\n"
|
" --replace=PATH Treat arguments as replacement for PATH\n"
|
||||||
" --no-pager Do not pipe output into a pager\n"
|
" --no-pager Do not pipe output into a pager\n"
|
||||||
"\nSee the %s for details.\n"
|
"\nSee the %s for details.\n"
|
||||||
|
@ -2955,7 +2928,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_PREFIX,
|
ARG_PREFIX,
|
||||||
ARG_EXCLUDE_PREFIX,
|
ARG_EXCLUDE_PREFIX,
|
||||||
ARG_ROOT,
|
ARG_ROOT,
|
||||||
ARG_IMAGE,
|
|
||||||
ARG_REPLACE,
|
ARG_REPLACE,
|
||||||
ARG_NO_PAGER,
|
ARG_NO_PAGER,
|
||||||
};
|
};
|
||||||
|
@ -2972,7 +2944,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
{ "prefix", required_argument, NULL, ARG_PREFIX },
|
{ "prefix", required_argument, NULL, ARG_PREFIX },
|
||||||
{ "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
|
{ "exclude-prefix", required_argument, NULL, ARG_EXCLUDE_PREFIX },
|
||||||
{ "root", required_argument, NULL, ARG_ROOT },
|
{ "root", required_argument, NULL, ARG_ROOT },
|
||||||
{ "image", required_argument, NULL, ARG_IMAGE },
|
|
||||||
{ "replace", required_argument, NULL, ARG_REPLACE },
|
{ "replace", required_argument, NULL, ARG_REPLACE },
|
||||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||||
{}
|
{}
|
||||||
|
@ -2983,7 +2954,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "hE", options, NULL)) >= 0)
|
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
|
@ -3033,21 +3004,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_IMAGE:
|
|
||||||
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* Imply -E here since it makes little sense to create files persistently in the /run mointpoint of a disk image */
|
|
||||||
_fallthrough_;
|
|
||||||
|
|
||||||
case 'E':
|
|
||||||
r = exclude_default_prefixes();
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARG_REPLACE:
|
case ARG_REPLACE:
|
||||||
if (!path_is_absolute(optarg) ||
|
if (!path_is_absolute(optarg) ||
|
||||||
!endswith(optarg, ".conf"))
|
!endswith(optarg, ".conf"))
|
||||||
|
@ -3080,13 +3036,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"When --replace= is given, some configuration items must be specified");
|
"When --replace= is given, some configuration items must be specified");
|
||||||
|
|
||||||
if (arg_root && arg_user)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"Combination of --user and --root= is not supported.");
|
|
||||||
|
|
||||||
if (arg_image && arg_root)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3262,9 +3211,6 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_array_hash_ops, char, string_
|
||||||
ItemArray, item_array_free);
|
ItemArray, item_array_free);
|
||||||
|
|
||||||
static int run(int argc, char *argv[]) {
|
static int run(int argc, char *argv[]) {
|
||||||
_cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
|
|
||||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
|
|
||||||
_cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
|
|
||||||
_cleanup_strv_free_ char **config_dirs = NULL;
|
_cleanup_strv_free_ char **config_dirs = NULL;
|
||||||
bool invalid_config = false;
|
bool invalid_config = false;
|
||||||
Iterator iterator;
|
Iterator iterator;
|
||||||
|
@ -3297,20 +3243,10 @@ static int run(int argc, char *argv[]) {
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *t = NULL;
|
_cleanup_free_ char *t = NULL;
|
||||||
char **i;
|
|
||||||
|
|
||||||
STRV_FOREACH(i, config_dirs) {
|
t = strv_join(config_dirs, "\n\t");
|
||||||
_cleanup_free_ char *j = NULL;
|
if (t)
|
||||||
|
log_debug("Looking for configuration files in (higher priority first):\n\t%s", t);
|
||||||
j = path_join(arg_root, *i);
|
|
||||||
if (!j)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
if (!strextend(&t, "\n\t", j, NULL))
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug("Looking for configuration files in (higher priority first):%s", t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg_cat_config) {
|
if (arg_cat_config) {
|
||||||
|
@ -3325,23 +3261,6 @@ static int run(int argc, char *argv[]) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (arg_image) {
|
|
||||||
assert(!arg_root);
|
|
||||||
|
|
||||||
r = mount_image_privately_interactively(
|
|
||||||
arg_image,
|
|
||||||
DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
|
|
||||||
&unlink_dir,
|
|
||||||
&loop_device,
|
|
||||||
&decrypted_image);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
arg_root = strdup(unlink_dir);
|
|
||||||
if (!arg_root)
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
items = ordered_hashmap_new(&item_array_hash_ops);
|
items = ordered_hashmap_new(&item_array_hash_ops);
|
||||||
globs = ordered_hashmap_new(&item_array_hash_ops);
|
globs = ordered_hashmap_new(&item_array_hash_ops);
|
||||||
if (!items || !globs)
|
if (!items || !globs)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Permit User Sessions
|
Description=Permit User Sessions
|
||||||
Documentation=man:systemd-user-sessions.service(8)
|
Documentation=man:systemd-user-sessions.service(8)
|
||||||
After=remote-fs.target nss-user-lookup.target network.target home.mount
|
After=remote-fs.target nss-user-lookup.target network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|
Loading…
Reference in New Issue