Compare commits
22 Commits
644af26285
...
36296ae2ad
Author | SHA1 | Date |
---|---|---|
Lennart Poettering | 36296ae2ad | |
Franck Bui | 8ce3de991b | |
Lennart Poettering | fabf877705 | |
Lennart Poettering | 9230f5774a | |
Lennart Poettering | 7ea3024b50 | |
Lennart Poettering | dee29aeb59 | |
Lennart Poettering | ef9bddb799 | |
Lennart Poettering | 27ffec0831 | |
Zbigniew Jędrzejewski-Szmek | 21556381ff | |
Zbigniew Jędrzejewski-Szmek | a9d99f6e3d | |
Zbigniew Jędrzejewski-Szmek | 550f3ba68d | |
Zbigniew Jędrzejewski-Szmek | b12bd993c8 | |
Zbigniew Jędrzejewski-Szmek | 7bb553bb98 | |
Zbigniew Jędrzejewski-Szmek | 48904c8bfd | |
Zbigniew Jędrzejewski-Szmek | d4d9f034b1 | |
Zbigniew Jędrzejewski-Szmek | be36bc1e14 | |
Zbigniew Jędrzejewski-Szmek | 115a7fb624 | |
Zbigniew Jędrzejewski-Szmek | 38ee19c04b | |
Zbigniew Jędrzejewski-Szmek | fe79f107ef | |
Zbigniew Jędrzejewski-Szmek | d583cf45b6 | |
Zbigniew Jędrzejewski-Szmek | 6119878480 | |
Zbigniew Jędrzejewski-Szmek | 5e98086d16 |
|
@ -60,10 +60,10 @@
|
||||||
device or file, or a specification of a block device via
|
device or file, or a specification of a block device via
|
||||||
<literal>UUID=</literal> followed by the UUID.</para>
|
<literal>UUID=</literal> followed by the UUID.</para>
|
||||||
|
|
||||||
<para>The third field specifies an absolute path to a file to read the encryption key from. Optionally,
|
<para>The third field specifies an absolute path to a file with the encryption key. Optionally,
|
||||||
the path may be followed by <literal>:</literal> and an fstab device specification (e.g. starting with
|
the path may be followed by <literal>:</literal> and an fstab device specification (e.g. starting with
|
||||||
<literal>LABEL=</literal> or similar); in which case, the path is relative to the device file system
|
<literal>LABEL=</literal> or similar); in which case the path is taken relative to the device file system
|
||||||
root. If the field is not present or set to <literal>none</literal> or <literal>-</literal>, a key file
|
root. If the field is not present or is <literal>none</literal> or <literal>-</literal>, a key file
|
||||||
named after the volume to unlock (i.e. the first column of the line), suffixed with
|
named after the volume to unlock (i.e. the first column of the line), suffixed with
|
||||||
<filename>.key</filename> is automatically loaded from the <filename>/etc/cryptsetup-keys.d/</filename>
|
<filename>.key</filename> is automatically loaded from the <filename>/etc/cryptsetup-keys.d/</filename>
|
||||||
and <filename>/run/cryptsetup-keys.d/</filename> directories, if present. Otherwise, the password has to
|
and <filename>/run/cryptsetup-keys.d/</filename> directories, if present. Otherwise, the password has to
|
||||||
|
@ -78,12 +78,12 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>cipher=</option></term>
|
<term><option>cipher=</option></term>
|
||||||
|
|
||||||
<listitem><para>Specifies the cipher to use. See
|
<listitem><para>Specifies the cipher to use. See <citerefentry
|
||||||
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
for possible values and the default value of this option. A
|
for possible values and the default value of this option. A cipher with unpredictable IV values, such
|
||||||
cipher with unpredictable IV values, such as
|
as <literal>aes-cbc-essiv:sha256</literal>, is recommended. Embedded commas in the cipher
|
||||||
<literal>aes-cbc-essiv:sha256</literal>, is
|
specification need to be escaped by preceding them with a backslash, see example below.</para>
|
||||||
recommended.</para></listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -498,15 +498,17 @@
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
<example>
|
<example>
|
||||||
<title>/etc/crypttab example</title>
|
<title>/etc/crypttab example</title>
|
||||||
<para>Set up four encrypted block devices. One using LUKS for
|
<para>Set up four encrypted block devices. One using LUKS for normal storage, another one for usage as
|
||||||
normal storage, another one for usage as a swap device and two
|
a swap device and two TrueCrypt volumes. For the fourth device, the option string is interpreted as two
|
||||||
TrueCrypt volumes.</para>
|
options <literal>cipher=xchacha12,aes-adiantum-plain64</literal>,
|
||||||
|
<literal>keyfile-timeout=10s</literal>.</para>
|
||||||
|
|
||||||
<programlisting>luks UUID=2505567a-9e27-4efe-a4d5-15ad146c258b
|
<programlisting>luks UUID=2505567a-9e27-4efe-a4d5-15ad146c258b
|
||||||
swap /dev/sda7 /dev/urandom swap
|
swap /dev/sda7 /dev/urandom swap
|
||||||
truecrypt /dev/sda2 /etc/container_password tcrypt
|
truecrypt /dev/sda2 /etc/container_password tcrypt
|
||||||
hidden /mnt/tc_hidden /dev/null tcrypt-hidden,tcrypt-keyfile=/etc/keyfile
|
hidden /mnt/tc_hidden /dev/null tcrypt-hidden,tcrypt-keyfile=/etc/keyfile
|
||||||
external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s</programlisting>
|
external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s,cipher=xchacha12\,aes-adiantum-plain64
|
||||||
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
<example>
|
<example>
|
||||||
|
|
|
@ -304,7 +304,7 @@
|
||||||
setting. Example: <option>--timezone=Europe/Amsterdam</option> will result in the environment
|
setting. Example: <option>--timezone=Europe/Amsterdam</option> will result in the environment
|
||||||
variable <literal>TZ=:Europe/Amsterdam</literal>. (<literal>:</literal> is used intentionally as part
|
variable <literal>TZ=:Europe/Amsterdam</literal>. (<literal>:</literal> is used intentionally as part
|
||||||
of the timezone specification, see
|
of the timezone specification, see
|
||||||
<citerefentry><refentrytitle>tzset</refentrytitle><manvolnum>3</manvolnum></citerefentry>.)
|
<citerefentry project='man-pages'><refentrytitle>tzset</refentrytitle><manvolnum>3</manvolnum></citerefentry>.)
|
||||||
</para></listitem>
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ target="man/$1.html"
|
||||||
ninja -C "@BUILD_ROOT@" "$target"
|
ninja -C "@BUILD_ROOT@" "$target"
|
||||||
|
|
||||||
fullname="@BUILD_ROOT@/$target"
|
fullname="@BUILD_ROOT@/$target"
|
||||||
redirect="$(readlink "$fullname" 2>/dev/null)"
|
redirect="$(test -f "$fullname" && readlink "$fullname" || :)"
|
||||||
if [ -n "$redirect" ]; then
|
if [ -n "$redirect" ]; then
|
||||||
ninja -C "@BUILD_ROOT@" "man/$redirect"
|
ninja -C "@BUILD_ROOT@" "man/$redirect"
|
||||||
|
|
||||||
|
|
|
@ -1036,12 +1036,14 @@ manpages = [
|
||||||
''],
|
''],
|
||||||
['udev_device_has_tag',
|
['udev_device_has_tag',
|
||||||
'3',
|
'3',
|
||||||
['udev_device_get_devlinks_list_entry',
|
['udev_device_get_current_tags_list_entry',
|
||||||
|
'udev_device_get_devlinks_list_entry',
|
||||||
'udev_device_get_properties_list_entry',
|
'udev_device_get_properties_list_entry',
|
||||||
'udev_device_get_property_value',
|
'udev_device_get_property_value',
|
||||||
'udev_device_get_sysattr_list_entry',
|
'udev_device_get_sysattr_list_entry',
|
||||||
'udev_device_get_sysattr_value',
|
'udev_device_get_sysattr_value',
|
||||||
'udev_device_get_tags_list_entry',
|
'udev_device_get_tags_list_entry',
|
||||||
|
'udev_device_has_current_tag',
|
||||||
'udev_device_set_sysattr_value'],
|
'udev_device_set_sysattr_value'],
|
||||||
''],
|
''],
|
||||||
['udev_device_new_from_syspath',
|
['udev_device_new_from_syspath',
|
||||||
|
|
|
@ -70,10 +70,10 @@
|
||||||
|
|
||||||
<para>OS images may use any kind of Linux-supported file systems. In addition they may make use of LUKS
|
<para>OS images may use any kind of Linux-supported file systems. In addition they may make use of LUKS
|
||||||
disk encryption, and contain Verity integrity information. Note that qualifying OS images may be booted
|
disk encryption, and contain Verity integrity information. Note that qualifying OS images may be booted
|
||||||
with <citerefentry><refentrytitle>system-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
with <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
||||||
<option>--image=</option> switch, and be used as root file system for system service using the
|
<option>--image=</option> switch, and be used as root file system for system service using the
|
||||||
<varname>RootImage=</varname> unit file setting, see
|
<varname>RootImage=</varname> unit file setting, see
|
||||||
<citerefentry><refentrytitle>system.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
||||||
|
|
||||||
<para>Note that the partition table shown when invoked without command switch (as listed below) does not
|
<para>Note that the partition table shown when invoked without command switch (as listed below) does not
|
||||||
necessarily show all partitions included in the image, but just the partitions that are understood and
|
necessarily show all partitions included in the image, but just the partitions that are understood and
|
||||||
|
@ -252,8 +252,8 @@
|
||||||
<title>See Also</title>
|
<title>See Also</title>
|
||||||
<para>
|
<para>
|
||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>system-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>system.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
<ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions Specification</ulink>,
|
<ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions Specification</ulink>,
|
||||||
<citerefentry project='man-pages'><refentrytitle>umount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
<citerefentry project='man-pages'><refentrytitle>umount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||||
<citerefentry project='man-pages'><refentrytitle>fdisk</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry project='man-pages'><refentrytitle>fdisk</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
|
|
|
@ -153,7 +153,9 @@
|
||||||
case the image has multiple partitions, otherwise partition name <literal>root</literal> is implied.
|
case the image has multiple partitions, otherwise partition name <literal>root</literal> is implied.
|
||||||
Options for multiple partitions can be specified in a single line with space separators. Assigning an empty
|
Options for multiple partitions can be specified in a single line with space separators. Assigning an empty
|
||||||
string removes previous assignments. Duplicated options are ignored. For a list of valid mount options, please
|
string removes previous assignments. Duplicated options are ignored. For a list of valid mount options, please
|
||||||
refer to <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
refer to
|
||||||
|
<citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>Valid partition names follow the <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable
|
<para>Valid partition names follow the <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable
|
||||||
Partitions Specification</ulink>.</para>
|
Partitions Specification</ulink>.</para>
|
||||||
|
@ -1009,7 +1011,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
|
|
||||||
<listitem><para>Sets the CPU scheduling policy for executed processes. Takes one of <option>other</option>,
|
<listitem><para>Sets the CPU scheduling policy for executed processes. Takes one of <option>other</option>,
|
||||||
<option>batch</option>, <option>idle</option>, <option>fifo</option> or <option>rr</option>. See
|
<option>batch</option>, <option>idle</option>, <option>fifo</option> or <option>rr</option>. See
|
||||||
<citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
<citerefentry project='man-pages'><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||||
details.</para></listitem>
|
details.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1019,7 +1021,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
<listitem><para>Sets the CPU scheduling priority for executed processes. The available priority range depends
|
<listitem><para>Sets the CPU scheduling priority for executed processes. The available priority range depends
|
||||||
on the selected CPU scheduling policy (see above). For real-time scheduling policies an integer between 1
|
on the selected CPU scheduling policy (see above). For real-time scheduling policies an integer between 1
|
||||||
(lowest priority) and 99 (highest priority) can be used. See
|
(lowest priority) and 99 (highest priority) can be used. See
|
||||||
<citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
<citerefentry project='man-pages'><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||||
details. </para></listitem>
|
details. </para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1030,7 +1032,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
will be reset when the executed processes call
|
will be reset when the executed processes call
|
||||||
<citerefentry project='man-pages'><refentrytitle>fork</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
<citerefentry project='man-pages'><refentrytitle>fork</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
||||||
and can hence not leak into child processes. See
|
and can hence not leak into child processes. See
|
||||||
<citerefentry><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
<citerefentry project='man-pages'><refentrytitle>sched_setscheduler</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
for details. Defaults to false.</para></listitem>
|
for details. Defaults to false.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -1043,7 +1045,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
are specified by the lower and upper CPU indices separated by a dash. This option may be specified more than
|
are specified by the lower and upper CPU indices separated by a dash. This option may be specified more than
|
||||||
once, in which case the specified CPU affinity masks are merged. If the empty string is assigned, the mask
|
once, in which case the specified CPU affinity masks are merged. If the empty string is assigned, the mask
|
||||||
is reset, all assignments prior to this will have no effect. See
|
is reset, all assignments prior to this will have no effect. See
|
||||||
<citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
<citerefentry project='man-pages'><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||||
details.</para></listitem>
|
details.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
|
@ -270,9 +270,8 @@
|
||||||
ideas behind systemd, please refer to the
|
ideas behind systemd, please refer to the
|
||||||
<ulink url="http://0pointer.de/blog/projects/systemd.html">Original Design Document</ulink>.</para>
|
<ulink url="http://0pointer.de/blog/projects/systemd.html">Original Design Document</ulink>.</para>
|
||||||
|
|
||||||
<para>Note that some but not all interfaces provided
|
<para>Note that some but not all interfaces provided by systemd are covered by the
|
||||||
by systemd are covered by the
|
<ulink url="https://systemd.io/PORTABILITY_AND_STABILITY/">Interface Portability and Stability Promise</ulink>.</para>
|
||||||
<ulink url="Portability and">Interface Portability and Stability Promise</ulink>.</para>
|
|
||||||
|
|
||||||
<para>Units may be generated dynamically at boot and system
|
<para>Units may be generated dynamically at boot and system
|
||||||
manager reload time, for example based on other configuration
|
manager reload time, for example based on other configuration
|
||||||
|
|
|
@ -267,12 +267,21 @@ int log_open(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log_target != LOG_TARGET_AUTO || getpid_cached() == 1 || stderr_is_journal()) {
|
if (getpid_cached() == 1 ||
|
||||||
|
stderr_is_journal() ||
|
||||||
|
IN_SET(log_target,
|
||||||
|
LOG_TARGET_KMSG,
|
||||||
|
LOG_TARGET_JOURNAL,
|
||||||
|
LOG_TARGET_JOURNAL_OR_KMSG,
|
||||||
|
LOG_TARGET_SYSLOG,
|
||||||
|
LOG_TARGET_SYSLOG_OR_KMSG)) {
|
||||||
|
|
||||||
if (!prohibit_ipc &&
|
if (!prohibit_ipc) {
|
||||||
IN_SET(log_target, LOG_TARGET_AUTO,
|
if (IN_SET(log_target,
|
||||||
|
LOG_TARGET_AUTO,
|
||||||
LOG_TARGET_JOURNAL_OR_KMSG,
|
LOG_TARGET_JOURNAL_OR_KMSG,
|
||||||
LOG_TARGET_JOURNAL)) {
|
LOG_TARGET_JOURNAL)) {
|
||||||
|
|
||||||
r = log_open_journal();
|
r = log_open_journal();
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
log_close_syslog();
|
log_close_syslog();
|
||||||
|
@ -281,9 +290,10 @@ int log_open(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prohibit_ipc &&
|
if (IN_SET(log_target,
|
||||||
IN_SET(log_target, LOG_TARGET_SYSLOG_OR_KMSG,
|
LOG_TARGET_SYSLOG_OR_KMSG,
|
||||||
LOG_TARGET_SYSLOG)) {
|
LOG_TARGET_SYSLOG)) {
|
||||||
|
|
||||||
r = log_open_syslog();
|
r = log_open_syslog();
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
log_close_journal();
|
log_close_journal();
|
||||||
|
@ -291,6 +301,7 @@ int log_open(void) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IN_SET(log_target, LOG_TARGET_AUTO,
|
if (IN_SET(log_target, LOG_TARGET_AUTO,
|
||||||
LOG_TARGET_JOURNAL_OR_KMSG,
|
LOG_TARGET_JOURNAL_OR_KMSG,
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef enum LogTarget{
|
||||||
LOG_TARGET_JOURNAL_OR_KMSG,
|
LOG_TARGET_JOURNAL_OR_KMSG,
|
||||||
LOG_TARGET_SYSLOG,
|
LOG_TARGET_SYSLOG,
|
||||||
LOG_TARGET_SYSLOG_OR_KMSG,
|
LOG_TARGET_SYSLOG_OR_KMSG,
|
||||||
LOG_TARGET_AUTO, /* console if stderr is tty, JOURNAL_OR_KMSG otherwise */
|
LOG_TARGET_AUTO, /* console if stderr is not journal, JOURNAL_OR_KMSG otherwise */
|
||||||
LOG_TARGET_NULL,
|
LOG_TARGET_NULL,
|
||||||
_LOG_TARGET_MAX,
|
_LOG_TARGET_MAX,
|
||||||
_LOG_TARGET_INVALID = -1
|
_LOG_TARGET_INVALID = -1
|
||||||
|
|
|
@ -367,7 +367,7 @@ int strv_split_colon_pairs(char ***t, const char *s) {
|
||||||
return (int) n;
|
return (int) n;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *strv_join_prefix(char * const *l, const char *separator, const char *prefix) {
|
char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool unescape_separators) {
|
||||||
char * const *s;
|
char * const *s;
|
||||||
char *r, *e;
|
char *r, *e;
|
||||||
size_t n, k, m;
|
size_t n, k, m;
|
||||||
|
@ -378,11 +378,17 @@ char *strv_join_prefix(char * const *l, const char *separator, const char *prefi
|
||||||
k = strlen(separator);
|
k = strlen(separator);
|
||||||
m = strlen_ptr(prefix);
|
m = strlen_ptr(prefix);
|
||||||
|
|
||||||
|
if (unescape_separators) /* If there separator is multi-char, we won't know how to escape it. */
|
||||||
|
assert(k == 1);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
STRV_FOREACH(s, l) {
|
STRV_FOREACH(s, l) {
|
||||||
if (s != l)
|
if (s != l)
|
||||||
n += k;
|
n += k;
|
||||||
n += m + strlen(*s);
|
|
||||||
|
bool needs_escaping = unescape_separators && strchr(*s, separator[0]);
|
||||||
|
|
||||||
|
n += m + strlen(*s) * (1 + needs_escaping);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = new(char, n+1);
|
r = new(char, n+1);
|
||||||
|
@ -397,6 +403,15 @@ char *strv_join_prefix(char * const *l, const char *separator, const char *prefi
|
||||||
if (prefix)
|
if (prefix)
|
||||||
e = stpcpy(e, prefix);
|
e = stpcpy(e, prefix);
|
||||||
|
|
||||||
|
bool needs_escaping = unescape_separators && strchr(*s, separator[0]);
|
||||||
|
|
||||||
|
if (needs_escaping)
|
||||||
|
for (size_t i = 0; (*s)[i]; i++) {
|
||||||
|
if ((*s)[i] == separator[0])
|
||||||
|
*(e++) = '\\';
|
||||||
|
*(e++) = (*s)[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
e = stpcpy(e, *s);
|
e = stpcpy(e, *s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,9 +91,9 @@ static inline char **strv_split(const char *s, const char *separators) {
|
||||||
* string in the vector is an empty string. */
|
* string in the vector is an empty string. */
|
||||||
int strv_split_colon_pairs(char ***t, const char *s);
|
int strv_split_colon_pairs(char ***t, const char *s);
|
||||||
|
|
||||||
char *strv_join_prefix(char * const *l, const char *separator, const char *prefix);
|
char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separtor);
|
||||||
static inline char *strv_join(char * const *l, const char *separator) {
|
static inline char *strv_join(char * const *l, const char *separator) {
|
||||||
return strv_join_prefix(l, separator, NULL);
|
return strv_join_full(l, separator, NULL, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
char **strv_parse_nulstr(const char *s, size_t l);
|
char **strv_parse_nulstr(const char *s, size_t l);
|
||||||
|
|
|
@ -53,6 +53,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_home, protect_home, Pro
|
||||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, ProtectSystem);
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, ProtectSystem);
|
||||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
|
||||||
static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
|
static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
|
||||||
|
static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec_context_get_effective_mount_apivfs);
|
||||||
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_CLASS);
|
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_CLASS);
|
||||||
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_DATA);
|
static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_DATA);
|
||||||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
|
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
|
||||||
|
@ -1143,7 +1144,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||||
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("MountAPIVFS", "b", property_get_mount_apivfs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
@ -1805,9 +1806,6 @@ int bus_exec_context_set_transient_property(
|
||||||
if (streq(name, "ProtectControlGroups"))
|
if (streq(name, "ProtectControlGroups"))
|
||||||
return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);
|
return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);
|
||||||
|
|
||||||
if (streq(name, "MountAPIVFS"))
|
|
||||||
return bus_set_transient_bool(u, name, &c->mount_apivfs, message, flags, error);
|
|
||||||
|
|
||||||
if (streq(name, "CPUSchedulingResetOnFork"))
|
if (streq(name, "CPUSchedulingResetOnFork"))
|
||||||
return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
|
return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
|
||||||
|
|
||||||
|
@ -2635,6 +2633,20 @@ int bus_exec_context_set_transient_property(
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
} else if (streq(name, "MountAPIVFS")) {
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
r = bus_set_transient_bool(u, name, &b, message, flags, error);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
c->mount_apivfs = b;
|
||||||
|
c->mount_apivfs_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
} else if (streq(name, "WorkingDirectory")) {
|
} else if (streq(name, "WorkingDirectory")) {
|
||||||
const char *s;
|
const char *s;
|
||||||
bool missing_ok;
|
bool missing_ok;
|
||||||
|
|
|
@ -1927,7 +1927,7 @@ static int build_environment(
|
||||||
if (!pre)
|
if (!pre)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
joined = strv_join_prefix(c->directories[t].paths, ":", pre);
|
joined = strv_join_full(c->directories[t].paths, ":", pre, true);
|
||||||
if (!joined)
|
if (!joined)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -2027,7 +2027,7 @@ static bool exec_needs_mount_namespace(
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (context->root_directory) {
|
if (context->root_directory) {
|
||||||
if (context->mount_apivfs)
|
if (exec_context_get_effective_mount_apivfs(context))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
|
for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
|
||||||
|
@ -3147,7 +3147,7 @@ static int apply_mount_namespace(
|
||||||
.protect_kernel_modules = context->protect_kernel_modules,
|
.protect_kernel_modules = context->protect_kernel_modules,
|
||||||
.protect_kernel_logs = context->protect_kernel_logs,
|
.protect_kernel_logs = context->protect_kernel_logs,
|
||||||
.protect_hostname = context->protect_hostname,
|
.protect_hostname = context->protect_hostname,
|
||||||
.mount_apivfs = context->mount_apivfs,
|
.mount_apivfs = exec_context_get_effective_mount_apivfs(context),
|
||||||
.private_mounts = context->private_mounts,
|
.private_mounts = context->private_mounts,
|
||||||
.protect_home = context->protect_home,
|
.protect_home = context->protect_home,
|
||||||
.protect_system = context->protect_system,
|
.protect_system = context->protect_system,
|
||||||
|
@ -5185,7 +5185,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||||
prefix, yes_no(c->private_users),
|
prefix, yes_no(c->private_users),
|
||||||
prefix, protect_home_to_string(c->protect_home),
|
prefix, protect_home_to_string(c->protect_home),
|
||||||
prefix, protect_system_to_string(c->protect_system),
|
prefix, protect_system_to_string(c->protect_system),
|
||||||
prefix, yes_no(c->mount_apivfs),
|
prefix, yes_no(exec_context_get_effective_mount_apivfs(c)),
|
||||||
prefix, yes_no(c->ignore_sigpipe),
|
prefix, yes_no(c->ignore_sigpipe),
|
||||||
prefix, yes_no(c->memory_deny_write_execute),
|
prefix, yes_no(c->memory_deny_write_execute),
|
||||||
prefix, yes_no(c->restrict_realtime),
|
prefix, yes_no(c->restrict_realtime),
|
||||||
|
@ -5650,6 +5650,20 @@ int exec_context_get_effective_ioprio(const ExecContext *c) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool exec_context_get_effective_mount_apivfs(const ExecContext *c) {
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
/* Explicit setting wins */
|
||||||
|
if (c->mount_apivfs_set)
|
||||||
|
return c->mount_apivfs;
|
||||||
|
|
||||||
|
/* Default to "yes" if root directory or image are specified */
|
||||||
|
if (c->root_image || !empty_or_root(c->root_directory))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void exec_context_free_log_extra_fields(ExecContext *c) {
|
void exec_context_free_log_extra_fields(ExecContext *c) {
|
||||||
assert(c);
|
assert(c);
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,7 @@ struct ExecContext {
|
||||||
bool nice_set:1;
|
bool nice_set:1;
|
||||||
bool ioprio_set:1;
|
bool ioprio_set:1;
|
||||||
bool cpu_sched_set:1;
|
bool cpu_sched_set:1;
|
||||||
|
bool mount_apivfs_set:1;
|
||||||
|
|
||||||
/* This is not exposed to the user but available internally. We need it to make sure that whenever we
|
/* This is not exposed to the user but available internally. We need it to make sure that whenever we
|
||||||
* spawn /usr/bin/mount it is run in the same process group as us so that the autofs logic detects
|
* spawn /usr/bin/mount it is run in the same process group as us so that the autofs logic detects
|
||||||
|
@ -409,6 +410,7 @@ bool exec_context_may_touch_console(const ExecContext *c);
|
||||||
bool exec_context_maintains_privileges(const ExecContext *c);
|
bool exec_context_maintains_privileges(const ExecContext *c);
|
||||||
|
|
||||||
int exec_context_get_effective_ioprio(const ExecContext *c);
|
int exec_context_get_effective_ioprio(const ExecContext *c);
|
||||||
|
bool exec_context_get_effective_mount_apivfs(const ExecContext *c);
|
||||||
|
|
||||||
void exec_context_free_log_extra_fields(ExecContext *c);
|
void exec_context_free_log_extra_fields(ExecContext *c);
|
||||||
|
|
||||||
|
|
|
@ -1349,6 +1349,44 @@ int config_parse_exec_cpu_sched_policy(const char *unit,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_parse_exec_mount_apivfs(const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *section,
|
||||||
|
unsigned section_line,
|
||||||
|
const char *lvalue,
|
||||||
|
int ltype,
|
||||||
|
const char *rvalue,
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
ExecContext *c = data;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
if (isempty(rvalue)) {
|
||||||
|
c->mount_apivfs_set = false;
|
||||||
|
c->mount_apivfs = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
k = parse_boolean(rvalue);
|
||||||
|
if (k < 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, k,
|
||||||
|
"Failed to parse boolean value, ignoring: %s",
|
||||||
|
rvalue);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->mount_apivfs_set = true;
|
||||||
|
c->mount_apivfs = k;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_numa_mask(const char *unit,
|
int config_parse_numa_mask(const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
|
|
|
@ -43,6 +43,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_io_priority);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_policy);
|
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_policy);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio);
|
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_sched_prio);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity);
|
CONFIG_PARSER_PROTOTYPE(config_parse_exec_cpu_affinity);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_exec_mount_apivfs);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits);
|
CONFIG_PARSER_PROTOTYPE(config_parse_exec_secure_bits);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_root_image_options);
|
CONFIG_PARSER_PROTOTYPE(config_parse_root_image_options);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_exec_root_hash);
|
CONFIG_PARSER_PROTOTYPE(config_parse_exec_root_hash);
|
||||||
|
|
|
@ -526,8 +526,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
|
||||||
assert(fd >= 0);
|
assert(fd >= 0);
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
r = getpeername(fd, &sa.peer.sa, &salen);
|
if (getpeername(fd, &sa.peer.sa, &salen) < 0)
|
||||||
if (r < 0)
|
|
||||||
return log_unit_error_errno(UNIT(s), errno, "getpeername failed: %m");
|
return log_unit_error_errno(UNIT(s), errno, "getpeername failed: %m");
|
||||||
|
|
||||||
if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
|
if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
|
||||||
|
|
|
@ -622,7 +622,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||||
static int add_crypttab_devices(void) {
|
static int add_crypttab_devices(void) {
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
unsigned crypttab_line = 0;
|
unsigned crypttab_line = 0;
|
||||||
struct stat st;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (!arg_read_crypttab)
|
if (!arg_read_crypttab)
|
||||||
|
@ -635,11 +634,6 @@ static int add_crypttab_devices(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fileno(f), &st) < 0) {
|
|
||||||
log_error_errno(errno, "Failed to stat %s: %m", arg_crypttab);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
_cleanup_free_ char *line = NULL, *name = NULL, *device = NULL, *keyspec = NULL, *options = NULL, *keyfile = NULL, *keydev = NULL;
|
_cleanup_free_ char *line = NULL, *name = NULL, *device = NULL, *keyspec = NULL, *options = NULL, *keyfile = NULL, *keydev = NULL;
|
||||||
crypto_device *d = NULL;
|
crypto_device *d = NULL;
|
||||||
|
|
|
@ -294,9 +294,9 @@ static int parse_options(const char *options) {
|
||||||
_cleanup_free_ char *word = NULL;
|
_cleanup_free_ char *word = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS);
|
r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to parse options: %m");
|
return log_error_errno(r, "Failed to parse options: %m");
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -874,6 +874,9 @@ static int run(int argc, char *argv[]) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_debug("%s %s ← %s type=%s cipher=%s", __func__,
|
||||||
|
argv[2], argv[3], strempty(arg_type), strempty(arg_cipher));
|
||||||
|
|
||||||
/* A delicious drop of snake oil */
|
/* A delicious drop of snake oil */
|
||||||
(void) mlockall(MCL_FUTURE);
|
(void) mlockall(MCL_FUTURE);
|
||||||
|
|
||||||
|
|
|
@ -5134,9 +5134,12 @@ static int run(int argc, char *argv[]) {
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
r = must_be_root();
|
if (geteuid() != 0) {
|
||||||
if (r < 0)
|
r = log_warning_errno(SYNTHETIC_ERRNO(EPERM),
|
||||||
|
argc >= 2 ? "Need to be root." :
|
||||||
|
"Need to be root (and some arguments are usually required).\nHint: try --help");
|
||||||
goto finish;
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
r = cant_be_in_netns();
|
r = cant_be_in_netns();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -842,19 +842,21 @@ static int verify_esp_blkid(
|
||||||
else if (r != 0)
|
else if (r != 0)
|
||||||
return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system \"%s\": %m", node);
|
return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system \"%s\": %m", node);
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
|
r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe file system type of \"%s\": %m", node);
|
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||||
|
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||||
|
"No filesystem found on \"%s\": %m", node);
|
||||||
if (!streq(v, "vfat"))
|
if (!streq(v, "vfat"))
|
||||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||||
"File system \"%s\" is not FAT.", node);
|
"File system \"%s\" is not FAT.", node);
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
|
r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return log_error_errno(errno ?: SYNTHETIC_ERRNO(EIO), "Failed to probe partition scheme of \"%s\": %m", node);
|
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||||
|
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||||
|
"File system \"%s\" is not located on a partitioned block device.", node);
|
||||||
if (!streq(v, "gpt"))
|
if (!streq(v, "gpt"))
|
||||||
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
return log_full_errno(searching ? LOG_DEBUG : LOG_ERR,
|
||||||
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
SYNTHETIC_ERRNO(searching ? EADDRNOTAVAIL : ENODEV),
|
||||||
|
|
|
@ -95,7 +95,19 @@ int fstab_filter_options(const char *opts, const char *names,
|
||||||
|
|
||||||
if (!ret_filtered) {
|
if (!ret_filtered) {
|
||||||
for (const char *word = opts;;) {
|
for (const char *word = opts;;) {
|
||||||
const char *end = word + strcspn(word, ",");
|
const char *end = word;
|
||||||
|
|
||||||
|
/* Look for an *non-escaped* comma separator. Only commas can be escaped, so "\," is
|
||||||
|
* the only valid escape sequence, so we can do a very simple test here. */
|
||||||
|
for (;;) {
|
||||||
|
size_t n = strcspn(end, ",");
|
||||||
|
|
||||||
|
end += n;
|
||||||
|
if (n > 0 && end[-1] == '\\')
|
||||||
|
end++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
NULSTR_FOREACH(name, names) {
|
NULSTR_FOREACH(name, names) {
|
||||||
if (end < word + strlen(name))
|
if (end < word + strlen(name))
|
||||||
|
@ -128,9 +140,10 @@ int fstab_filter_options(const char *opts, const char *names,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stor = strv_split(opts, ",");
|
r = strv_split_full(&stor, opts, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
|
||||||
if (!stor)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return r;
|
||||||
|
|
||||||
strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
|
strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
|
||||||
if (!strv)
|
if (!strv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -165,7 +178,7 @@ answer:
|
||||||
if (ret_filtered) {
|
if (ret_filtered) {
|
||||||
char *f;
|
char *f;
|
||||||
|
|
||||||
f = strv_join(strv, ",");
|
f = strv_join_full(strv, ",", NULL, true);
|
||||||
if (!f)
|
if (!f)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
|
#include "cgroup-util.h"
|
||||||
#include "dropin.h"
|
#include "dropin.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
|
@ -620,6 +621,11 @@ int generator_write_cryptsetup_service_section(
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_setup_generator(void) {
|
void log_setup_generator(void) {
|
||||||
|
/* Disable talking to syslog/journal (i.e. the two IPC-based loggers) if we run in system context. */
|
||||||
|
if (cg_pid_get_owner_uid(0, NULL) == -ENXIO /* not running in a per-user slice */)
|
||||||
log_set_prohibit_ipc(true);
|
log_set_prohibit_ipc(true);
|
||||||
log_setup_service();
|
|
||||||
|
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); /* This effectively means: journal for per-user generators, kmsg otherwise */
|
||||||
|
log_parse_environment();
|
||||||
|
(void) log_open();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,12 +118,13 @@ static int device_new_from_dev_path(const char *devlink, sd_device **ret_device)
|
||||||
|
|
||||||
assert(devlink);
|
assert(devlink);
|
||||||
|
|
||||||
r = stat(devlink, &st);
|
if (stat(devlink, &st) < 0)
|
||||||
if (r < 0)
|
return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
|
||||||
return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to stat() %s: %m", devlink);
|
"Failed to stat() %s: %m", devlink);
|
||||||
|
|
||||||
if (!S_ISBLK(st.st_mode))
|
if (!S_ISBLK(st.st_mode))
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "%s does not point to a block device: %m", devlink);
|
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
||||||
|
"%s does not point to a block device: %m", devlink);
|
||||||
|
|
||||||
r = sd_device_new_from_devnum(ret_device, 'b', st.st_rdev);
|
r = sd_device_new_from_devnum(ret_device, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -18,7 +18,6 @@ static void do_fstab_filter_options(const char *opts,
|
||||||
const char *name_expected,
|
const char *name_expected,
|
||||||
const char *value_expected,
|
const char *value_expected,
|
||||||
const char *filtered_expected) {
|
const char *filtered_expected) {
|
||||||
|
|
||||||
int r;
|
int r;
|
||||||
const char *name;
|
const char *name;
|
||||||
_cleanup_free_ char *value = NULL, *filtered = NULL;
|
_cleanup_free_ char *value = NULL, *filtered = NULL;
|
||||||
|
@ -34,7 +33,7 @@ static void do_fstab_filter_options(const char *opts,
|
||||||
|
|
||||||
/* also test the malloc-less mode */
|
/* also test the malloc-less mode */
|
||||||
r = fstab_filter_options(opts, remove, &name, NULL, NULL);
|
r = fstab_filter_options(opts, remove, &name, NULL, NULL);
|
||||||
log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"",
|
log_info("\"%s\" → %d, \"%s\", expected %d, \"%s\"\n-",
|
||||||
opts, r, name,
|
opts, r, name,
|
||||||
r_expected, name_expected);
|
r_expected, name_expected);
|
||||||
assert_se(r == r_expected);
|
assert_se(r == r_expected);
|
||||||
|
@ -54,6 +53,12 @@ static void test_fstab_filter_options(void) {
|
||||||
do_fstab_filter_options("opt,other", "x-opt\0opt\0", 1, "opt", NULL, "other");
|
do_fstab_filter_options("opt,other", "x-opt\0opt\0", 1, "opt", NULL, "other");
|
||||||
do_fstab_filter_options("x-opt,other", "opt\0x-opt\0", 1, "x-opt", NULL, "other");
|
do_fstab_filter_options("x-opt,other", "opt\0x-opt\0", 1, "x-opt", NULL, "other");
|
||||||
|
|
||||||
|
do_fstab_filter_options("opt=0\\,1,other", "opt\0x-opt\0", 1, "opt", "0,1", "other");
|
||||||
|
do_fstab_filter_options("opt=0,other,x-opt\\,foobar", "x-opt\0opt\0", 1, "opt", "0", "other,x-opt\\,foobar");
|
||||||
|
do_fstab_filter_options("opt,other,x-opt\\,part", "opt\0x-opt\0", 1, "opt", NULL, "other,x-opt\\,part");
|
||||||
|
do_fstab_filter_options("opt,other,part\\,x-opt", "x-opt\0opt\0", 1, "opt", NULL, "other,part\\,x-opt");
|
||||||
|
do_fstab_filter_options("opt,other\\,\\,\\,opt,x-part", "opt\0x-opt\0", 1, "opt", NULL, "other\\,\\,\\,opt,x-part");
|
||||||
|
|
||||||
do_fstab_filter_options("opto=0,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
do_fstab_filter_options("opto=0,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||||
do_fstab_filter_options("opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
do_fstab_filter_options("opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||||
do_fstab_filter_options("x-opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
do_fstab_filter_options("x-opto,other", "opt\0x-opt\0", 0, NULL, NULL, NULL);
|
||||||
|
|
|
@ -162,71 +162,84 @@ static void test_strv_find_startswith(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_strv_join(void) {
|
static void test_strv_join(void) {
|
||||||
_cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
|
|
||||||
|
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
p = strv_join((char **)input_table_multiple, ", ");
|
_cleanup_free_ char *p = strv_join((char **)input_table_multiple, ", ");
|
||||||
assert_se(p);
|
assert_se(p);
|
||||||
assert_se(streq(p, "one, two, three"));
|
assert_se(streq(p, "one, two, three"));
|
||||||
|
|
||||||
q = strv_join((char **)input_table_multiple, ";");
|
_cleanup_free_ char *q = strv_join((char **)input_table_multiple, ";");
|
||||||
assert_se(q);
|
assert_se(q);
|
||||||
assert_se(streq(q, "one;two;three"));
|
assert_se(streq(q, "one;two;three"));
|
||||||
|
|
||||||
r = strv_join((char **)input_table_multiple, NULL);
|
_cleanup_free_ char *r = strv_join((char **)input_table_multiple, NULL);
|
||||||
assert_se(r);
|
assert_se(r);
|
||||||
assert_se(streq(r, "one two three"));
|
assert_se(streq(r, "one two three"));
|
||||||
|
|
||||||
s = strv_join((char **)input_table_one, ", ");
|
_cleanup_free_ char *s = strv_join(STRV_MAKE("1", "2", "3,3"), ",");
|
||||||
assert_se(s);
|
assert_se(s);
|
||||||
assert_se(streq(s, "one"));
|
assert_se(streq(s, "1,2,3,3"));
|
||||||
|
|
||||||
t = strv_join((char **)input_table_none, ", ");
|
_cleanup_free_ char *t = strv_join((char **)input_table_one, ", ");
|
||||||
assert_se(t);
|
assert_se(t);
|
||||||
assert_se(streq(t, ""));
|
assert_se(streq(t, "one"));
|
||||||
|
|
||||||
v = strv_join((char **)input_table_two_empties, ", ");
|
_cleanup_free_ char *u = strv_join((char **)input_table_none, ", ");
|
||||||
|
assert_se(u);
|
||||||
|
assert_se(streq(u, ""));
|
||||||
|
|
||||||
|
_cleanup_free_ char *v = strv_join((char **)input_table_two_empties, ", ");
|
||||||
assert_se(v);
|
assert_se(v);
|
||||||
assert_se(streq(v, ", "));
|
assert_se(streq(v, ", "));
|
||||||
|
|
||||||
w = strv_join((char **)input_table_one_empty, ", ");
|
_cleanup_free_ char *w = strv_join((char **)input_table_one_empty, ", ");
|
||||||
assert_se(w);
|
assert_se(w);
|
||||||
assert_se(streq(w, ""));
|
assert_se(streq(w, ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_strv_join_prefix(void) {
|
static void test_strv_join_full(void) {
|
||||||
_cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
|
|
||||||
|
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
p = strv_join_prefix((char **)input_table_multiple, ", ", "foo");
|
_cleanup_free_ char *p = strv_join_full((char **)input_table_multiple, ", ", "foo", false);
|
||||||
assert_se(p);
|
assert_se(p);
|
||||||
assert_se(streq(p, "fooone, footwo, foothree"));
|
assert_se(streq(p, "fooone, footwo, foothree"));
|
||||||
|
|
||||||
q = strv_join_prefix((char **)input_table_multiple, ";", "foo");
|
_cleanup_free_ char *q = strv_join_full((char **)input_table_multiple, ";", "foo", false);
|
||||||
assert_se(q);
|
assert_se(q);
|
||||||
assert_se(streq(q, "fooone;footwo;foothree"));
|
assert_se(streq(q, "fooone;footwo;foothree"));
|
||||||
|
|
||||||
r = strv_join_prefix((char **)input_table_multiple, NULL, "foo");
|
_cleanup_free_ char *r = strv_join_full(STRV_MAKE("a", "a;b", "a:c"), ";", NULL, true);
|
||||||
assert_se(r);
|
assert_se(r);
|
||||||
assert_se(streq(r, "fooone footwo foothree"));
|
assert_se(streq(r, "a;a\\;b;a:c"));
|
||||||
|
|
||||||
s = strv_join_prefix((char **)input_table_one, ", ", "foo");
|
_cleanup_free_ char *s = strv_join_full(STRV_MAKE("a", "a;b", "a;;c", ";", ";x"), ";", NULL, true);
|
||||||
assert_se(s);
|
assert_se(s);
|
||||||
assert_se(streq(s, "fooone"));
|
assert_se(streq(s, "a;a\\;b;a\\;\\;c;\\;;\\;x"));
|
||||||
|
|
||||||
t = strv_join_prefix((char **)input_table_none, ", ", "foo");
|
_cleanup_free_ char *t = strv_join_full(STRV_MAKE("a", "a;b", "a:c", ";"), ";", "=", true);
|
||||||
assert_se(t);
|
assert_se(t);
|
||||||
assert_se(streq(t, ""));
|
assert_se(streq(t, "=a;=a\\;b;=a:c;=\\;"));
|
||||||
|
t = mfree(t);
|
||||||
|
|
||||||
v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo");
|
_cleanup_free_ char *u = strv_join_full((char **)input_table_multiple, NULL, "foo", false);
|
||||||
|
assert_se(u);
|
||||||
|
assert_se(streq(u, "fooone footwo foothree"));
|
||||||
|
|
||||||
|
_cleanup_free_ char *v = strv_join_full((char **)input_table_one, ", ", "foo", false);
|
||||||
assert_se(v);
|
assert_se(v);
|
||||||
assert_se(streq(v, "foo, foo"));
|
assert_se(streq(v, "fooone"));
|
||||||
|
|
||||||
w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo");
|
_cleanup_free_ char *w = strv_join_full((char **)input_table_none, ", ", "foo", false);
|
||||||
assert_se(w);
|
assert_se(w);
|
||||||
assert_se(streq(w, "foo"));
|
assert_se(streq(w, ""));
|
||||||
|
|
||||||
|
_cleanup_free_ char *x = strv_join_full((char **)input_table_two_empties, ", ", "foo", false);
|
||||||
|
assert_se(x);
|
||||||
|
assert_se(streq(x, "foo, foo"));
|
||||||
|
|
||||||
|
_cleanup_free_ char *y = strv_join_full((char **)input_table_one_empty, ", ", "foo", false);
|
||||||
|
assert_se(y);
|
||||||
|
assert_se(streq(y, "foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_strv_unquote(const char *quoted, char **list) {
|
static void test_strv_unquote(const char *quoted, char **list) {
|
||||||
|
@ -995,7 +1008,7 @@ int main(int argc, char *argv[]) {
|
||||||
test_strv_find_prefix();
|
test_strv_find_prefix();
|
||||||
test_strv_find_startswith();
|
test_strv_find_startswith();
|
||||||
test_strv_join();
|
test_strv_join();
|
||||||
test_strv_join_prefix();
|
test_strv_join_full();
|
||||||
|
|
||||||
test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz"));
|
test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz"));
|
||||||
test_strv_unquote("", STRV_MAKE_EMPTY);
|
test_strv_unquote("", STRV_MAKE_EMPTY);
|
||||||
|
|
|
@ -110,10 +110,8 @@ static const char* parse_token(const char *current, int32_t *val_out) {
|
||||||
static int override_abs(sd_device *dev, int fd, unsigned evcode, const char *value) {
|
static int override_abs(sd_device *dev, int fd, unsigned evcode, const char *value) {
|
||||||
struct input_absinfo absinfo;
|
struct input_absinfo absinfo;
|
||||||
const char *next;
|
const char *next;
|
||||||
int r;
|
|
||||||
|
|
||||||
r = ioctl(fd, EVIOCGABS(evcode), &absinfo);
|
if (ioctl(fd, EVIOCGABS(evcode), &absinfo) < 0)
|
||||||
if (r < 0)
|
|
||||||
return log_device_error_errno(dev, errno, "Failed to call EVIOCGABS");
|
return log_device_error_errno(dev, errno, "Failed to call EVIOCGABS");
|
||||||
|
|
||||||
next = parse_token(value, &absinfo.minimum);
|
next = parse_token(value, &absinfo.minimum);
|
||||||
|
@ -122,12 +120,12 @@ static int override_abs(sd_device *dev, int fd, unsigned evcode, const char *val
|
||||||
next = parse_token(next, &absinfo.fuzz);
|
next = parse_token(next, &absinfo.fuzz);
|
||||||
next = parse_token(next, &absinfo.flat);
|
next = parse_token(next, &absinfo.flat);
|
||||||
if (!next)
|
if (!next)
|
||||||
return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Failed to parse EV_ABS override '%s'", value);
|
return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Failed to parse EV_ABS override '%s'", value);
|
||||||
|
|
||||||
log_device_debug(dev, "keyboard: %x overridden with %"PRIi32"/%"PRIi32"/%"PRIi32"/%"PRIi32"/%"PRIi32,
|
log_device_debug(dev, "keyboard: %x overridden with %"PRIi32"/%"PRIi32"/%"PRIi32"/%"PRIi32"/%"PRIi32,
|
||||||
evcode, absinfo.minimum, absinfo.maximum, absinfo.resolution, absinfo.fuzz, absinfo.flat);
|
evcode, absinfo.minimum, absinfo.maximum, absinfo.resolution, absinfo.fuzz, absinfo.flat);
|
||||||
r = ioctl(fd, EVIOCSABS(evcode), &absinfo);
|
if (ioctl(fd, EVIOCSABS(evcode), &absinfo) < 0)
|
||||||
if (r < 0)
|
|
||||||
return log_device_error_errno(dev, errno, "Failed to call EVIOCSABS");
|
return log_device_error_errno(dev, errno, "Failed to call EVIOCSABS");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -60,11 +60,12 @@ fi
|
||||||
umount ${image_dir}/mount
|
umount ${image_dir}/mount
|
||||||
umount ${image_dir}/mount2
|
umount ${image_dir}/mount2
|
||||||
|
|
||||||
systemd-run -t --property RootImage=${image}.raw /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p RootImage=${image}.raw cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
mv ${image}.verity ${image}.fooverity
|
mv ${image}.verity ${image}.fooverity
|
||||||
mv ${image}.roothash ${image}.foohash
|
mv ${image}.roothash ${image}.foohash
|
||||||
systemd-run -t --property RootImage=${image}.raw --property RootHash=${image}.foohash --property RootVerity=${image}.fooverity /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p RootImage=${image}.raw -p RootHash=${image}.foohash -p RootVerity=${image}.fooverity cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property RootImage=${image}.raw --property RootHash=${roothash} --property RootVerity=${image}.fooverity /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
# Let's use the long option name just here as a test
|
||||||
|
systemd-run -t --property RootImage=${image}.raw --property RootHash=${roothash} --property RootVerity=${image}.fooverity cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
mv ${image}.fooverity ${image}.verity
|
mv ${image}.fooverity ${image}.verity
|
||||||
mv ${image}.foohash ${image}.roothash
|
mv ${image}.foohash ${image}.roothash
|
||||||
|
|
||||||
|
@ -128,19 +129,19 @@ cat ${image_dir}/mount/etc/os-release | grep -q -F -f $os_release
|
||||||
cat ${image_dir}/mount/usr/lib/os-release | grep -q -F "MARKER=1"
|
cat ${image_dir}/mount/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
umount ${image_dir}/mount
|
umount ${image_dir}/mount
|
||||||
|
|
||||||
systemd-run -t --property RootImage=${image}.gpt --property RootHash=${roothash} /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
# add explicit -p MountAPIVFS=yes once to test the parser
|
||||||
|
systemd-run -t -p RootImage=${image}.gpt -p RootHash=${roothash} -p MountAPIVFS=yes cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
|
|
||||||
systemd-run -t --property RootImage=${image}.raw --property RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p RootImage=${image}.raw -p RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t --property RootImage=${image}.gpt --property RootImageOptions="root:ro,noatime root:ro,dev" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "noatime"
|
systemd-run -t -p RootImage=${image}.gpt -p RootImageOptions="root:ro,noatime root:ro,dev" mount | grep -F "squashfs" | grep -q -F "noatime"
|
||||||
|
|
||||||
mkdir -p mkdir -p ${image_dir}/result
|
mkdir -p mkdir -p ${image_dir}/result
|
||||||
cat > /run/systemd/system/testservice-50a.service <<EOF
|
cat >/run/systemd/system/testservice-50a.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=bash -c "mount > /run/result/a"
|
ExecStart=bash -c "mount >/run/result/a"
|
||||||
BindPaths=${image_dir}/result:/run/result
|
BindPaths=${image_dir}/result:/run/result
|
||||||
TemporaryFileSystem=/run
|
TemporaryFileSystem=/run
|
||||||
MountAPIVFS=yes
|
|
||||||
RootImage=${image}.raw
|
RootImage=${image}.raw
|
||||||
RootImageOptions=root:ro,noatime home:ro,dev relatime,dev
|
RootImageOptions=root:ro,noatime home:ro,dev relatime,dev
|
||||||
RootImageOptions=nosuid,dev
|
RootImageOptions=nosuid,dev
|
||||||
|
@ -149,33 +150,34 @@ systemctl start testservice-50a.service
|
||||||
grep -F "squashfs" ${image_dir}/result/a | grep -q -F "noatime"
|
grep -F "squashfs" ${image_dir}/result/a | grep -q -F "noatime"
|
||||||
grep -F "squashfs" ${image_dir}/result/a | grep -q -F -v "nosuid"
|
grep -F "squashfs" ${image_dir}/result/a | grep -q -F -v "nosuid"
|
||||||
|
|
||||||
cat > /run/systemd/system/testservice-50b.service <<EOF
|
cat >/run/systemd/system/testservice-50b.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
ExecStart=bash -c "mount > /run/result/b"
|
ExecStart=bash -c "mount >/run/result/b"
|
||||||
BindPaths=${image_dir}/result:/run/result
|
BindPaths=${image_dir}/result:/run/result
|
||||||
TemporaryFileSystem=/run
|
TemporaryFileSystem=/run
|
||||||
MountAPIVFS=yes
|
|
||||||
RootImage=${image}.gpt
|
RootImage=${image}.gpt
|
||||||
RootImageOptions=root:ro,noatime,nosuid home:ro,dev nosuid,dev
|
RootImageOptions=root:ro,noatime,nosuid home:ro,dev nosuid,dev
|
||||||
RootImageOptions=home:ro,dev nosuid,dev,%%foo
|
RootImageOptions=home:ro,dev nosuid,dev,%%foo
|
||||||
|
# this is the default, but let's specify once to test the parser
|
||||||
|
MountAPIVFS=yes
|
||||||
EOF
|
EOF
|
||||||
systemctl start testservice-50b.service
|
systemctl start testservice-50b.service
|
||||||
grep -F "squashfs" ${image_dir}/result/b | grep -q -F "noatime"
|
grep -F "squashfs" ${image_dir}/result/b | grep -q -F "noatime"
|
||||||
|
|
||||||
# Check that specifier escape is applied %%foo -> %foo
|
# Check that specifier escape is applied %%foo → %foo
|
||||||
busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo"
|
busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo"
|
||||||
|
|
||||||
# Now do some checks with MountImages, both by itself, with options and in combination with RootImage, and as single FS or GPT image
|
# Now do some checks with MountImages, both by itself, with options and in combination with RootImage, and as single FS or GPT image
|
||||||
systemd-run -t --property MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" /usr/bin/cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" /usr/bin/cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2:nosuid,dev" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2:nosuid,dev" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t --property MountImages="${image}.gpt:/run/img1:root:nosuid ${image}.raw:/run/img2:home:suid" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p MountImages="${image}.gpt:/run/img1:root:nosuid ${image}.raw:/run/img2:home:suid" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t --property MountImages="${image}.raw:/run/img2\:3" /usr/bin/cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p MountImages="${image}.raw:/run/img2\:3" cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property MountImages="${image}.raw:/run/img2\:3:nosuid" --property MountAPIVFS=yes mount | grep -F "squashfs" | grep -q -F "nosuid"
|
systemd-run -t -p MountImages="${image}.raw:/run/img2\:3:nosuid" mount | grep -F "squashfs" | grep -q -F "nosuid"
|
||||||
systemd-run -t --property TemporaryFileSystem=/run --property RootImage=${image}.raw --property MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" /usr/bin/cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p TemporaryFileSystem=/run -p RootImage=${image}.raw -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property TemporaryFileSystem=/run --property RootImage=${image}.raw --property MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" /usr/bin/cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p TemporaryFileSystem=/run -p RootImage=${image}.raw -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
systemd-run -t --property TemporaryFileSystem=/run --property RootImage=${image}.gpt --property RootHash=${roothash} --property MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" /usr/bin/cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
|
systemd-run -t -p TemporaryFileSystem=/run -p RootImage=${image}.gpt -p RootHash=${roothash} -p MountImages="${image}.gpt:/run/img1 ${image}.raw:/run/img2" cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
|
||||||
cat >/run/systemd/system/testservice-50c.service <<EOF
|
cat >/run/systemd/system/testservice-50c.service <<EOF
|
||||||
[Service]
|
[Service]
|
||||||
MountAPIVFS=yes
|
MountAPIVFS=yes
|
||||||
|
@ -183,9 +185,9 @@ TemporaryFileSystem=/run
|
||||||
RootImage=${image}.raw
|
RootImage=${image}.raw
|
||||||
MountImages=${image}.gpt:/run/img1:root:noatime:home:relatime
|
MountImages=${image}.gpt:/run/img1:root:noatime:home:relatime
|
||||||
MountImages=${image}.raw:/run/img2\:3:nosuid
|
MountImages=${image}.raw:/run/img2\:3:nosuid
|
||||||
ExecStart=bash -c "cat /run/img1/usr/lib/os-release > /run/result/c"
|
ExecStart=bash -c "cat /run/img1/usr/lib/os-release >/run/result/c"
|
||||||
ExecStart=bash -c "cat /run/img2:3/usr/lib/os-release >> /run/result/c"
|
ExecStart=bash -c "cat /run/img2:3/usr/lib/os-release >>/run/result/c"
|
||||||
ExecStart=bash -c "mount >> /run/result/c"
|
ExecStart=bash -c "mount >>/run/result/c"
|
||||||
BindPaths=${image_dir}/result:/run/result
|
BindPaths=${image_dir}/result:/run/result
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
EOF
|
EOF
|
||||||
|
@ -194,6 +196,6 @@ grep -q -F "MARKER=1" ${image_dir}/result/c
|
||||||
grep -F "squashfs" ${image_dir}/result/c | grep -q -F "noatime"
|
grep -F "squashfs" ${image_dir}/result/c | grep -q -F "noatime"
|
||||||
grep -F "squashfs" ${image_dir}/result/c | grep -q -F -v "nosuid"
|
grep -F "squashfs" ${image_dir}/result/c | grep -q -F -v "nosuid"
|
||||||
|
|
||||||
echo OK > /testok
|
echo OK >/testok
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|
Loading…
Reference in New Issue