]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #15352 from poettering/user-group-name-valdity-rework
authorLennart Poettering <lennart@poettering.net>
Thu, 9 Apr 2020 16:49:22 +0000 (18:49 +0200)
committerGitHub <noreply@github.com>
Thu, 9 Apr 2020 16:49:22 +0000 (18:49 +0200)
user/group name validity rework

47 files changed:
docs/TRANSIENT-SETTINGS.md
hwdb.d/60-keyboard.hwdb
man/systemd-run.xml
man/systemd.exec.xml
man/systemd.network.xml
man/systemd.service.xml
man/systemd.unit.xml
src/basic/escape.c
src/basic/escape.h
src/basic/parse-util.c
src/basic/parse-util.h
src/basic/process-util.c
src/basic/process-util.h
src/basic/terminal-util.h
src/core/dbus-execute.c
src/core/execute.c
src/core/execute.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/main.c
src/core/mount-setup.c
src/core/mount-setup.h
src/core/unit.c
src/libsystemd-network/lldp-neighbor.c
src/libsystemd-network/lldp-neighbor.h
src/network/networkd-lldp-tx.c
src/network/networkd-lldp-tx.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/run/run.c
src/shared/bus-unit-util.c
src/shared/bus-util.c
src/shared/bus-util.h
src/shared/coredump-util.c [new file with mode: 0644]
src/shared/coredump-util.h [new file with mode: 0644]
src/shared/meson.build
src/shared/sleep-config.c
src/systemd/sd-lldp.h
src/test/meson.build
src/test/test-coredump-util.c [new file with mode: 0644]
src/test/test-escape.c
src/test/test-parse-util.c
src/test/test-terminal-util.c
test/fuzz/fuzz-network-parser/directives.network
test/fuzz/fuzz-unit-file/directives.service

index 271d8ab1e3d6d23670bac8a736f987e912b17c42..d5a80466769841be47e77e173875713c0bfdd927 100644 (file)
@@ -114,6 +114,7 @@ All execution-related settings are available for transient units.
 ✓ SupplementaryGroups=
 ✓ Nice=
 ✓ OOMScoreAdjust=
+✓ CoredumpFilter=
 ✓ IOSchedulingClass=
 ✓ IOSchedulingPriority=
 ✓ CPUSchedulingPolicy=
index 176ec3836a36f9b94caefb5a372630dc39739871..ee335c8c1180878a25ff4547a4f47c78c1d8ac9c 100644 (file)
@@ -160,6 +160,11 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*8930:*
 evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*7750G:pvr*
  KEYBOARD_KEY_e0=!pageup
 
+# Predator PH 315-52
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredator*PH*315-52:pvr*
+ KEYBOARD_KEY_ef=kbdillumup                             # Fn+F10
+ KEYBOARD_KEY_f0=kbdillumdown                           # Fn+F9
+
 # Travelmate C300
 evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr*
  KEYBOARD_KEY_67=f24                                    # FIXME: rotate screen
index 3a1d18dae9ad7b3f7c5e15e67d46bf8f88bc2fec..a88f60fbb6017da5055e7f52b55448e2c5a51b96 100644 (file)
       <varlistentry>
         <term><option>--slice=</option></term>
 
-        <listitem><para>Make the new <filename>.service</filename> or <filename>.scope</filename> unit part of the
-        specified slice, instead of <filename>system.slice</filename>.</para>
+        <listitem><para>Make the new <filename>.service</filename> or <filename>.scope</filename> unit part
+        of the specified slice, instead of <filename>system.slice</filename> (when running in
+        <option>--system</option> mode) or the root slice (when running in <option>--user</option>
+        mode).</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><option>--slice-inherit</option></term>
+
+        <listitem><para>Make the new <filename>.service</filename> or <filename>.scope</filename> unit part
+        of the inherited slice. This option can be combined with <option>--slice=</option>.</para>
+
+        <para>An inherited slice is located within <command>systemd-run</command> slice. Example: if
+        <command>systemd-run</command> slice is <filename>foo.slice</filename>, and the
+        <option>--slice=</option> argument is <filename>bar</filename>, the unit will be placed under the
+        <filename>foo-bar.slice</filename>.</para>
+
         </listitem>
       </varlistentry>
 
index fd1755e422a2f652dd7cbfd0d2b5387b14bd97fb..54b07e30043f4dc812e1fc8ec47aef3c26c3dfd1 100644 (file)
@@ -655,8 +655,39 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <term><varname>UMask=</varname></term>
 
         <listitem><para>Controls the file mode creation mask. Takes an access mode in octal notation. See
-        <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for details. Defaults
-        to 0022.</para></listitem>
+        <citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
+        details. Defaults to 0022 for system units. For units of the user service manager the default value
+        is inherited from the user instance (whose default is inherited from the system service manager, and
+        thus also is 0022). Hence changing the default value of a user instance, either via
+        <varname>UMask=</varname> or via a PAM module, will affect the user instance itself and all user
+        units started by the user instance unless a user unit has specified its own
+        <varname>UMask=</varname>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>CoredumpFilter=</varname></term>
+
+        <listitem><para>Controls which types of memory mappings will be saved if the process dumps core
+        (using the <filename>/proc/<replaceable>pid</replaceable>/coredump_filter</filename> file). Takes a
+        whitespace-separated combination of mapping type names or numbers (with the default base 16). Mapping
+        type names are <constant>private-anonymous</constant>, <constant>shared-anonymous</constant>,
+        <constant>private-file-backed</constant>, <constant>shared-file-backed</constant>,
+        <constant>elf-headers</constant>, <constant>private-huge</constant>,
+        <constant>shared-huge</constant>, <constant>private-dax</constant>, <constant>shared-dax</constant>,
+        and the special values <constant>all</constant> (all types) and <constant>default</constant> (the
+        kernel default of <literal><constant>private-anonymous</constant>
+        <constant>shared-anonymous</constant> <constant>elf-headers</constant>
+        <constant>private-huge</constant></literal>). See
+        <citerefentry><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry> for the
+        meaning of the mapping types. When specified multiple times, all specified masks are ORed. When not
+        set, or if the empty value is assigned, the inherited value is not changed.</para>
+
+        <example>
+          <title>Add DAX pages to the dump filter</title>
+
+          <programlisting>CoredumpFilter=default private-dax shared-dax</programlisting>
+        </example>
+        </listitem>
       </varlistentry>
 
       <varlistentry>
index d2cdb59f461636df053fea19e3a536b17b5d5b76..8d11922c71e2761a26e739d220ba90e32f655cc5 100644 (file)
             reception.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><varname>BindCarrier=</varname></term>
           <listitem>
       </variablelist>
   </refsect1>
 
+  <refsect1>
+    <title>[LLDP] Section Options</title>
+      <para>The <literal>[LLDP]</literal> section manages the Link Layer Discovery Protocol (LLDP) and accepts the
+      following keys.</para>
+      <variablelist class='network-directives'>
+        <varlistentry>
+          <term><varname>MUDURL=</varname></term>
+          <listitem>
+            <para>Controls support for Ethernet LLDP packet's Manufacturer Usage Description (MUD). MUD is an embedded software
+            standard defined by the IETF that allows IoT Device makers to advertise device specifications, including the intended
+            communication patterns for their device when it connects to the network. The network can then use this intent to author
+            a context-specific access policy, so the device functions only within those parameters. Takes an URL of length up to 255
+            characters. A superficial verification that the string is a valid URL
+            will be performed. See
+            <ulink url="https://tools.ietf.org/html/rfc8520">RFC 8520</ulink> for details. The MUD URL received
+            from the LLDP packets will be saved at the state files and can be read via
+            <function>sd_lldp_neighbor_get_mud_url()</function> function.</para>
+          </listitem>
+        </varlistentry>
+      </variablelist>
+  </refsect1>
+
   <refsect1>
     <title>[CAN] Section Options</title>
       <para>The <literal>[CAN]</literal> section manages the Controller Area Network (CAN bus) and accepts the
index 17e446e203f107552b9fc9a5a1110c3d8b958d8a..02eb7067899410c0af0d3e167655e62ba760365a 100644 (file)
         <varname>ExecStart=</varname>, or <varname>ExecStartPost=</varname> fail (and are not prefixed with
         <literal>-</literal>, see above) or time out before the service is fully up, execution continues with commands
         specified in <varname>ExecStopPost=</varname>, the commands in <varname>ExecStop=</varname> are skipped.</para>
+
+        <para>Note that the execution of <varname>ExecStartPost=</varname> is taken into account for the purpose of
+        <varname>Before=</varname>/<varname>After=</varname> ordering constraints.</para>
         </listitem>
       </varlistentry>
 
         service, as well as the main process' exit code and status, set in the <varname>$SERVICE_RESULT</varname>,
         <varname>$EXIT_CODE</varname> and <varname>$EXIT_STATUS</varname> environment variables, see
         <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
-        details.</para></listitem>
+        details.</para>
+
+        <para>Note that the execution of <varname>ExecStopPost=</varname> is taken into account for the purpose of
+        <varname>Before=</varname>/<varname>After=</varname> ordering constraints.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 64240208c2bdac0c6d8ba11059e6410c54894b27..d0de9aa5006fdb9e484969c5339446205f9e75c5 100644 (file)
         type when precisely a unit has finished starting up. Most importantly, for service units start-up is
         considered completed for the purpose of <varname>Before=</varname>/<varname>After=</varname> when all
         its configured start-up commands have been invoked and they either failed or reported start-up
-        success.</para>
+        success. Note that this does includes <varname>ExecStartPost=</varname> (or
+        <varname>ExecStopPost=</varname> for the shutdown case).</para>
 
         <para>Note that those settings are independent of and orthogonal to the requirement dependencies as
         configured by <varname>Requires=</varname>, <varname>Wants=</varname>, <varname>Requisite=</varname>,
index c5c44d2e7d8e940b087edf28e10e7c69031745e8..116efa4119d44f61ffef2111f27cf611c023acf5 100644 (file)
@@ -518,22 +518,28 @@ char* shell_maybe_quote(const char *s, EscapeStyle style) {
                 return NULL;
 
         t = r;
-        if (style == ESCAPE_BACKSLASH)
+        switch (style) {
+        case ESCAPE_BACKSLASH:
+        case ESCAPE_BACKSLASH_ONELINE:
                 *(t++) = '"';
-        else if (style == ESCAPE_POSIX) {
+                break;
+        case ESCAPE_POSIX:
                 *(t++) = '$';
                 *(t++) = '\'';
-        } else
+                break;
+        default:
                 assert_not_reached("Bad EscapeStyle");
+        }
 
         t = mempcpy(t, s, p - s);
 
-        if (style == ESCAPE_BACKSLASH)
-                t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false);
+        if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE))
+                t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE,
+                                             style == ESCAPE_BACKSLASH_ONELINE);
         else
                 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true);
 
-        if (style == ESCAPE_BACKSLASH)
+        if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE))
                 *(t++) = '"';
         else
                 *(t++) = '\'';
index b8eb137c3d398bf4e6adf48c33d3f7721eaac7d4..0b00b116edc82a5b6105bd881cbba94fb26cd3da 100644 (file)
@@ -34,8 +34,13 @@ typedef enum UnescapeFlags {
 } UnescapeFlags;
 
 typedef enum EscapeStyle {
-        ESCAPE_BACKSLASH = 1,
-        ESCAPE_POSIX     = 2,
+        ESCAPE_BACKSLASH         = 1,  /* Add shell quotes ("") so the shell will consider this a single
+                                          argument, possibly multiline. Tabs and newlines are not escaped. */
+        ESCAPE_BACKSLASH_ONELINE = 2,  /* Similar to ESCAPE_BACKSLASH, but always produces a single-line
+                                          string instead. Shell escape sequences are produced for tabs and
+                                          newlines. */
+        ESCAPE_POSIX             = 3,  /* Similar to ESCAPE_BACKSLASH_ONELINE, but uses POSIX shell escape
+                                        * syntax (a string enclosed in $'') instead of plain quotes. */
 } EscapeStyle;
 
 char *cescape(const char *s);
index e0094b0f370a8943774b8ef5066420990441487a..8de5cd5c568361e517c539b2022a77635ca19141 100644 (file)
@@ -395,7 +395,7 @@ int safe_atoi(const char *s, int *ret_i) {
         return 0;
 }
 
-int safe_atollu(const char *s, long long unsigned *ret_llu) {
+int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) {
         char *x = NULL;
         unsigned long long l;
 
@@ -404,7 +404,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
         s += strspn(s, WHITESPACE);
 
         errno = 0;
-        l = strtoull(s, &x, 0);
+        l = strtoull(s, &x, base);
         if (errno > 0)
                 return -errno;
         if (!x || x == s || *x != 0)
index 36d76ba57617b5f98bc9c4a371e2593881935655..970bdefbf0e53a49ea55431a5a55547e54018451 100644 (file)
@@ -28,7 +28,6 @@ static inline int safe_atou(const char *s, unsigned *ret_u) {
 }
 
 int safe_atoi(const char *s, int *ret_i);
-int safe_atollu(const char *s, unsigned long long *ret_u);
 int safe_atolli(const char *s, long long int *ret_i);
 
 int safe_atou8(const char *s, uint8_t *ret);
@@ -59,6 +58,12 @@ static inline int safe_atoi32(const char *s, int32_t *ret_i) {
         return safe_atoi(s, (int*) ret_i);
 }
 
+int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu);
+
+static inline int safe_atollu(const char *s, long long unsigned *ret_llu) {
+        return safe_atollu_full(s, 0, ret_llu);
+}
+
 static inline int safe_atou64(const char *s, uint64_t *ret_u) {
         assert_cc(sizeof(uint64_t) == sizeof(unsigned long long));
         return safe_atollu(s, (unsigned long long*) ret_u);
@@ -69,6 +74,11 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) {
         return safe_atolli(s, (long long int*) ret_i);
 }
 
+static inline int safe_atoux64(const char *s, uint64_t *ret) {
+        assert_cc(sizeof(int64_t) == sizeof(long long unsigned));
+        return safe_atollu_full(s, 16, (long long unsigned*) ret);
+}
+
 #if LONG_MAX == INT_MAX
 static inline int safe_atolu(const char *s, unsigned long *ret_u) {
         assert_cc(sizeof(unsigned long) == sizeof(unsigned));
index fefc2bd840b79b804061619842c82b37ee5f1a00..704d6682532d707f46a29f1cc1708af7e8119ea6 100644 (file)
@@ -628,6 +628,23 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) {
         return 0;
 }
 
+int get_process_umask(pid_t pid, mode_t *umask) {
+        _cleanup_free_ char *m = NULL;
+        const char *p;
+        int r;
+
+        assert(umask);
+        assert(pid >= 0);
+
+        p = procfs_file_alloca(pid, "status");
+
+        r = get_proc_field(p, "Umask", WHITESPACE, &m);
+        if (r == -ENOENT)
+                return -ESRCH;
+
+        return parse_mode(m, umask);
+}
+
 int wait_for_terminate(pid_t pid, siginfo_t *status) {
         siginfo_t dummy;
 
index 4160af45ba7bcfef5bf9432180c54a29268a22ec..ca9825293c3a2eb1a678df3838301102afc69d07 100644 (file)
@@ -45,6 +45,7 @@ int get_process_cwd(pid_t pid, char **cwd);
 int get_process_root(pid_t pid, char **root);
 int get_process_environ(pid_t pid, char **environ);
 int get_process_ppid(pid_t pid, pid_t *ppid);
+int get_process_umask(pid_t pid, mode_t *umask);
 
 int wait_for_terminate(pid_t pid, siginfo_t *status);
 
index efc22b1591773a066ff8c56c19ac60533b582beb..c7570c7a617ff2c9d7604dd0f0da33f12b5193c5 100644 (file)
@@ -30,7 +30,7 @@
 /* Underlined */
 #define ANSI_HIGHLIGHT_RED_UNDERLINE     "\x1B[0;1;4;31m"
 #define ANSI_HIGHLIGHT_GREEN_UNDERLINE   "\x1B[0;1;4;32m"
-#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE  "\x1B[0;1;4;33m"
+#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE  "\x1B[0;1;4;38;5;185m"
 #define ANSI_HIGHLIGHT_BLUE_UNDERLINE    "\x1B[0;1;4;34m"
 #define ANSI_HIGHLIGHT_MAGENTA_UNDERLINE "\x1B[0;1;4;35m"
 #define ANSI_HIGHLIGHT_GREY_UNDERLINE    "\x1B[0;1;4;38;5;245m"
index 93857436b4efea57c8bedb42f168fbc5fd2e15bd..ebc8ea7e44c3b29886dece6654bf1fa71315491d 100644 (file)
@@ -102,6 +102,7 @@ static int property_get_oom_score_adjust(
 
         ExecContext *c = userdata;
         int32_t n;
+        int r;
 
         assert(bus);
         assert(reply);
@@ -113,13 +114,55 @@ static int property_get_oom_score_adjust(
                 _cleanup_free_ char *t = NULL;
 
                 n = 0;
-                if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
-                        safe_atoi32(t, &n);
+                r = read_one_line_file("/proc/self/oom_score_adj", &t);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to read /proc/self/oom_score_adj, ignoring: %m");
+                else {
+                        r = safe_atoi32(t, &n);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/oom_score_adj, ignoring: %m", t);
+                }
         }
 
         return sd_bus_message_append(reply, "i", n);
 }
 
+static int property_get_coredump_filter(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        ExecContext *c = userdata;
+        uint64_t n;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(c);
+
+        if (c->coredump_filter_set)
+                n = c->coredump_filter;
+        else {
+                _cleanup_free_ char *t = NULL;
+
+                n = COREDUMP_FILTER_MASK_DEFAULT;
+                r = read_one_line_file("/proc/self/coredump_filter", &t);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to read /proc/self/coredump_filter, ignoring: %m");
+                else {
+                        r = safe_atoux64(t, &n);
+                        if (r < 0)
+                                log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/coredump_filter, ignoring: %m", t);
+                }
+        }
+
+        return sd_bus_message_append(reply, "t", n);
+}
+
 static int property_get_nice(
                 sd_bus *bus,
                 const char *path,
@@ -747,6 +790,7 @@ const sd_bus_vtable bus_exec_vtable[] = {
         SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -2190,6 +2234,21 @@ int bus_exec_context_set_transient_property(
 
                 return 1;
 
+        } else if (streq(name, "CoredumpFilter")) {
+                uint64_t f;
+
+                r = sd_bus_message_read(message, "t", &f);
+                if (r < 0)
+                        return r;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->coredump_filter = f;
+                        c->coredump_filter_set = true;
+                        unit_write_settingf(u, flags, name, "CoredumpFilter=0x%"PRIx64, f);
+                }
+
+                return 1;
+
         } else if (streq(name, "EnvironmentFiles")) {
 
                 _cleanup_free_ char *joined = NULL;
index 8e1e77b4b2a5442c741943f978def1495ca85898..c59acad4ce65980f0d67accb108b3794f1836229 100644 (file)
@@ -3323,6 +3323,14 @@ static int exec_child(
                 }
         }
 
+        if (context->coredump_filter_set) {
+                r = set_coredump_filter(context->coredump_filter);
+                if (ERRNO_IS_PRIVILEGE(r))
+                        log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m");
+                else if (r < 0)
+                        return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m");
+        }
+
         if (context->nice_set) {
                 r = setpriority_closest(context->nice);
                 if (r < 0)
@@ -4614,6 +4622,11 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                         "%sOOMScoreAdjust: %i\n",
                         prefix, c->oom_score_adjust);
 
+        if (c->coredump_filter_set)
+                fprintf(f,
+                        "%sCoredumpFilter: 0x%"PRIx64"\n",
+                        prefix, c->coredump_filter);
+
         for (i = 0; i < RLIM_NLIMITS; i++)
                 if (c->rlimit[i]) {
                         fprintf(f, "%sLimit%s: " RLIM_FMT "\n",
index 4baf5b1a405f942d7d00de64ab4a6eedd30b03a5..f96a2915eb75701f084a78ca40e93ab1870497c2 100644 (file)
@@ -14,6 +14,7 @@ typedef struct Manager Manager;
 #include <sys/capability.h>
 
 #include "cgroup-util.h"
+#include "coredump-util.h"
 #include "cpu-set-util.h"
 #include "exec-util.h"
 #include "fdset.h"
@@ -161,6 +162,7 @@ struct ExecContext {
         bool working_directory_home:1;
 
         bool oom_score_adjust_set:1;
+        bool coredump_filter_set:1;
         bool nice_set:1;
         bool ioprio_set:1;
         bool cpu_sched_set:1;
@@ -179,6 +181,7 @@ struct ExecContext {
         int ioprio;
         int cpu_sched_policy;
         int cpu_sched_priority;
+        uint64_t coredump_filter;
 
         CPUSet cpu_set;
         NUMAPolicy numa_policy;
index 69abdb65ba704d018e37e8aa6afc32bf20ac6898..165b9ca9c12c260b67ae98c9d7a2c1ce93f16513 100644 (file)
@@ -28,6 +28,7 @@ $1.Group,                        config_parse_user_group_compat,     0,
 $1.SupplementaryGroups,          config_parse_user_group_strv_compat, 0,                            offsetof($1, exec_context.supplementary_groups)
 $1.Nice,                         config_parse_exec_nice,             0,                             offsetof($1, exec_context)
 $1.OOMScoreAdjust,               config_parse_exec_oom_score_adjust, 0,                             offsetof($1, exec_context)
+$1.CoredumpFilter,               config_parse_exec_coredump_filter,  0,                             offsetof($1, exec_context)
 $1.IOSchedulingClass,            config_parse_exec_io_class,         0,                             offsetof($1, exec_context)
 $1.IOSchedulingPriority,         config_parse_exec_io_priority,      0,                             offsetof($1, exec_context)
 $1.CPUSchedulingPolicy,          config_parse_exec_cpu_sched_policy, 0,                             offsetof($1, exec_context)
index f3fe73535e3d06195055bc7b17cda563dcd4e6f3..b16c62a5c7c62d2adb10623c0759cc6ef6159893 100644 (file)
@@ -592,6 +592,45 @@ int config_parse_exec_oom_score_adjust(
         return 0;
 }
 
+int config_parse_exec_coredump_filter(
+                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 r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                c->coredump_filter = 0;
+                c->coredump_filter_set = false;
+                return 0;
+        }
+
+        uint64_t f;
+        r = coredump_filter_mask_from_string(rvalue, &f);
+        if (r < 0) {
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse the CoredumpFilter=%s, ignoring: %m", rvalue);
+                return 0;
+        }
+
+        c->coredump_filter |= f;
+        c->oom_score_adjust_set = true;
+        return 0;
+}
+
 int config_parse_exec(
                 const char *unit,
                 const char *filename,
index b6b46b2449b118f6cad5876de780871991c1e250..bc72ef77451fe65864170ecace32ac805d599723 100644 (file)
@@ -26,6 +26,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_socket_protocol);
 CONFIG_PARSER_PROTOTYPE(config_parse_socket_bind);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_nice);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_oom_score_adjust);
+CONFIG_PARSER_PROTOTYPE(config_parse_exec_coredump_filter);
 CONFIG_PARSER_PROTOTYPE(config_parse_exec);
 CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout);
 CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout_abort);
index d700b3afc5299d4d6b1f3a81ff5891ad3fe23730..db6521b924d82f09021ea2e95b520bcdf74fa3fa 100644 (file)
@@ -2581,7 +2581,7 @@ int main(int argc, char *argv[]) {
                 if (!skip_setup)
                         kmod_setup();
 
-                r = mount_setup(loaded_policy);
+                r = mount_setup(loaded_policy, skip_setup);
                 if (r < 0) {
                         error_message = "Failed to mount API filesystems";
                         goto finish;
index 284e3f6b077236cd382db530a4308dd5939d9551..ffe3d4cc64127419d14ca53b36b6843a825d9e1e 100644 (file)
@@ -478,7 +478,7 @@ static int relabel_extra(void) {
 }
 #endif
 
-int mount_setup(bool loaded_policy) {
+int mount_setup(bool loaded_policy, bool leave_propagation) {
         int r = 0;
 
         r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy);
@@ -524,7 +524,7 @@ int mount_setup(bool loaded_policy) {
          * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a
          * container manager we assume the container manager knows what it is doing (for example, because it set up
          * some directories with different propagation modes). */
-        if (detect_container() <= 0)
+        if (detect_container() <= 0 && !leave_propagation)
                 if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0)
                         log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m");
 
index b4ca2cf4b45bf28de8bd124d7746ac51e06c73f7..bccd094961152c996d38acbc7111399723eadcbc 100644 (file)
@@ -4,7 +4,7 @@
 #include <stdbool.h>
 
 int mount_setup_early(void);
-int mount_setup(bool loaded_policy);
+int mount_setup(bool loaded_policy, bool leave_propagation);
 
 int mount_cgroup_controllers(void);
 
index 95d574d8d48d32079ed7b3abb3434ab5b4c47c10..ce0b197e6bc553de991b45e67163b2133375f297 100644 (file)
@@ -187,8 +187,16 @@ static void unit_init(Unit *u) {
         if (ec) {
                 exec_context_init(ec);
 
-                ec->keyring_mode = MANAGER_IS_SYSTEM(u->manager) ?
-                        EXEC_KEYRING_SHARED : EXEC_KEYRING_INHERIT;
+                if (MANAGER_IS_SYSTEM(u->manager))
+                        ec->keyring_mode = EXEC_KEYRING_SHARED;
+                else {
+                        ec->keyring_mode = EXEC_KEYRING_INHERIT;
+
+                        /* User manager might have its umask redefined by PAM or UMask=. In this
+                         * case let the units it manages inherit this value by default. They can
+                         * still tune this value through their own unit file */
+                        (void) get_process_umask(getpid_cached(), &ec->umask);
+                }
         }
 
         kc = unit_get_kill_context(u);
index 1e9fe73034b4be6994d984ecdfbc128fc521b558..02645b2bcd79dc291406d8258de2ecab1500ddb8 100644 (file)
@@ -50,6 +50,7 @@ static void lldp_neighbor_free(sd_lldp_neighbor *n) {
         free(n->port_description);
         free(n->system_name);
         free(n->system_description);
+        free(n->mud_url);
         free(n->chassis_id_as_string);
         free(n->port_id_as_string);
         free(n);
@@ -292,9 +293,20 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) {
 
                         break;
 
-                case SD_LLDP_TYPE_PRIVATE:
+                case SD_LLDP_TYPE_PRIVATE: {
                         if (length < 4)
                                 log_lldp("Found private TLV that is too short, ignoring.");
+                        else {
+                                /* RFC 8520: MUD URL */
+                                if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 &&
+                                    p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) {
+                                        r = parse_string(&n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1,
+                                                         length - 1 - sizeof(SD_LLDP_OUI_MUD));
+                                        if (r < 0)
+                                                return r;
+                                }
+                        }
+                }
 
                         break;
                 }
@@ -593,6 +605,17 @@ _public_ int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const ch
         return 0;
 }
 
+_public_ int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret) {
+        assert_return(n, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        if (!n->mud_url)
+                return -ENODATA;
+
+        *ret = n->mud_url;
+        return 0;
+}
+
 _public_ int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret) {
         assert_return(n, -EINVAL);
         assert_return(ret, -EINVAL);
index 62dbff42cad1f89d5ce792c2f559236a39c56171..74175edf545cc9aa4530c845e1ac795e64cbd0d0 100644 (file)
@@ -54,6 +54,7 @@ struct sd_lldp_neighbor {
         char *port_description;
         char *system_name;
         char *system_description;
+        char *mud_url;
 
         uint16_t port_vlan_id;
 
index 51db60e1f2e816a987801c3510187a66bebf827a..1fbf9d0dd9161657cce39dfabcaca3c0e1452e4d 100644 (file)
@@ -6,6 +6,7 @@
 #include <net/if_arp.h>
 
 #include "alloc-util.h"
+#include "escape.h"
 #include "env-file.h"
 #include "fd-util.h"
 #include "hostname-util.h"
@@ -18,6 +19,7 @@
 #include "socket-util.h"
 #include "string-util.h"
 #include "unaligned.h"
+#include "web-util.h"
 
 /* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
 #define LLDP_TX_FAST_INIT 4U
@@ -81,9 +83,11 @@ static int lldp_make_packet(
                 const char *pretty_hostname,
                 uint16_t system_capabilities,
                 uint16_t enabled_capabilities,
+                char *mud,
                 void **ret, size_t *sz) {
 
-        size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, pretty_hostname_length = 0;
+        size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0,
+                pretty_hostname_length = 0, mud_length = 0;
         _cleanup_free_ void *packet = NULL;
         struct ether_header *h;
         uint8_t *p;
@@ -110,6 +114,9 @@ static int lldp_make_packet(
         if (pretty_hostname)
                 pretty_hostname_length = strlen(pretty_hostname);
 
+        if (mud)
+                mud_length = strlen(mud);
+
         l = sizeof(struct ether_header) +
                 /* Chassis ID */
                 2 + 1 + machine_id_length +
@@ -134,6 +141,10 @@ static int lldp_make_packet(
         if (pretty_hostname)
                 l += 2 + pretty_hostname_length;
 
+        /* MUD URL */
+        if (mud)
+                l += 2 + sizeof(SD_LLDP_OUI_MUD) + 1 + mud_length;
+
         packet = malloc(l);
         if (!packet)
                 return -ENOMEM;
@@ -184,6 +195,32 @@ static int lldp_make_packet(
                 p = mempcpy(p, pretty_hostname, pretty_hostname_length);
         }
 
+        if (mud) {
+                uint8_t oui_mud[sizeof(SD_LLDP_OUI_MUD)] = {0x00, 0x00, 0x5E};
+                /*
+                 * +--------+--------+----------+---------+--------------
+                 * |TLV Type|  len   |   OUI    |subtype  | MUDString
+                 * |  =127  |        |= 00 00 5E|  = 1    |
+                 * |(7 bits)|(9 bits)|(3 octets)|(1 octet)|(1-255 octets)
+                 * +--------+--------+----------+---------+--------------
+                 * where:
+
+                 * o  TLV Type = 127 indicates a vendor-specific TLV
+                 * o  len = indicates the TLV string length
+                 * o  OUI = 00 00 5E is the organizationally unique identifier of IANA
+                 * o  subtype = 1 (as assigned by IANA for the MUDstring)
+                 * o  MUDstring = the length MUST NOT exceed 255 octets
+                 */
+
+                r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PRIVATE, sizeof(SD_LLDP_OUI_MUD) + 1 + mud_length);
+                if (r < 0)
+                        return r;
+
+                p = mempcpy(p, &oui_mud, sizeof(SD_LLDP_OUI_MUD));
+                *(p++) = SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION;
+                p = mempcpy(p, mud, mud_length);
+        }
+
         r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4);
         if (r < 0)
                 return r;
@@ -281,6 +318,7 @@ static int link_send_lldp(Link *link) {
                              pretty_hostname,
                              SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
                              caps,
+                             link->network ? link->network->lldp_mud : NULL,
                              &packet, &packet_size);
         if (r < 0)
                 return r;
@@ -414,3 +452,40 @@ int config_parse_lldp_emit(
 
         return 0;
 }
+
+int config_parse_lldp_mud(
+                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) {
+
+        _cleanup_free_ char *unescaped = NULL;
+        Network *n = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+
+        r = cunescape(rvalue, 0, &unescaped);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r,
+                           "Failed to Failed to unescape LLDP MUD URL, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) {
+                log_syntax(unit, LOG_ERR, filename, line, 0,
+                           "Failed to parse LLDP MUD URL '%s', ignoring: %m", rvalue);
+
+                return 0;
+        }
+
+        return free_and_replace(n->lldp_mud, unescaped);
+}
index 561becda41c84fec4d967165e0fe181009e9c637..1409984ac02fda3f0bcf80897694f3089a727ccf 100644 (file)
@@ -20,3 +20,4 @@ int link_lldp_emit_start(Link *link);
 void link_lldp_emit_stop(Link *link);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_lldp_emit);
+CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mud);
index fe6adc4089a298cd0d924719427801ff95b91953..c63f57f96249761677f4063acc4ad200e64c2e54 100644 (file)
@@ -259,6 +259,7 @@ IPv6Prefix.PreferredLifetimeSec,             config_parse_prefix_lifetime,
 IPv6Prefix.Assign,                           config_parse_prefix_assign,                               0,                             0
 IPv6RoutePrefix.Route,                       config_parse_route_prefix,                                0,                             0
 IPv6RoutePrefix.LifetimeSec,                 config_parse_route_prefix_lifetime,                       0,                             0
+LLDP.MUDURL,                                 config_parse_lldp_mud,                                    0,                             0
 CAN.BitRate,                                 config_parse_can_bitrate,                                 0,                             offsetof(Network, can_bitrate)
 CAN.SamplePoint,                             config_parse_permille,                                    0,                             offsetof(Network, can_sample_point)
 CAN.DataBitRate,                             config_parse_can_bitrate,                                 0,                             offsetof(Network, can_data_bitrate)
index f46b91e724392a1395e0167482cfe04c076aae42..9edf9e15616d7c93db39cbebeb6db160b2fc0070 100644 (file)
@@ -485,6 +485,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                               "IPv6PrefixDelegation\0"
                               "IPv6Prefix\0"
                               "IPv6RoutePrefix\0"
+                              "LLDP\0"
                               "TrafficControlQueueingDiscipline\0"
                               "CAN\0"
                               "QDisc\0"
@@ -726,6 +727,8 @@ static Network *network_free(Network *network) {
 
         set_free_free(network->dnssec_negative_trust_anchors);
 
+        free(network->lldp_mud);
+
         ordered_hashmap_free(network->dhcp_client_send_options);
         ordered_hashmap_free(network->dhcp_client_send_vendor_options);
         ordered_hashmap_free(network->dhcp_server_send_options);
index e6182327e103398984958d8f3522f14f3f025715..1c600ae7bd81bd5e98bea95bca5f88e931bb8c16 100644 (file)
@@ -258,8 +258,10 @@ struct Network {
         bool required_for_online; /* Is this network required to be considered online? */
         LinkOperationalStateRange required_operstate_for_online;
 
+        /* LLDP support */
         LLDPMode lldp_mode; /* LLDP reception */
         LLDPEmit lldp_emit; /* LLDP transmission */
+        char *lldp_mud;    /* LLDP MUD URL */
 
         LIST_HEAD(Address, static_addresses);
         LIST_HEAD(Route, static_routes);
index 2b806fb6ac4fc7c6364885a86ccbf3087a9de41b..6076eabe92e2db614ae525b539876e3da6d6b3f9 100644 (file)
@@ -41,6 +41,7 @@ static bool arg_wait = false;
 static const char *arg_unit = NULL;
 static const char *arg_description = NULL;
 static const char *arg_slice = NULL;
+static bool arg_slice_inherit = false;
 static bool arg_send_sighup = false;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 static const char *arg_host = NULL;
@@ -97,6 +98,7 @@ static int help(void) {
                "  -p --property=NAME=VALUE        Set service or scope unit property\n"
                "     --description=TEXT           Description for unit\n"
                "     --slice=SLICE                Run in the specified slice\n"
+               "     --slice-inherit              Inherit the slice\n"
                "     --no-block                   Do not wait until operation finished\n"
                "  -r --remain-after-exit          Leave service around until explicitly stopped\n"
                "     --wait                       Wait until service stopped again\n"
@@ -162,6 +164,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_SCOPE,
                 ARG_DESCRIPTION,
                 ARG_SLICE,
+                ARG_SLICE_INHERIT,
                 ARG_SEND_SIGHUP,
                 ARG_SERVICE_TYPE,
                 ARG_EXEC_USER,
@@ -194,6 +197,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "unit",              required_argument, NULL, 'u'                   },
                 { "description",       required_argument, NULL, ARG_DESCRIPTION       },
                 { "slice",             required_argument, NULL, ARG_SLICE             },
+                { "slice-inherit",     no_argument,       NULL, ARG_SLICE_INHERIT     },
                 { "remain-after-exit", no_argument,       NULL, 'r'                   },
                 { "send-sighup",       no_argument,       NULL, ARG_SEND_SIGHUP       },
                 { "host",              required_argument, NULL, 'H'                   },
@@ -273,6 +277,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_slice = optarg;
                         break;
 
+                case ARG_SLICE_INHERIT:
+                        arg_slice_inherit = true;
+                        break;
+
                 case ARG_SEND_SIGHUP:
                         arg_send_sighup = true;
                         break;
@@ -637,23 +645,50 @@ static int transient_unit_set_properties(sd_bus_message *m, UnitType t, char **p
 }
 
 static int transient_cgroup_set_properties(sd_bus_message *m) {
+        _cleanup_free_ char *name = NULL;
+        _cleanup_free_ char *slice = NULL;
         int r;
         assert(m);
 
-        if (!isempty(arg_slice)) {
-                _cleanup_free_ char *slice = NULL;
+        if (arg_slice_inherit) {
+                char *end;
 
-                r = unit_name_mangle_with_suffix(arg_slice, "as slice",
-                                                 arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
-                                                 ".slice", &slice);
+                if (arg_user)
+                        r = cg_pid_get_user_slice(0, &name);
+                else
+                        r = cg_pid_get_slice(0, &name);
                 if (r < 0)
-                        return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice);
+                        return log_error_errno(r, "Failed to get PID slice: %m");
 
-                r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
-                if (r < 0)
-                        return bus_log_create_error(r);
+                end = endswith(name, ".slice");
+                if (!end)
+                        return -ENXIO;
+                *end = 0;
         }
 
+        if (!isempty(arg_slice)) {
+                if (name) {
+                        char *j = strjoin(name, "-", arg_slice);
+                        free_and_replace(name, j);
+                } else
+                        name = strdup(arg_slice);
+                if (!name)
+                        return log_oom();
+        }
+
+        if (!name)
+                return 0;
+
+        r = unit_name_mangle_with_suffix(name, "as slice",
+                                         arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN,
+                                         ".slice", &slice);
+        if (r < 0)
+                return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice);
+
+        r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         return 0;
 }
 
index a30876c1a13f672dedc943c7923b11c2c9570e95..463a0ddb716086bb83eff8d235c127b33f7fb6f9 100644 (file)
@@ -8,6 +8,7 @@
 #include "cgroup-setup.h"
 #include "cgroup-util.h"
 #include "condition.h"
+#include "coredump-util.h"
 #include "cpu-set-util.h"
 #include "escape.h"
 #include "exec-util.h"
@@ -119,6 +120,7 @@ DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64);
 DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode);
 DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou);
 DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, coredump_filter_mask_from_string);
 
 static int bus_append_string(sd_bus_message *m, const char *field, const char *eq) {
         int r;
@@ -898,6 +900,9 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                               "OOMScoreAdjust"))
                 return bus_append_safe_atoi(m, field, eq);
 
+        if (streq(field, "CoredumpFilter"))
+                return bus_append_coredump_filter_mask_from_string(m, field, eq);
+
         if (streq(field, "Nice"))
                 return bus_append_parse_nice(m, field, eq);
 
index 4b0a3a3e317e23863a37dbdcbf67309b8291f96a..d107a06ce3413b17b8ab2cfe6a9f5427b46069c4 100644 (file)
@@ -21,6 +21,7 @@
 #include "bus-util.h"
 #include "cap-list.h"
 #include "cgroup-util.h"
+#include "escape.h"
 #include "mountpoint-util.h"
 #include "nsflags.h"
 #include "parse-util.h"
@@ -373,6 +374,12 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
                         (void) format_timespan(timespan, sizeof(timespan), u, 0);
                         bus_print_property_value(name, expected_value, value, timespan);
 
+                } else if (streq(name, "CoredumpFilter")) {
+                        char buf[STRLEN("0xFFFFFFFF")];
+
+                        xsprintf(buf, "0x%"PRIx64, u);
+                        bus_print_property_value(name, expected_value, value, buf);
+
                 } else if (streq(name, "RestrictNamespaces")) {
                         _cleanup_free_ char *s = NULL;
                         const char *result;
@@ -500,18 +507,20 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b
                                 return r;
 
                         while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) {
-                                bool good;
+                                _cleanup_free_ char *e = NULL;
 
-                                if (first && !value)
-                                        printf("%s=", name);
+                                e = shell_maybe_quote(str, ESCAPE_BACKSLASH_ONELINE);
+                                if (!e)
+                                        return -ENOMEM;
 
-                                /* This property has multiple space-separated values, so
-                                 * neither spaces nor newlines can be allowed in a value. */
-                                good = str[strcspn(str, " \n")] == '\0';
+                                if (first) {
+                                        if (!value)
+                                                printf("%s=", name);
+                                        first = false;
+                                } else
+                                        fputs(" ", stdout);
 
-                                printf("%s%s", first ? "" : " ", good ? str : "[unprintable]");
-
-                                first = false;
+                                fputs(e, stdout);
                         }
                         if (r < 0)
                                 return r;
@@ -1390,3 +1399,142 @@ const struct hash_ops bus_message_hash_ops = {
         .compare = trivial_compare_func,
         .free_value = bus_message_unref_wrapper,
 };
+
+/* Shorthand flavors of the sd-bus convenience helpers with destination,path,interface
+ * strings encapsulated within a single struct.
+ */
+int bus_call_method_async(
+                sd_bus *bus,
+                sd_bus_slot **slot,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_message_handler_t callback,
+                void *userdata,
+                const char *types, ...) {
+
+        va_list ap;
+        int r;
+
+        assert(address);
+
+        va_start(ap, types);
+        r = sd_bus_call_method_asyncv(bus, slot, address->destination, address->path, address->interface, member, callback, userdata, types, ap);
+        va_end(ap);
+
+        return r;
+}
+
+int bus_call_method(
+                sd_bus *bus,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_error *error,
+                sd_bus_message **reply,
+                const char *types, ...) {
+
+        va_list ap;
+        int r;
+
+        assert(address);
+
+        va_start(ap, types);
+        r = sd_bus_call_methodv(bus, address->destination, address->path, address->interface, member, error, reply, types, ap);
+        va_end(ap);
+
+        return r;
+}
+
+int bus_get_property(
+                sd_bus *bus,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_error *error,
+                sd_bus_message **reply,
+                const char *type) {
+
+        assert(address);
+
+        return sd_bus_get_property(bus, address->destination, address->path, address->interface, member, error, reply, type);
+}
+
+int bus_get_property_trivial(
+                sd_bus *bus,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_error *error,
+                char type, void *ptr) {
+
+        assert(address);
+
+        return sd_bus_get_property_trivial(bus, address->destination, address->path, address->interface, member, error, type, ptr);
+}
+
+int bus_get_property_string(
+                sd_bus *bus,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_error *error,
+                char **ret) {
+
+        assert(address);
+
+        return sd_bus_get_property_string(bus, address->destination, address->path, address->interface, member, error, ret);
+}
+
+int bus_get_property_strv(
+                sd_bus *bus,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_error *error,
+                char ***ret) {
+
+        assert(address);
+
+        return sd_bus_get_property_strv(bus, address->destination, address->path, address->interface, member, error, ret);
+}
+
+int bus_set_property(
+                sd_bus *bus,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_error *error,
+                const char *type, ...) {
+
+        va_list ap;
+        int r;
+
+        assert(address);
+
+        va_start(ap, type);
+        r = sd_bus_set_propertyv(bus, address->destination, address->path, address->interface, member, error, type, ap);
+        va_end(ap);
+
+        return r;
+}
+
+int bus_match_signal(
+                sd_bus *bus,
+                sd_bus_slot **ret,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_message_handler_t callback,
+                void *userdata) {
+
+        assert(address);
+
+        return sd_bus_match_signal(bus, ret, address->destination, address->path, address->interface, member, callback, userdata);
+}
+
+int bus_match_signal_async(
+                sd_bus *bus,
+                sd_bus_slot **ret,
+                const BusAddress *address,
+                const char *member,
+                sd_bus_message_handler_t callback,
+                sd_bus_message_handler_t install_callback,
+                void *userdata) {
+
+        assert(address);
+
+        return sd_bus_match_signal_async(bus, ret, address->destination, address->path, address->interface, member, callback, install_callback, userdata);
+}
index db245a791ea4fa4c21450e0394f41993e5f38dde..f3bdde41aea9917b3880e72a8ad81d83d20d5f0b 100644 (file)
@@ -22,6 +22,12 @@ typedef enum BusTransport {
         _BUS_TRANSPORT_INVALID = -1
 } BusTransport;
 
+typedef struct BusAddress {
+        const char    *destination;
+        const char    *path;
+        const char    *interface;
+} BusAddress;
+
 typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata);
 
 struct bus_properties_map {
@@ -179,3 +185,16 @@ static inline int bus_open_system_watch_bind(sd_bus **ret) {
 int bus_reply_pair_array(sd_bus_message *m, char **l);
 
 extern const struct hash_ops bus_message_hash_ops;
+
+/* Shorthand flavors of the sd-bus convenience helpers with destination,path,interface
+ * strings encapsulated within a single struct.
+ */
+int bus_call_method_async(sd_bus *bus, sd_bus_slot **slot, const BusAddress *address, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...);
+int bus_call_method(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *types, ...);
+int bus_get_property(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *type);
+int bus_get_property_trivial(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, char type, void *ptr);
+int bus_get_property_string(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, char **ret);
+int bus_get_property_strv(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, char ***ret);
+int bus_set_property(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, const char *type, ...);
+int bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const BusAddress *address, const char *member, sd_bus_message_handler_t callback, void *userdata);
+int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusAddress *address, const char *member, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata);
diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c
new file mode 100644 (file)
index 0000000..6789741
--- /dev/null
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "coredump-util.h"
+#include "extract-word.h"
+#include "fileio.h"
+#include "string-table.h"
+
+static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = {
+        [COREDUMP_FILTER_PRIVATE_ANONYMOUS]   = "private-anonymous",
+        [COREDUMP_FILTER_SHARED_ANONYMOUS]    = "shared-anonymous",
+        [COREDUMP_FILTER_PRIVATE_FILE_BACKED] = "private-file-backed",
+        [COREDUMP_FILTER_SHARED_FILE_BACKED]  = "shared-file-backed",
+        [COREDUMP_FILTER_ELF_HEADERS]         = "elf-headers",
+        [COREDUMP_FILTER_PRIVATE_HUGE]        = "private-huge",
+        [COREDUMP_FILTER_SHARED_HUGE]         = "shared-huge",
+        [COREDUMP_FILTER_PRIVATE_DAX]         = "private-dax",
+        [COREDUMP_FILTER_SHARED_DAX]          = "shared-dax",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(coredump_filter, CoredumpFilter);
+
+int coredump_filter_mask_from_string(const char *s, uint64_t *ret) {
+        uint64_t m = 0;
+
+        assert(s);
+        assert(ret);
+
+        for (;;) {
+                _cleanup_free_ char *n = NULL;
+                CoredumpFilter v;
+                int r;
+
+                r = extract_first_word(&s, &n, NULL, 0);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                if (streq(n, "default")) {
+                        m |= COREDUMP_FILTER_MASK_DEFAULT;
+                        continue;
+                }
+
+                if (streq(n, "all")) {
+                        m = UINT64_MAX;
+                        continue;
+                }
+
+                v = coredump_filter_from_string(n);
+                if (v >= 0) {
+                        m |= 1u << v;
+                        continue;
+                }
+
+                uint64_t x;
+                r = safe_atoux64(n, &x);
+                if (r < 0)
+                        return r;
+
+                m |= x;
+        }
+
+        *ret = m;
+        return 0;
+}
+
+int set_coredump_filter(uint64_t value) {
+        char t[STRLEN("0xFFFFFFFF")];
+
+        sprintf(t, "0x%"PRIx64, value);
+
+        return write_string_file("/proc/self/coredump_filter", t,
+                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
+}
diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h
new file mode 100644 (file)
index 0000000..ff2e511
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "macro.h"
+
+typedef enum CoredumpFilter {
+        COREDUMP_FILTER_PRIVATE_ANONYMOUS = 0,
+        COREDUMP_FILTER_SHARED_ANONYMOUS,
+        COREDUMP_FILTER_PRIVATE_FILE_BACKED,
+        COREDUMP_FILTER_SHARED_FILE_BACKED,
+        COREDUMP_FILTER_ELF_HEADERS,
+        COREDUMP_FILTER_PRIVATE_HUGE,
+        COREDUMP_FILTER_SHARED_HUGE,
+        COREDUMP_FILTER_PRIVATE_DAX,
+        COREDUMP_FILTER_SHARED_DAX,
+        _COREDUMP_FILTER_MAX,
+        _COREDUMP_FILTER_INVALID = -1,
+} CoredumpFilter;
+
+#define COREDUMP_FILTER_MASK_DEFAULT (1u << COREDUMP_FILTER_PRIVATE_ANONYMOUS | \
+                                      1u << COREDUMP_FILTER_SHARED_ANONYMOUS | \
+                                      1u << COREDUMP_FILTER_ELF_HEADERS | \
+                                      1u << COREDUMP_FILTER_PRIVATE_HUGE)
+
+const char* coredump_filter_to_string(CoredumpFilter i) _const_;
+CoredumpFilter coredump_filter_from_string(const char *s) _pure_;
+int coredump_filter_mask_from_string(const char *s, uint64_t *ret);
+
+int set_coredump_filter(uint64_t value);
index 45a723f3633256e20cb55f2b76a3e05bdcd9243c..d1832a1f53f2774e88ef3fcbe0580e33ff9c1292 100644 (file)
@@ -51,6 +51,8 @@ shared_sources = files('''
         condition.h
         conf-parser.c
         conf-parser.h
+        coredump-util.c
+        coredump-util.h
         cpu-set-util.c
         cpu-set-util.h
         crypt-util.c
index e63ef0f261b08752bfbeadf087146224b3415f86..6dbdff7b28155c0320e6faacb79750dd0c0c86fb 100644 (file)
@@ -223,7 +223,7 @@ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offse
 
         fd = open(swap->device, O_RDONLY|O_CLOEXEC|O_NOCTTY);
         if (fd < 0)
-                return log_error_errno(errno, "Failed to open %s: %m", swap->device);
+                return log_error_errno(errno, "Failed to open swap file %s to determine on-disk offset: %m", swap->device);
 
         if (fstat(fd, &sb) < 0)
                 return log_error_errno(errno, "Failed to stat %s: %m", swap->device);
index bf3afadcec54e1c237f647f0d8b424d33d02c256..2dc9f6324623d1d51ebf29c315e967aa751105b3 100644 (file)
@@ -96,6 +96,9 @@ enum {
 #define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 }
 #define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f }
 
+#define SD_LLDP_OUI_MUD   (uint8_t[]) { 0x00, 0x00, 0x5E }
+#define SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION  0x01
+
 /* IEEE 802.1AB-2009 Annex E */
 enum {
         SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID          = 1,
@@ -169,6 +172,7 @@ int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec);
 int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret);
 int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret);
 int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret);
+int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret);
 int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
 int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
 
index 6297875c0d9b96563b1a650f29c95fc407217d9c..a674d6cfe9313c13ac319535bb6e304fe1a4bafb 100644 (file)
@@ -588,6 +588,10 @@ tests += [
          [],
          []],
 
+        [['src/test/test-coredump-util.c'],
+         [],
+         []],
+
         [['src/test/test-daemon.c'],
          [],
          []],
diff --git a/src/test/test-coredump-util.c b/src/test/test-coredump-util.c
new file mode 100644 (file)
index 0000000..14a7800
--- /dev/null
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "alloc-util.h"
+#include "coredump-util.h"
+#include "macro.h"
+#include "tests.h"
+
+static void test_coredump_filter_to_from_string(void) {
+        log_info("/* %s */", __func__);
+
+        for (CoredumpFilter i = 0; i < _COREDUMP_FILTER_MAX; i++) {
+                const char *n;
+
+                assert_se(n = coredump_filter_to_string(i));
+                log_info("0x%x\t%s", 1<<i, n);
+                assert_se(coredump_filter_from_string(n) == i);
+
+                uint64_t f;
+                assert_se(coredump_filter_mask_from_string(n, &f) == 0);
+                assert_se(f == 1u << i);
+        }
+}
+
+static void test_coredump_filter_mask_from_string(void) {
+        log_info("/* %s */", __func__);
+
+        uint64_t f;
+        assert_se(coredump_filter_mask_from_string("default", &f) == 0);
+        assert_se(f == COREDUMP_FILTER_MASK_DEFAULT);
+
+        assert_se(coredump_filter_mask_from_string("  default\tdefault\tdefault  ", &f) == 0);
+        assert_se(f == COREDUMP_FILTER_MASK_DEFAULT);
+
+        assert_se(coredump_filter_mask_from_string("defaulta", &f) < 0);
+        assert_se(coredump_filter_mask_from_string("default defaulta default", &f) < 0);
+        assert_se(coredump_filter_mask_from_string("default default defaulta", &f) < 0);
+
+        assert_se(coredump_filter_mask_from_string("private-anonymous default", &f) == 0);
+        assert_se(f == COREDUMP_FILTER_MASK_DEFAULT);
+
+        assert_se(coredump_filter_mask_from_string("shared-file-backed shared-dax", &f) == 0);
+        assert_se(f == (1 << COREDUMP_FILTER_SHARED_FILE_BACKED |
+                        1 << COREDUMP_FILTER_SHARED_DAX));
+
+        assert_se(coredump_filter_mask_from_string("private-file-backed private-dax 0xF", &f) == 0);
+        assert_se(f == (1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED |
+                        1 << COREDUMP_FILTER_PRIVATE_DAX |
+                        0xF));
+
+        assert_se(coredump_filter_mask_from_string("11", &f) == 0);
+        assert_se(f == 0x11);
+
+        assert_se(coredump_filter_mask_from_string("0x1101", &f) == 0);
+        assert_se(f == 0x1101);
+
+        assert_se(coredump_filter_mask_from_string("0", &f) == 0);
+        assert_se(f == 0);
+
+        assert_se(coredump_filter_mask_from_string("all", &f) == 0);
+        assert_se(FLAGS_SET(f, (1 << COREDUMP_FILTER_PRIVATE_ANONYMOUS |
+                                1 << COREDUMP_FILTER_SHARED_ANONYMOUS |
+                                1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED |
+                                1 << COREDUMP_FILTER_SHARED_FILE_BACKED |
+                                1 << COREDUMP_FILTER_ELF_HEADERS |
+                                1 << COREDUMP_FILTER_PRIVATE_HUGE |
+                                1 << COREDUMP_FILTER_SHARED_HUGE |
+                                1 << COREDUMP_FILTER_PRIVATE_DAX |
+                                1 << COREDUMP_FILTER_SHARED_DAX)));
+}
+
+int main(int argc, char **argv) {
+        test_setup_logging(LOG_INFO);
+
+        test_coredump_filter_to_from_string();
+        test_coredump_filter_mask_from_string();
+
+        return 0;
+}
index f6aae1eb1828d8432648cd043a1f036bc73127c6..699747fcc3cae4945d6c5b7b97d34cd650d4f345 100644 (file)
@@ -142,31 +142,42 @@ static void test_shell_maybe_quote_one(const char *s,
 static void test_shell_maybe_quote(void) {
 
         test_shell_maybe_quote_one("", ESCAPE_BACKSLASH, "");
+        test_shell_maybe_quote_one("", ESCAPE_BACKSLASH_ONELINE, "");
         test_shell_maybe_quote_one("", ESCAPE_POSIX, "");
         test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH, "\"\\\\\"");
+        test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH_ONELINE, "\"\\\\\"");
         test_shell_maybe_quote_one("\\", ESCAPE_POSIX, "$'\\\\'");
         test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH, "\"\\\"\"");
+        test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH_ONELINE, "\"\\\"\"");
         test_shell_maybe_quote_one("\"", ESCAPE_POSIX, "$'\"'");
         test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH, "foobar");
+        test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH_ONELINE, "foobar");
         test_shell_maybe_quote_one("foobar", ESCAPE_POSIX, "foobar");
         test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH, "\"foo bar\"");
+        test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH_ONELINE, "\"foo bar\"");
         test_shell_maybe_quote_one("foo bar", ESCAPE_POSIX, "$'foo bar'");
         test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH, "\"foo\tbar\"");
+        test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH_ONELINE, "\"foo\\tbar\"");
         test_shell_maybe_quote_one("foo\tbar", ESCAPE_POSIX, "$'foo\\tbar'");
         test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH, "\"foo\nbar\"");
+        test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH_ONELINE, "\"foo\\nbar\"");
         test_shell_maybe_quote_one("foo\nbar", ESCAPE_POSIX, "$'foo\\nbar'");
         test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH, "\"foo \\\"bar\\\" waldo\"");
+        test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH_ONELINE, "\"foo \\\"bar\\\" waldo\"");
         test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_POSIX, "$'foo \"bar\" waldo'");
         test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH, "\"foo\\$bar\"");
+        test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH_ONELINE, "\"foo\\$bar\"");
         test_shell_maybe_quote_one("foo$bar", ESCAPE_POSIX, "$'foo$bar'");
 
         /* Note that current users disallow control characters, so this "test"
          * is here merely to establish current behaviour. If control characters
          * were allowed, they should be quoted, i.e. \001 should become \\001. */
         test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH, "\"a\nb\001\"");
+        test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH_ONELINE, "\"a\\nb\001\"");
         test_shell_maybe_quote_one("a\nb\001", ESCAPE_POSIX, "$'a\\nb\001'");
 
         test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH, "\"foo!bar\"");
+        test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH_ONELINE, "\"foo!bar\"");
         test_shell_maybe_quote_one("foo!bar", ESCAPE_POSIX, "$'foo!bar'");
 }
 
index d732f402f0b9091769cc3a3666b0ea442f433c92..1627bc747d5c07077653aa6a840eed10b72e1dc9 100644 (file)
@@ -561,6 +561,44 @@ static void test_safe_atoi64(void) {
         assert_se(r == -EINVAL);
 }
 
+static void test_safe_atoux64(void) {
+        int r;
+        uint64_t l;
+
+        r = safe_atoux64("12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 0x12345);
+
+        r = safe_atoux64("  12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 0x12345);
+
+        r = safe_atoux64("0x12345", &l);
+        assert_se(r == 0);
+        assert_se(l == 0x12345);
+
+        r = safe_atoux64("18446744073709551617", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoux64("-1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoux64("  -1", &l);
+        assert_se(r == -ERANGE);
+
+        r = safe_atoux64("junk", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoux64("123x", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoux64("12.3", &l);
+        assert_se(r == -EINVAL);
+
+        r = safe_atoux64("", &l);
+        assert_se(r == -EINVAL);
+}
+
 static void test_safe_atod(void) {
         int r;
         double d;
@@ -838,6 +876,7 @@ int main(int argc, char *argv[]) {
         test_safe_atoux16();
         test_safe_atou64();
         test_safe_atoi64();
+        test_safe_atoux64();
         test_safe_atod();
         test_parse_percent();
         test_parse_percent_unbounded();
index 0e563f54970b8e5734d8d4eae4b703a1bd7bd553..52e651faefe4a5f9e3c11618d8eafb45b014c2ed 100644 (file)
@@ -88,7 +88,7 @@ static void test_colors(void) {
         test_one_color("green", ansi_green());
         test_one_color("yellow", ansi_yellow());
         test_one_color("blue", ansi_blue());
-        test_one_color("megenta", ansi_magenta());
+        test_one_color("magenta", ansi_magenta());
         test_one_color("grey", ansi_grey());
         test_one_color("highlight-red", ansi_highlight_red());
         test_one_color("highlight-green", ansi_highlight_green());
index 672c2a96652cff810b2418c4154af2d2b12c506c..147ea1b63945b76d1e7f728bbb1ffe7cff6799ef 100644 (file)
@@ -199,6 +199,8 @@ LifetimeSec=
 EgressUntagged=
 VLAN=
 PVID=
+[LLDP]
+MUDURL=
 [CAN]
 SamplePoint=
 BitRate=
index 45f8751971b9b199ced97758b187936a4284b5b7..98cddad3494addaaa333ee33d364c32894820309 100644 (file)
@@ -44,6 +44,7 @@ BlockIOWeight=
 BlockIOWriteBandwidth=
 Broadcast=
 BusName=
+CoredumpFilter=
 CPUAccounting=
 CPUQuota=
 CPUShares=