]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #14494 from poettering/container-interface
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 8 Jan 2020 08:58:57 +0000 (09:58 +0100)
committerGitHub <noreply@github.com>
Wed, 8 Jan 2020 08:58:57 +0000 (09:58 +0100)
Let's import the container interface description text from the fdo wiki

39 files changed:
man/systemd-networkd-wait-online.service.xml
man/systemd.net-naming-scheme.xml
man/systemd.network.xml
meson.build
meson_options.txt
shell-completion/zsh/_systemctl.in
src/basic/locale-util.c
src/basic/locale-util.h
src/basic/virt.c
src/boot/efi/boot.c
src/gpt-auto-generator/gpt-auto-generator.c
src/libsystemd/sd-netlink/netlink-util.c
src/libsystemd/sd-netlink/netlink-util.h
src/libsystemd/sd-netlink/rtnl-message.c
src/login/71-seat.rules.in
src/network/meson.build
src/network/networkd-dhcp4.c
src/network/networkd-link.c
src/network/networkd-manager.c
src/network/networkd-ndisc.c
src/network/networkd-route.c
src/network/networkd-route.h
src/nspawn/nspawn-mount.c
src/nspawn/nspawn-mount.h
src/nspawn/nspawn-network.c
src/nspawn/nspawn.c
src/shared/pkcs11-util.c
src/test/test-locale-util.c
src/udev/udev-builtin-net_id.c
src/udev/udev-rules.c
test/TEST-43-PRIVATEUSER-UNPRIV/test.sh
test/TEST-43-PRIVATEUSER-UNPRIV/testsuite.sh
test/test-network/conf/dhcp-client-gateway-ipv4.network [new file with mode: 0644]
test/test-network/conf/dhcp-client-gateway-ipv6.network [new file with mode: 0644]
test/test-network/systemd-networkd-tests.py
units/meson.build
units/modprobe@.service [new file with mode: 0644]
units/systemd-logind.service.in
units/systemd-nspawn@.service.in

index 51b865dc0b1ecf9da350c4cfb9af8c0b6ed51864..96fcb5fb48e3c58b125549a23ddf58f4f2b7793d 100644 (file)
@@ -97,7 +97,7 @@
       </varlistentry>
 
       <varlistentry>
-        <term><option>--timeout=</option> <replaceable>SECS</replaceable></term>
+        <term><option>--timeout=</option><replaceable>SECS</replaceable></term>
 
         <listitem><para>Fail the service if the network is not online
         by the time the timeout elapses. A timeout of 0 disables the
index 126be320f670e05ab6db83664e46073c5959c910..70b4b27d7b3a6d70e579a83e0bfb61a592a136d6 100644 (file)
@@ -99,8 +99,8 @@
         <varlistentry>
           <term><varname>ID_NET_NAME_ONBOARD=<replaceable>prefix</replaceable><constant>o</constant><replaceable>number</replaceable></varname></term>
 
-          <listitem><para>This name is set based on the ordering information given by the firmware for
-          on-board devices. The name consists of the prefix, letter <constant>o</constant>, and a number
+          <listitem><para>This name is set based on the numeric ordering information given by the firmware
+          for on-board devices. The name consists of the prefix, letter <constant>o</constant>, and a number
           specified by the firmware. This is only available for PCI devices.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
           <term><varname>ID_NET_LABEL_ONBOARD=<replaceable>prefix</replaceable> <replaceable>label</replaceable></varname></term>
 
-          <listitem><para>This property is set based on label given by the firmware for on-board devices. The
-          name consists of the prefix concatenated with the label. This is only available for PCI devices.
+          <listitem><para>This property is set based on textual label given by the firmware for on-board
+          devices. The name consists of the prefix concatenated with the label. This is only available for
+          PCI devices.
           </para>
           </listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]</varname></term>
+          <term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable><constant>v</constant><replaceable>slot</replaceable></varname></term>
           <term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>b</constant><replaceable>number</replaceable></varname></term>
           <term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>u</constant><replaceable>port</replaceable>…[<constant>c</constant><replaceable>config</replaceable>][<constant>i</constant><replaceable>interface</replaceable>]</varname></term>
           <term><varname>ID_NET_NAME_SLOT=<replaceable>prefix</replaceable>[<constant>P</constant><replaceable>domain</replaceable>]<constant>s</constant><replaceable>slot</replaceable>[<constant>f</constant><replaceable>function</replaceable>][<constant>n</constant><replaceable>port_name</replaceable>|<constant>d</constant><replaceable>dev_port</replaceable>]<constant>v</constant><replaceable>slot</replaceable></varname></term>
 
           <listitem><para>This property describes the slot position. Different schemes are used depending on
-          the bus type, as described in the table below. In all cases, PCI slot information must be known. In
-          case of USB, BCMA, and SR-VIO devices, the full name consists of the prefix, PCI slot identifier,
-          and USB or BCMA or SR-VIO slot identifier. The first two parts are denoted as "…" in the table
-          below.</para>
+          the bus type, as described in the table below. In case of USB, BCMA, and SR-VIO devices, the full
+          name consists of the prefix, PCI slot identifier, and USB or BCMA or SR-VIO slot identifier. The
+          first two parts are denoted as "…" in the table below.</para>
 
           <table>
             <title>Slot naming schemes</title>
                   <entry>PCI slot number</entry>
                 </row>
 
+                <row>
+                  <entry><replaceable>prefix</replaceable> <constant>v</constant><replaceable>slot</replaceable></entry>
+                  <entry>VIO slot number (IBM PowerVM)</entry>
+                </row>
+
                 <row>
                   <entry>… <constant>b</constant><replaceable>number</replaceable></entry>
                   <entry>Broadcom bus (BCMA) core number</entry>
           <para>For USB devices the full chain of port numbers of hubs is composed. If the name gets longer
           than the maximum number of 15 characters, the name is not exported. The usual USB configuration
           number 1 and interface number 0 values are suppressed.</para>
-          </listitem>
 
           <para>SR-IOV virtual devices are named based on the name of the parent interface, with a suffix of
           <constant>v</constant> and the virtual device number, with any leading zeros removed. The bus
-          number is ignored. This device type is found in IBM PowerVMs.</para>
+          number is ignored.</para>
+          </listitem>
         </varlistentry>
 
         <varlistentry>
index 4cd25201737f2638c38c9cdb12017f6ae376422f..4299583fe7e1810a69c663afe0572394fda2e1c8 100644 (file)
         <varlistentry>
           <term><varname>Gateway=</varname></term>
           <listitem>
-            <para>As in the <literal>[Network]</literal> section.</para>
+            <para>Takes the gateway address or special value <literal>dhcp</literal>. If
+            <literal>dhcp</literal>, then the gateway address provided by DHCP (or in the IPv6 case,
+            provided by IPv6 RA) is used.</para>
           </listitem>
         </varlistentry>
          <varlistentry>
index 004f01521cb5ee8c183f20f09ed709d9ddc21a58..3b3786bbdb512942ab416754f465a63a844decda 100644 (file)
@@ -2762,7 +2762,7 @@ if conf.get('ENABLE_NETWORKD') == 1
                    link_with : [libnetworkd_core,
                                 libsystemd_network,
                                 libudev_static,
-                                libshared],
+                                networkd_link_with],
                    dependencies : [threads],
                    install_rpath : rootlibexecdir,
                    install : true,
@@ -2772,7 +2772,7 @@ if conf.get('ENABLE_NETWORKD') == 1
                    systemd_networkd_wait_online_sources,
                    include_directories : includes,
                    link_with : [libnetworkd_core,
-                                libshared],
+                                networkd_link_with],
                    install_rpath : rootlibexecdir,
                    install : true,
                    install_dir : rootlibexecdir)
@@ -2781,7 +2781,7 @@ if conf.get('ENABLE_NETWORKD') == 1
                    networkctl_sources,
                    include_directories : includes,
                    link_with : [libsystemd_network,
-                              libshared],
+                              networkd_link_with],
                    install_rpath : rootlibexecdir,
                    install : true,
                    install_dir : rootbindir)
@@ -2790,7 +2790,7 @@ if conf.get('ENABLE_NETWORKD') == 1
         executable('systemd-network-generator',
                    network_generator_sources,
                    include_directories : includes,
-                   link_with : [libshared],
+                   link_with : [networkd_link_with],
                    install_rpath : rootlibexecdir,
                    install : true,
                    install_dir : rootlibexecdir)
@@ -3296,6 +3296,7 @@ foreach tuple : [
         ['trace logging',    conf.get('LOG_TRACE') == 1],
         ['link-udev-shared',      get_option('link-udev-shared')],
         ['link-systemctl-shared', get_option('link-systemctl-shared')],
+        ['link-networkd-shared',  get_option('link-networkd-shared')],
 ]
 
         if tuple.length() >= 2
index 8a1143a7ec4c30843cb39e6d9ccba3cff42e29b2..4d641c3671240fea9f428e595d1fbfb0c97179ff 100644 (file)
@@ -16,6 +16,8 @@ option('link-udev-shared', type : 'boolean',
        description : 'link systemd-udev and its helpers to libsystemd-shared.so')
 option('link-systemctl-shared', type: 'boolean',
        description : 'link systemctl against libsystemd-shared.so')
+option('link-networkd-shared', type: 'boolean',
+       description : 'link systemd-networkd and its helpers to libsystemd-shared.so')
 option('static-libsystemd', type : 'combo',
        choices : ['false', 'true', 'pic', 'no-pic'],
        description : '''install a static library for libsystemd''')
index 67c1c2b327a773dc1c292dd819fe473bd44606c4..66bf03d05876a688736ce655a95c1a10ca175bdd 100644 (file)
@@ -3,8 +3,10 @@
 
 (( $+functions[_systemctl_commands] )) || _systemctl_commands()
 {
-    local -a _systemctl_cmds
-    _systemctl_cmds=(
+    local expl i
+
+    local -a unit_commands=(
+        # Unit Commands
         "list-sockets:List sockets"
         "list-timers:List timers"
         "list-units:List units"
@@ -16,9 +18,6 @@
         "try-restart:Restart one or more units if active"
         "reload-or-restart:Reload one or more units if possible, otherwise start or restart"
         "force-reload:Reload one or more units if possible, otherwise restart if active"
-        "hibernate:Hibernate the system"
-        "hybrid-sleep:Hibernate and suspend the system"
-        "suspend-then-hibernate:Suspend the system for a period of time, and then hibernate it"
         "try-reload-or-restart:Reload one or more units if possible, otherwise restart if active"
         "isolate:Start one unit and stop all others"
         "kill:Send signal to processes of a unit"
         "status:Show runtime status of one or more units"
         "show:Show properties of one or more units/jobs or the manager"
         "cat:Show the source unit files and drop-ins"
+        "set-property:Sets one or more properties of a unit"
+        "help:Show documentation for specified units"
         "reset-failed:Reset failed state for all, one, or more units"
+        "list-dependencies:Show unit dependency tree"
+        "clean:Remove configuration, state, cache, logs or runtime data of units"
+    )
+
+    local -a machine_commands=(
+        # Machine Commands
+        "list-machines:List the host and all running local containers"
+    )
+
+    local -a unit_file_commands=(
+        # Unit File Commands
         "list-unit-files:List installed unit files"
         "enable:Enable one or more unit files"
         "disable:Disable one or more unit files"
-        "add-wants:Add Wants= dependencies to a unit"
-        "add-requires:Add Requires= dependencies to a unit"
         "reenable:Reenable one or more unit files"
         "preset:Enable/disable one or more unit files based on preset configuration"
         "preset-all:Enable/disable all unit files based on preset configuration"
-        "set-default:Set the default target"
-        "get-default:Query the default target"
-        "edit:Edit one or more unit files"
-        "is-system-running:Query overall status of the system"
-        "help:Show documentation for specified units"
-        "list-dependencies:Show unit dependency tree"
+        "is-enabled:Check whether unit files are enabled"
         "mask:Mask one or more units"
         "unmask:Unmask one or more units"
         "link:Link one or more units files into the search path"
-        "is-enabled:Check whether unit files are enabled"
+        "revert:Revert unit files to their vendor versions"
+        "add-wants:Add Wants= dependencies to a unit"
+        "add-requires:Add Requires= dependencies to a unit"
+        "set-default:Set the default target"
+        "get-default:Query the default target"
+        "edit:Edit one or more unit files"
+    )
+
+    local -a job_commands=(
+        # Job Commands
         "list-jobs:List jobs"
         "cancel:Cancel all, one, or more jobs"
+    )
+
+    local -a environment_commands=(
+        # Environment Commands
         "show-environment:Dump environment"
         "set-environment:Set one or more environment variables"
         "unset-environment:Unset one or more environment variables"
+        "import-environment:Import environment variables set on the client"
+    )
+
+    local -a manager_state_commands=(
+        # Manager State Commands
         "daemon-reload:Reload systemd manager configuration"
         "daemon-reexec:Reexecute systemd manager"
+        "log-level:Get or set the log level"
+        "log-target:Get or set the log target"
+        "service-watchdogs:Get or set the state of software watchdogs"
+    )
+
+    local -a system_commands=(
+        # System Commands
+        "is-system-running:Query overall status of the system"
         "default:Enter system default mode"
         "rescue:Enter system rescue mode"
         "emergency:Enter system emergency mode"
         "kexec:Shut down and reboot the system with kexec"
         "exit:Ask for user instance termination"
         "switch-root:Change root directory"
-        "revert:Revert unit files to their vendor versions"
-        "set-property:Sets one or more properties of a unit"
+        "hibernate:Hibernate the system"
+        "hybrid-sleep:Hibernate and suspend the system"
+        "suspend-then-hibernate:Suspend the system for a period of time, and then hibernate it"
     )
 
+    local -a groups=( unit machine unit_file job environment manager_state system )
+    local -a _systemctl_cmds
+    for i in $groups; do
+        _systemctl_cmds+=( "${(@P)${:-"${i}_commands"}}" )
+    done
+
     if (( CURRENT == 1 )); then
-        _describe -t commands 'systemctl command' _systemctl_cmds || compadd "$@"
+        _tags ${^groups//_/-}-commands
+        while _tags; do
+            for i in $groups; do
+                if _requested ${i//_/-}-commands; then
+                    _describe -t ${i//_/-}-commands "${i//_/ } command" ${i}_commands \
+                        && ret=0
+                fi
+            done
+        done
     else
-        local curcontext="$curcontext" expl
+        local curcontext="$curcontext"
 
         cmd="${${_systemctl_cmds[(r)$words[1]:*]%%:*}}"
         # Deal with any aliases
index 457280df9fe7d479d90f92f7fdd3cb2fb9acef85..dc625119355f7c3e042f32d47d8acf05100f7bd3 100644 (file)
@@ -342,12 +342,11 @@ const char *special_glyph(SpecialGlyph code) {
                         [SPECIAL_GLYPH_TRIANGULAR_BULLET]       = ">",
                         [SPECIAL_GLYPH_BLACK_CIRCLE]            = "*",
                         [SPECIAL_GLYPH_BULLET]                  = "*",
-                        [SPECIAL_GLYPH_ARROW]                   = "->",
-                        [SPECIAL_GLYPH_MDASH]                   = "-",
-                        [SPECIAL_GLYPH_ELLIPSIS]                = "...",
                         [SPECIAL_GLYPH_MU]                      = "u",
                         [SPECIAL_GLYPH_CHECK_MARK]              = "+",
                         [SPECIAL_GLYPH_CROSS_MARK]              = "-",
+                        [SPECIAL_GLYPH_ARROW]                   = "->",
+                        [SPECIAL_GLYPH_ELLIPSIS]                = "...",
                         [SPECIAL_GLYPH_ECSTATIC_SMILEY]         = ":-]",
                         [SPECIAL_GLYPH_HAPPY_SMILEY]            = ":-}",
                         [SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY]   = ":-)",
@@ -359,26 +358,34 @@ const char *special_glyph(SpecialGlyph code) {
 
                 /* UTF-8 */
                 [true] = {
+                        /* The following are multiple glyphs in both ASCII and in UNICODE */
                         [SPECIAL_GLYPH_TREE_VERTICAL]           = "\342\224\202 ",            /* │  */
                         [SPECIAL_GLYPH_TREE_BRANCH]             = "\342\224\234\342\224\200", /* ├─ */
                         [SPECIAL_GLYPH_TREE_RIGHT]              = "\342\224\224\342\224\200", /* └─ */
                         [SPECIAL_GLYPH_TREE_SPACE]              = "  ",                       /*    */
+
+                        /* Single glyphs in both cases */
                         [SPECIAL_GLYPH_TRIANGULAR_BULLET]       = "\342\200\243",             /* ‣ */
                         [SPECIAL_GLYPH_BLACK_CIRCLE]            = "\342\227\217",             /* ● */
                         [SPECIAL_GLYPH_BULLET]                  = "\342\200\242",             /* • */
-                        [SPECIAL_GLYPH_ARROW]                   = "\342\206\222",             /* → */
-                        [SPECIAL_GLYPH_MDASH]                   = "\342\200\223",             /* – */
-                        [SPECIAL_GLYPH_ELLIPSIS]                = "\342\200\246",             /* … */
-                        [SPECIAL_GLYPH_MU]                      = "\316\274",                 /* μ */
+                        [SPECIAL_GLYPH_MU]                      = "\316\274",                 /* μ (actually called: GREEK SMALL LETTER MU) */
                         [SPECIAL_GLYPH_CHECK_MARK]              = "\342\234\223",             /* ✓ */
-                        [SPECIAL_GLYPH_CROSS_MARK]              = "\342\234\227",             /* ✗ */
-                        [SPECIAL_GLYPH_ECSTATIC_SMILEY]         = "\360\237\230\207",         /* 😇 */
-                        [SPECIAL_GLYPH_HAPPY_SMILEY]            = "\360\237\230\200",         /* 😀 */
-                        [SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY]   = "\360\237\231\202",         /* 🙂 */
-                        [SPECIAL_GLYPH_NEUTRAL_SMILEY]          = "\360\237\230\220",         /* 😐 */
-                        [SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = "\360\237\231\201",         /* 🙁 */
-                        [SPECIAL_GLYPH_UNHAPPY_SMILEY]          = "\360\237\230\250",         /* 😨 */
-                        [SPECIAL_GLYPH_DEPRESSED_SMILEY]        = "\360\237\244\242",         /* 🤢 */
+                        [SPECIAL_GLYPH_CROSS_MARK]              = "\342\234\227",             /* ✗ (actually called: BALLOT X) */
+
+                        /* Single glyph in Unicode, two in ASCII */
+                        [SPECIAL_GLYPH_ARROW]                   = "\342\206\222",             /* → (actually called: RIGHTWARDS ARROW) */
+
+                        /* Single glyph in Unicode, three in ASCII */
+                        [SPECIAL_GLYPH_ELLIPSIS]                = "\342\200\246",             /* … (actually called: HORIZONTAL ELLIPSIS) */
+
+                        /* These smileys are a single glyph in Unicode, and three in ASCII */
+                        [SPECIAL_GLYPH_ECSTATIC_SMILEY]         = "\360\237\230\207",         /* 😇 (actually called: SMILING FACE WITH HALO) */
+                        [SPECIAL_GLYPH_HAPPY_SMILEY]            = "\360\237\230\200",         /* 😀 (actually called: GRINNING FACE) */
+                        [SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY]   = "\360\237\231\202",         /* 🙂 (actually called: SLIGHTLY SMILING FACE) */
+                        [SPECIAL_GLYPH_NEUTRAL_SMILEY]          = "\360\237\230\220",         /* 😐 (actually called: NEUTRAL FACE) */
+                        [SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = "\360\237\231\201",         /* 🙁 (actually called: SLIGHTLY FROWNING FACE) */
+                        [SPECIAL_GLYPH_UNHAPPY_SMILEY]          = "\360\237\230\250",         /* 😨 (actually called: FEARFUL FACE) */
+                        [SPECIAL_GLYPH_DEPRESSED_SMILEY]        = "\360\237\244\242",         /* 🤢 (actually called: NAUSEATED FACE) */
                 },
         };
 
index 78abbafd8f0b2d1f0b5657e8bf9c90564c1f8efc..1df8ac4cb0ce631a78a0ecea9da113976dd5dafa 100644 (file)
@@ -46,12 +46,11 @@ typedef enum {
         SPECIAL_GLYPH_TRIANGULAR_BULLET,
         SPECIAL_GLYPH_BLACK_CIRCLE,
         SPECIAL_GLYPH_BULLET,
-        SPECIAL_GLYPH_ARROW,
-        SPECIAL_GLYPH_MDASH,
-        SPECIAL_GLYPH_ELLIPSIS,
         SPECIAL_GLYPH_MU,
         SPECIAL_GLYPH_CHECK_MARK,
         SPECIAL_GLYPH_CROSS_MARK,
+        SPECIAL_GLYPH_ARROW,
+        SPECIAL_GLYPH_ELLIPSIS,
         _SPECIAL_GLYPH_FIRST_SMILEY,
         SPECIAL_GLYPH_ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_SMILEY,
         SPECIAL_GLYPH_HAPPY_SMILEY,
index 6ba880dbc4a5fa3c5828e742e855b15049c4113f..12bf77e7013a140930bffff0cdeabbb371fae98b 100644 (file)
 #include "string-util.h"
 #include "virt.h"
 
+static const char *const vm_table[_VIRTUALIZATION_MAX] = {
+        [VIRTUALIZATION_XEN]       = "XenVMMXenVMM",
+        [VIRTUALIZATION_KVM]       = "KVMKVMKVM",
+        [VIRTUALIZATION_QEMU]      = "TCGTCGTCGTCG",
+        /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
+        [VIRTUALIZATION_VMWARE]    = "VMwareVMware",
+        /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */
+        [VIRTUALIZATION_MICROSOFT] = "Microsoft Hv",
+        /* https://wiki.freebsd.org/bhyve */
+        [VIRTUALIZATION_BHYVE]     = "bhyve bhyve ",
+        [VIRTUALIZATION_QNX]       = "QNXQVMBSQG",
+        /* https://projectacrn.org */
+        [VIRTUALIZATION_ACRN]      = "ACRNACRNACRN",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(vm, int);
+
 static int detect_vm_cpuid(void) {
 
         /* CPUID is an x86 specific interface. */
 #if defined(__i386__) || defined(__x86_64__)
 
-        static const struct {
-                const char *cpuid;
-                int id;
-        } cpuid_vendor_table[] = {
-                { "XenVMMXenVMM", VIRTUALIZATION_XEN       },
-                { "KVMKVMKVM",    VIRTUALIZATION_KVM       },
-                { "TCGTCGTCGTCG", VIRTUALIZATION_QEMU      },
-                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
-                { "VMwareVMware", VIRTUALIZATION_VMWARE    },
-                /* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs */
-                { "Microsoft Hv", VIRTUALIZATION_MICROSOFT },
-                /* https://wiki.freebsd.org/bhyve */
-                { "bhyve bhyve ", VIRTUALIZATION_BHYVE     },
-                { "QNXQVMBSQG",   VIRTUALIZATION_QNX       },
-                /* https://projectacrn.org */
-                { "ACRNACRNACRN", VIRTUALIZATION_ACRN      },
-        };
-
         uint32_t eax, ebx, ecx, edx;
         bool hypervisor;
 
@@ -59,7 +58,7 @@ static int detect_vm_cpuid(void) {
                         uint32_t sig32[3];
                         char text[13];
                 } sig = {};
-                unsigned j;
+                int v;
 
                 /* There is a hypervisor, see what it is */
                 __cpuid(0x40000000U, eax, ebx, ecx, edx);
@@ -70,11 +69,11 @@ static int detect_vm_cpuid(void) {
 
                 log_debug("Virtualization found, CPUID=%s", sig.text);
 
-                for (j = 0; j < ELEMENTSOF(cpuid_vendor_table); j ++)
-                        if (streq(sig.text, cpuid_vendor_table[j].cpuid))
-                                return cpuid_vendor_table[j].id;
+                v = vm_from_string(sig.text);
+                if (v < 0)
+                        return VIRTUALIZATION_VM_OTHER;
 
-                return VIRTUALIZATION_VM_OTHER;
+                return v;
         }
 #endif
         log_debug("No virtualization found in CPUID");
@@ -142,7 +141,7 @@ static int detect_vm_dmi(void) {
                 int id;
         } dmi_vendor_table[] = {
                 { "KVM",                 VIRTUALIZATION_KVM       },
-                { "QEMU",                VIRTUALIZATION_QEMU      },                
+                { "QEMU",                VIRTUALIZATION_QEMU      },
                 { "VMware",              VIRTUALIZATION_VMWARE    }, /* https://kb.vmware.com/s/article/1009458 */
                 { "VMW",                 VIRTUALIZATION_VMWARE    },
                 { "innotek GmbH",        VIRTUALIZATION_ORACLE    },
@@ -432,25 +431,23 @@ finish:
         return r;
 }
 
-int detect_container(void) {
-        static const struct {
-                const char *value;
-                int id;
-        } value_table[] = {
-                { "lxc",            VIRTUALIZATION_LXC            },
-                { "lxc-libvirt",    VIRTUALIZATION_LXC_LIBVIRT    },
-                { "systemd-nspawn", VIRTUALIZATION_SYSTEMD_NSPAWN },
-                { "docker",         VIRTUALIZATION_DOCKER         },
-                { "podman",         VIRTUALIZATION_PODMAN         },
-                { "rkt",            VIRTUALIZATION_RKT            },
-                { "wsl",            VIRTUALIZATION_WSL            },
-        };
+static const char *const container_table[_VIRTUALIZATION_MAX] = {
+        [VIRTUALIZATION_LXC]            = "lxc",
+        [VIRTUALIZATION_LXC_LIBVIRT]    = "lxc-libvirt",
+        [VIRTUALIZATION_SYSTEMD_NSPAWN] = "systemd-nspawn",
+        [VIRTUALIZATION_DOCKER]         = "docker",
+        [VIRTUALIZATION_PODMAN]         = "podman",
+        [VIRTUALIZATION_RKT]            = "rkt",
+        [VIRTUALIZATION_WSL]            = "wsl",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int);
 
+int detect_container(void) {
         static thread_local int cached_found = _VIRTUALIZATION_INVALID;
         _cleanup_free_ char *m = NULL;
         _cleanup_free_ char *o = NULL;
         const char *e = NULL;
-        unsigned j;
         int r;
 
         if (cached_found >= 0)
@@ -532,13 +529,9 @@ int detect_container(void) {
         goto finish;
 
 translate_name:
-        for (j = 0; j < ELEMENTSOF(value_table); j++)
-                if (streq(e, value_table[j].value)) {
-                        r = value_table[j].id;
-                        goto finish;
-                }
-
-        r = VIRTUALIZATION_CONTAINER_OTHER;
+        r = container_from_string(e);
+        if (r < 0)
+                r = VIRTUALIZATION_CONTAINER_OTHER;
 
 finish:
         log_debug("Found container virtualization %s.", virtualization_to_string(r));
index 84293364b47eb03fd23cd0bed99d04bec966c520..e1a1a685279a7fddbeaa73b9c06c553f4fe2db74 100644 (file)
@@ -1958,7 +1958,7 @@ static VOID config_entry_add_linux(
                                 continue;
                         }
 
-                        if (strcmpa((CHAR8 *)"VERSION_ID", key) == 0) {
+                        if (strcmpa((CHAR8 *)"VERSION", key) == 0) {
                                 FreePool(os_version);
                                 os_version = stra_to_str(value);
                                 continue;
index 4aac903aa6c7f33bb82535f73f380a208452a552..af3bd2345041a8563ef9f7d9d55efb3eb7fe4413 100644 (file)
@@ -443,6 +443,19 @@ static int add_automount(
         return generator_add_symlink(arg_dest, SPECIAL_LOCAL_FS_TARGET, "wants", unit);
 }
 
+static const char *esp_or_xbootldr_options(const DissectedPartition *p) {
+        assert(p);
+
+        /* if we probed vfat or have no idea about the file system then assume these file systems are vfat
+         * and thus understand "umask=0077". If we detected something else then don't specify any options and
+         * use kernel defaults. */
+
+        if (!p->fstype || streq(p->fstype, "vfat"))
+                return "umask=0077";
+
+        return NULL;
+}
+
 static int add_xbootldr(DissectedPartition *p) {
         int r;
 
@@ -472,7 +485,7 @@ static int add_xbootldr(DissectedPartition *p) {
                              "/boot",
                              p->fstype,
                              true,
-                             "umask=0077",
+                             esp_or_xbootldr_options(p),
                              "Boot Loader Partition",
                              120 * USEC_PER_SEC);
 }
@@ -546,7 +559,7 @@ static int add_esp(DissectedPartition *p, bool has_xbootldr) {
                              esp_path,
                              p->fstype,
                              true,
-                             "umask=0077",
+                             esp_or_xbootldr_options(p),
                              "EFI System Partition Automount",
                              120 * USEC_PER_SEC);
 }
index aa10d0c3a42a7eceeab94aa6e2c24500ca426d26..a91db5df5f1f0adbf8bbc406d16a79f7c9128015 100644 (file)
@@ -124,6 +124,49 @@ int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const
         return 0;
 }
 
+int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
+        int r;
+
+        assert(rtnl);
+        assert(ifname);
+
+        if (strv_isempty(alternative_names))
+                return 0;
+
+        if (!*rtnl) {
+                r = sd_netlink_open(rtnl);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_append_string(message, IFLA_IFNAME, ifname);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_message_close_container(message);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_call(*rtnl, message, 0, NULL);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
 int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
         int r;
index 1782786841115dde899f58c7471fba2d81542e0e..7b007a61c23ac04ec97f201374f2a71183c4c862 100644 (file)
@@ -50,6 +50,7 @@ static inline bool rtnl_message_type_is_qdisc(uint16_t type) {
 int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
 int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
 int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
+int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names);
 int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, int *ret);
 
 int rtnl_log_parse_error(int r);
index 71d2bf0f8b7bb009d95b84cdffbbf8a5988b97ac..182a666746055ff6210e02ba1bcc63fe2f0c13cc 100644 (file)
@@ -512,8 +512,8 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
 
         if (nlmsg_type == RTM_NEWLINK)
                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
-        else if (nlmsg_type == RTM_NEWLINK)
-                (*ret)->hdr->nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND;
+        else if (nlmsg_type == RTM_NEWLINKPROP)
+                (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL | NLM_F_APPEND;
 
         ifi = NLMSG_DATA((*ret)->hdr);
 
index 2bbd18363e69a817dd0c769c489b53fbacbb1f08..2a9ddb93aa73f998cd89df76eb1f7e1149a5631c 100644 (file)
@@ -32,9 +32,12 @@ SUBSYSTEM=="pci", ENV{ID_PCI_CLASS_FROM_DATABASE}=="Display controller", \
 SUBSYSTEM=="drm", KERNEL=="card[0-9]*", TAG+="seat", TAG+="master-of-seat"
 SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat"
 
-# 'Plugable' USB hub, sound, network, graphics adapter
+# 'Plugable UD-160' USB hub, sound, network, graphics adapter
 SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1"
 
+# 'Plugable UD-PRO8' USB hub, sound, network, graphics adapter
+SUBSYSTEM=="usb", ATTR{idVendor}=="1a40", ATTR{idProduct}=="0201", ENV{ID_AUTOSEAT}="1"
+
 # qemu (version 2.4+) has a PCI-PCI bridge (-device pci-bridge-seat) to group
 # devices belonging to one seat. See:
 #     http://git.qemu.org/?p=qemu.git;a=blob;f=docs/multiseat.txt
index 8b9ab8e9eb3320f9b270ea7067e21a179c63323e..7cb1bb5a388a82fbbb94698047f68681e5850597 100644 (file)
@@ -146,6 +146,15 @@ network_generator_sources = files('''
 network_include_dir = [includes, include_directories(['.', 'netdev', 'tc'])]
 
 if conf.get('ENABLE_NETWORKD') == 1
+        if get_option('link-networkd-shared')
+                networkd_link_with = [libshared]
+        else
+                networkd_link_with = [libsystemd_static,
+                                      libshared_static,
+                                      libjournal_client,
+                                      libbasic_gcrypt]
+        endif
+
         networkd_gperf_c = custom_target(
                 'networkd-gperf.c',
                 input : 'networkd-gperf.gperf',
@@ -172,7 +181,7 @@ if conf.get('ENABLE_NETWORKD') == 1
                 networkd_network_gperf_c,
                 netdev_gperf_c,
                 include_directories : network_include_dir,
-                link_with : [libshared])
+                link_with : [networkd_link_with])
 
         install_data('org.freedesktop.network1.conf',
                      install_dir : dbuspolicydir)
@@ -198,7 +207,7 @@ if conf.get('ENABLE_NETWORKD') == 1
      [libnetworkd_core,
       libudev_static,
       libsystemd_network,
-      libshared],
+      networkd_link_with],
      [threads],
      [],
      network_include_dir],
@@ -208,7 +217,7 @@ if conf.get('ENABLE_NETWORKD') == 1
      [libnetworkd_core,
       libudev_static,
       libsystemd_network,
-      libshared],
+      networkd_link_with],
      [threads],
      [],
      network_include_dir],
@@ -225,7 +234,7 @@ if conf.get('ENABLE_NETWORKD') == 1
      [libnetworkd_core,
       libudev_static,
       libsystemd_network,
-      libshared],
+      networkd_link_with],
      [threads],
      '', '', [], network_include_dir],
 
@@ -239,17 +248,16 @@ if conf.get('ENABLE_NETWORKD') == 1
       test_tables_h],
      [libnetworkd_core,
       libudev_static,
-      libudev_core,
       libsystemd_network,
-      libshared],
+      networkd_link_with],
      [threads],
      '', '', [],
-     [network_include_dir] + libudev_core_includes],
+     [network_include_dir]],
 
     [['src/network/generator/test-network-generator.c',
       'src/network/generator/network-generator.c',
       'src/network/generator/network-generator.h'],
-     [libshared],
+     [networkd_link_with],
      [], '', '', [], network_include_dir],
   ]
 endif
index 66d83e76bfae4ffd3c590999c01cc051d3b4445f..70377ad6bb5b0bd18b30397da46e161222f09cd7 100644 (file)
@@ -377,6 +377,23 @@ static int link_set_dhcp_routes(Link *link) {
                         return log_link_error_errno(link, r, "Could not set router: %m");
         }
 
+        Route *rt;
+        LIST_FOREACH(routes, rt, link->network->static_routes) {
+                if (!rt->gateway_from_dhcp)
+                        continue;
+
+                if (rt->family != AF_INET)
+                        continue;
+
+                rt->gw.in = router[0];
+
+                r = route_configure(rt, link, dhcp4_route_handler);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Could not set gateway: %m");
+                if (r > 0)
+                        link->dhcp4_messages++;
+        }
+
         return link_set_dns_routes(link, &address);
 }
 
@@ -480,6 +497,20 @@ static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_
         if (remove_all || !set_contains(link->dhcp_routes, route))
                 (void) route_remove(route, link, NULL);
 
+        Route *rt;
+        LIST_FOREACH(routes, rt, link->network->static_routes) {
+                if (!rt->gateway_from_dhcp)
+                        continue;
+
+                if (rt->family != AF_INET)
+                        continue;
+
+                if (!remove_all && in4_addr_equal(router, &rt->gw.in))
+                        continue;
+
+                (void) route_remove(rt, link, NULL);
+        }
+
         return 0;
 }
 
index 23d0ee675b007ba9a4c9496bfb337e783c9293e9..f2027057c44f39782731d290cfee6c63e7588486 100644 (file)
@@ -1039,6 +1039,8 @@ int link_request_set_routes(Link *link) {
         /* First add the routes that enable us to talk to gateways, then add in the others that need a gateway. */
         for (phase = 0; phase < _PHASE_MAX; phase++)
                 LIST_FOREACH(routes, rt, link->network->static_routes) {
+                        if (rt->gateway_from_dhcp)
+                                continue;
 
                         if ((in_addr_is_null(rt->family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY))
                                 continue;
index f4e4162cf1213e19e39126a0f9fc9699b5516d0d..380f5c1c61f14613e113284964e9f29c931b092e 100644 (file)
@@ -695,8 +695,8 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
                                        strnull(addr_str), strnull(lladdr_str));
                         (void) neighbor_free(neighbor);
                 } else
-                        log_link_info(link, "Kernel removed a neighbor we don't remember: %s->%s, ignoring.",
-                                      strnull(addr_str), strnull(lladdr_str));
+                        log_link_debug(link, "Kernel removed a neighbor we don't remember: %s->%s, ignoring.",
+                                       strnull(addr_str), strnull(lladdr_str));
 
                 break;
 
@@ -855,9 +855,9 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
                                        valid_str ? "for " : "forever", strempty(valid_str));
                         (void) address_drop(address);
                 } else
-                        log_link_info(link, "Kernel removed an address we don't remember: %s/%u (valid %s%s), ignoring.",
-                                      strnull(buf), prefixlen,
-                                      valid_str ? "for " : "forever", strempty(valid_str));
+                        log_link_debug(link, "Kernel removed an address we don't remember: %s/%u (valid %s%s), ignoring.",
+                                       strnull(buf), prefixlen,
+                                       valid_str ? "for " : "forever", strempty(valid_str));
 
                 break;
 
index d1db9e4931c17e9d84cd837f2c01bf432d312544..fb3d6f2a841ace03b792adfbf004c3042ae658f5 100644 (file)
@@ -169,6 +169,26 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         if (r > 0)
                 link->ndisc_messages++;
 
+        Route *route_gw;
+        LIST_FOREACH(routes, route_gw, link->network->static_routes) {
+                if (!route_gw->gateway_from_dhcp)
+                        continue;
+
+                if (route_gw->family != AF_INET6)
+                        continue;
+
+                route_gw->gw = gateway;
+
+                r = route_configure(route_gw, link, ndisc_netlink_route_message_handler);
+                if (r < 0) {
+                        log_link_error_errno(link, r, "Could not set gateway: %m");
+                        link_enter_failed(link);
+                        return r;
+                }
+                if (r > 0)
+                        link->ndisc_messages++;
+        }
+
         return 0;
 }
 
index ecc8d219b7d1d59da62a3a31b19b94de35ddd23c..4e90fdef18535dd3e4cf66680493cf876669e88d 100644 (file)
@@ -998,10 +998,19 @@ int config_parse_gateway(
                 /* we are not in an Route section, so treat
                  * this as the special '0' section */
                 r = route_new_static(network, NULL, 0, &n);
-        } else
+                if (r < 0)
+                        return r;
+        } else {
                 r = route_new_static(network, filename, section_line, &n);
-        if (r < 0)
-                return r;
+                if (r < 0)
+                        return r;
+
+                if (streq(rvalue, "dhcp")) {
+                        n->gateway_from_dhcp = true;
+                        TAKE_PTR(n);
+                        return 0;
+                }
+        }
 
         if (n->family == AF_UNSPEC)
                 r = in_addr_from_string_auto(rvalue, &n->family, &n->gw);
index 91bba368ee21f73e14c5108a889f19667ef3dc64..067c65f2f78217eb387d953526525ee2b8785e35 100644 (file)
@@ -48,6 +48,7 @@ struct Route {
         unsigned char pref;
         unsigned flags;
         int gateway_onlink;
+        bool gateway_from_dhcp;
 
         union in_addr_union gw;
         union in_addr_union dst;
index f423f625905ef2fa7bf082d9ffee3ce84bd80e37..6afc31d824b345a3deecd9456a6caf677c9be7dc 100644 (file)
@@ -989,6 +989,19 @@ int mount_custom(
         return 0;
 }
 
+bool has_custom_root_mount(const CustomMount *mounts, size_t n) {
+        size_t i;
+
+        for (i = 0; i < n; i++) {
+                const CustomMount *m = mounts + i;
+
+                if (path_equal(m->destination, "/"))
+                        return true;
+        }
+
+        return false;
+}
+
 static int setup_volatile_state(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) {
 
         _cleanup_free_ char *buf = NULL;
index aabc9e29bef5161e66ca02b03dbae897d3726602..680ff350e5d33a12ccc8480247d8665be79654c7 100644 (file)
@@ -55,6 +55,7 @@ int mount_all(const char *dest, MountSettingsMask mount_settings, uid_t uid_shif
 int mount_sysfs(const char *dest, MountSettingsMask mount_settings);
 
 int mount_custom(const char *dest, CustomMount *mounts, size_t n, uid_t uid_shift, const char *selinux_apifs_context, MountSettingsMask mount_settings);
+bool has_custom_root_mount(const CustomMount *mounts, size_t n);
 
 int setup_volatile_mode(const char *directory, VolatileMode mode, uid_t uid_shift, const char *selinux_apifs_context);
 
index e91a9d36bf334302db28ae72d241cfea5c31c614..9c9cf4812e8f2cb8a0fea709dcefd443c89c5f7e 100644 (file)
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
+#include <net/if.h>
+#include <linux/if.h>
 #include <linux/veth.h>
 #include <sys/file.h>
 
@@ -99,10 +101,34 @@ static int generate_mac(
         return 0;
 }
 
+static int set_alternative_ifname(sd_netlink *rtnl, const char *ifname, const char *altifname) {
+        int r;
+
+        assert(rtnl);
+        assert(ifname);
+
+        if (!altifname)
+                return 0;
+
+        if (strlen(altifname) >= ALTIFNAMSIZ)
+                return log_warning_errno(SYNTHETIC_ERRNO(ERANGE),
+                                         "Alternative interface name '%s' for '%s' is too long, ignoring",
+                                         altifname, ifname);
+
+        r = rtnl_set_link_alternative_names_by_ifname(&rtnl, ifname, STRV_MAKE(altifname));
+        if (r < 0)
+                return log_warning_errno(r,
+                                         "Failed to set alternative interface name '%s' to '%s', ignoring: %m",
+                                         altifname, ifname);
+
+        return 0;
+}
+
 static int add_veth(
                 sd_netlink *rtnl,
                 pid_t pid,
                 const char *ifname_host,
+                const char *altifname_host,
                 const struct ether_addr *mac_host,
                 const char *ifname_container,
                 const struct ether_addr *mac_container) {
@@ -168,6 +194,8 @@ static int add_veth(
         if (r < 0)
                 return log_error_errno(r, "Failed to add new veth interfaces (%s:%s): %m", ifname_host, ifname_container);
 
+        (void) set_alternative_ifname(rtnl, ifname_host, altifname_host);
+
         return 0;
 }
 
@@ -181,13 +209,13 @@ static char urlsafe_base64char(int x) {
         return table[x & 63];
 }
 
-static void shorten_ifname(char *ifname) {
+static int shorten_ifname(char *ifname) {
         char new_ifname[IFNAMSIZ];
 
         assert(ifname);
 
         if (strlen(ifname) < IFNAMSIZ) /* Name is short enough */
-                return;
+                return 0;
 
         if (naming_scheme_has(NAMING_NSPAWN_LONG_HASH)) {
                 uint64_t h;
@@ -211,6 +239,7 @@ static void shorten_ifname(char *ifname) {
         log_warning("Network interface name '%s' has been changed to '%s' to fit length constraints.", ifname, new_ifname);
 
         strcpy(ifname, new_ifname);
+        return 1;
 }
 
 int setup_veth(const char *machine_name,
@@ -221,7 +250,7 @@ int setup_veth(const char *machine_name,
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         struct ether_addr mac_host, mac_container;
         unsigned u;
-        char *n;
+        char *n, *a = NULL;
         int r;
 
         assert(machine_name);
@@ -231,7 +260,9 @@ int setup_veth(const char *machine_name,
         /* Use two different interface name prefixes depending whether
          * we are in bridge mode or not. */
         n = strjoina(bridge ? "vb-" : "ve-", machine_name);
-        shorten_ifname(n);
+        r = shorten_ifname(n);
+        if (r > 0)
+                a = strjoina(bridge ? "vb-" : "ve-", machine_name);
 
         r = generate_mac(machine_name, &mac_container, CONTAINER_HASH_KEY, 0);
         if (r < 0)
@@ -245,7 +276,7 @@ int setup_veth(const char *machine_name,
         if (r < 0)
                 return log_error_errno(r, "Failed to connect to netlink: %m");
 
-        r = add_veth(rtnl, pid, n, &mac_host, "host0", &mac_container);
+        r = add_veth(rtnl, pid, n, a, &mac_host, "host0", &mac_container);
         if (r < 0)
                 return r;
 
@@ -288,7 +319,7 @@ int setup_veth_extra(
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate predictable MAC address for container side of extra veth link: %m");
 
-                r = add_veth(rtnl, pid, *a, &mac_host, *b, &mac_container);
+                r = add_veth(rtnl, pid, *a, NULL, &mac_host, *b, &mac_container);
                 if (r < 0)
                         return r;
 
@@ -536,7 +567,7 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
 
         STRV_FOREACH(i, ifaces) {
                 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
-                _cleanup_free_ char *n = NULL;
+                _cleanup_free_ char *n = NULL, *a = NULL;
                 struct ether_addr mac;
                 int ifi;
 
@@ -560,7 +591,12 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 if (!n)
                         return log_oom();
 
-                shorten_ifname(n);
+                r = shorten_ifname(n);
+                if (r > 0) {
+                        a = strjoin("mv-", *i);
+                        if (!a)
+                                return log_oom();
+                }
 
                 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
                 if (r < 0)
@@ -597,6 +633,8 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 r = sd_netlink_call(rtnl, m, 0, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to add new macvlan interfaces: %m");
+
+                (void) set_alternative_ifname(rtnl, n, a);
         }
 
         return 0;
@@ -616,7 +654,7 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
 
         STRV_FOREACH(i, ifaces) {
                 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
-                _cleanup_free_ char *n = NULL;
+                _cleanup_free_ char *n = NULL, *a = NULL;
                 int ifi;
 
                 ifi = parse_interface(*i);
@@ -635,7 +673,12 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 if (!n)
                         return log_oom();
 
-                shorten_ifname(n);
+                r = shorten_ifname(n);
+                if (r > 0) {
+                        a = strjoin("iv-", *i);
+                        if (!a)
+                                return log_oom();
+                }
 
                 r = sd_netlink_message_append_string(m, IFLA_IFNAME, n);
                 if (r < 0)
@@ -668,6 +711,8 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces) {
                 r = sd_netlink_call(rtnl, m, 0, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to add new ipvlan interfaces: %m");
+
+                (void) set_alternative_ifname(rtnl, n, a);
         }
 
         return 0;
index 32294ed00293e31e1daf33c203d1476369c52532..791bdd35321a64f171603ed0f3d516ad213ef7b7 100644 (file)
@@ -1541,6 +1541,9 @@ static int verify_arguments(void) {
         if (arg_volatile_mode != VOLATILE_NO) /* Make sure all file systems contained in the image are mounted read-only if we are in volatile mode */
                 arg_read_only = true;
 
+        if (has_custom_root_mount(arg_custom_mounts, arg_n_custom_mounts))
+                arg_read_only = true;
+
         if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0)
                 /* Save the user from accidentally registering either user-$SESSION.scope or user@.service.
                  * The latter is not technically a user session, but we don't need to labour the point. */
@@ -3438,7 +3441,8 @@ static int outer_child(
         if (r < 0)
                 return r;
 
-        if (arg_read_only && arg_volatile_mode == VOLATILE_NO) {
+        if (arg_read_only && arg_volatile_mode == VOLATILE_NO &&
+                !has_custom_root_mount(arg_custom_mounts, arg_n_custom_mounts)) {
                 r = bind_remount_recursive(directory, MS_RDONLY, MS_RDONLY, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to make tree read-only: %m");
index fac98ad0eadf09c9de80e9ed3c84ccaa27dd49e5..3fcd7630db6bd429c2fd154168e7d728b84db61f 100644 (file)
@@ -218,7 +218,7 @@ int pkcs11_token_login(
                         r = asprintf(&text,
                                      "Please enter correct PIN for security token '%s' in order to unlock %s (final try):",
                                      token_label, friendly_name);
-                if (FLAGS_SET(token_info->flags, CKF_USER_PIN_COUNT_LOW))
+                else if (FLAGS_SET(token_info->flags, CKF_USER_PIN_COUNT_LOW))
                         r = asprintf(&text,
                                      "PIN has been entered incorrectly previously, please enter correct PIN for security token '%s' in order to unlock %s:",
                                      token_label, friendly_name);
index 28d90be8964d1b19da6ed29f1bd8c6fc226da777..f49cc6371ef0a21bd7278b520edbbdde99512761 100644 (file)
@@ -81,7 +81,6 @@ static void dump_special_glyphs(void) {
         dump_glyph(SPECIAL_GLYPH_BLACK_CIRCLE);
         dump_glyph(SPECIAL_GLYPH_BULLET);
         dump_glyph(SPECIAL_GLYPH_ARROW);
-        dump_glyph(SPECIAL_GLYPH_MDASH);
         dump_glyph(SPECIAL_GLYPH_ELLIPSIS);
         dump_glyph(SPECIAL_GLYPH_MU);
         dump_glyph(SPECIAL_GLYPH_CHECK_MARK);
index e94fff2520cb195000eab78cd755bab3063efe7f..169d6ce8f7cb2e164baa6f988882cf8e74d6d098 100644 (file)
@@ -330,8 +330,9 @@ static int dev_pci_slot(sd_device *dev, struct netnames *names) {
                         char str[PATH_MAX];
                         _cleanup_free_ char *address = NULL;
 
-                        if (dent->d_name[0] == '.')
+                        if (dot_or_dot_dot(dent->d_name))
                                 continue;
+
                         r = safe_atou_full(dent->d_name, 10, &i);
                         if (r < 0 || i <= 0)
                                 continue;
index 6168b332d3b23f8801dbc2db4952d72329c5716e..b9b350d1ef7a4f8064a7a7bd1e6b796d4bfaff7a 100644 (file)
@@ -1654,7 +1654,7 @@ static int udev_rule_apply_token_to_event(
                 if (mode == MODE_INVALID)
                         return token->op == OP_MATCH;
 
-                match = (((statbuf.st_mode ^ mode) & 07777) == 0);
+                match = (statbuf.st_mode & mode) > 0;
                 return token->op == (match ? OP_MATCH : OP_NOMATCH);
         }
         case TK_M_PROGRAM: {
index 49d61c6a7f94342b1dba56c51098cca301c56109..fe20114756b4d9f5af959b2493ee9e50318c07d0 100755 (executable)
@@ -15,20 +15,23 @@ test_setup() {
 
         mask_supporting_services
 
-        usermod --root $initdir -d /home/nobody -s /bin/bash nobody
-        mkdir $initdir/home $initdir/home/nobody
-        # Ubuntu's equivalent is nogroup
-        chown nobody:nobody $initdir/home/nobody || chown nobody:nogroup $initdir/home/nobody
+        # Allocate user for running test case under
+        mkdir -p $initdir/etc/sysusers.d
+        cat >$initdir/etc/sysusers.d/testuser.conf <<EOF
+u testuser    4711     "Test User" /home/testuser
+EOF
 
-        enable_user_manager nobody
+        mkdir -p $initdir/home/testuser -m 0700
+        chown 4711:4711 $initdir/home/testuser
 
-        nobody_uid=$(id -u nobody)
+        enable_user_manager testuser
 
         # setup the testsuite service
         cat >$initdir/etc/systemd/system/testsuite.service <<EOF
 [Unit]
 Description=Testsuite service
-After=systemd-logind.service user@$nobody_uid.service
+After=systemd-logind.service user@4711.service
+Wants=user@4711.service
 
 [Service]
 ExecStart=/testsuite.sh
index cd61dc95c9560edb0750f5bd9bbf1179ead585d5..fa5da2ec7d7536246524c62c53b9432d9ffd01c1 100755 (executable)
@@ -7,15 +7,13 @@ systemd-analyze log-level debug
 runas() {
     declare userid=$1
     shift
-    su "$userid" -c 'XDG_RUNTIME_DIR=/run/user/$UID "$@"' -- sh "$@"
+    su "$userid" -s /bin/sh -c 'XDG_RUNTIME_DIR=/run/user/$UID exec "$@"' -- sh "$@"
 }
 
-runas nobody systemctl --user --wait is-system-running
-
-runas nobody systemd-run --user --unit=test-private-users \
+runas testuser systemd-run --user --unit=test-private-users \
     -p PrivateUsers=yes -P echo hello
 
-runas nobody systemd-run --user --unit=test-private-tmp-innerfile \
+runas testuser systemd-run --user --unit=test-private-tmp-innerfile \
     -p PrivateUsers=yes -p PrivateTmp=yes \
     -P touch /tmp/innerfile.txt
 # File should not exist outside the job's tmp directory.
@@ -23,31 +21,31 @@ test ! -e /tmp/innerfile.txt
 
 touch /tmp/outerfile.txt
 # File should not appear in unit's private tmp.
-runas nobody systemd-run --user --unit=test-private-tmp-outerfile \
+runas testuser systemd-run --user --unit=test-private-tmp-outerfile \
     -p PrivateUsers=yes -p PrivateTmp=yes \
     -P test ! -e /tmp/outerfile.txt
 
 # Confirm that creating a file in home works
-runas nobody systemd-run --user --unit=test-unprotected-home \
-    -P touch /home/nobody/works.txt
-test -e /home/nobody/works.txt
+runas testuser systemd-run --user --unit=test-unprotected-home \
+    -P touch /home/testuser/works.txt
+test -e /home/testuser/works.txt
 
 # Confirm that creating a file in home is blocked under read-only
-runas nobody systemd-run --user --unit=test-protect-home-read-only \
+runas testuser systemd-run --user --unit=test-protect-home-read-only \
     -p PrivateUsers=yes -p ProtectHome=read-only \
     -P bash -c '
-        test -e /home/nobody/works.txt
-        ! touch /home/nobody/blocked.txt
+        test -e /home/testuser/works.txt
+        ! touch /home/testuser/blocked.txt
     '
-test ! -e /home/nobody/blocked.txt
+test ! -e /home/testuser/blocked.txt
 
 # Check that tmpfs hides the whole directory
-runas nobody systemd-run --user --unit=test-protect-home-tmpfs \
+runas testuser systemd-run --user --unit=test-protect-home-tmpfs \
     -p PrivateUsers=yes -p ProtectHome=tmpfs \
-    -P test ! -e /home/nobody
+    -P test ! -e /home/testuser
 
 # Confirm that home, /root, and /run/user are inaccessible under "yes"
-runas nobody systemd-run --user --unit=test-protect-home-yes \
+runas testuser systemd-run --user --unit=test-protect-home-yes \
     -p PrivateUsers=yes -p ProtectHome=yes \
     -P bash -c '
         test "$(stat -c %a /home)" = "0"
@@ -59,7 +57,7 @@ runas nobody systemd-run --user --unit=test-protect-home-yes \
 # namespace (no CAP_SETGID in the parent namespace to write the additional
 # mapping of the user supplied group and thus cannot change groups to an
 # unmapped group ID)
-! runas nobody systemd-run --user --unit=test-group-fail \
+! runas testuser systemd-run --user --unit=test-group-fail \
     -p PrivateUsers=yes -p Group=daemon \
     -P true
 
diff --git a/test/test-network/conf/dhcp-client-gateway-ipv4.network b/test/test-network/conf/dhcp-client-gateway-ipv4.network
new file mode 100644 (file)
index 0000000..1b8a375
--- /dev/null
@@ -0,0 +1,10 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv4
+IPv6AcceptRA=no
+
+[Route]
+Gateway=dhcp
+Destination=10.0.0.0/8
diff --git a/test/test-network/conf/dhcp-client-gateway-ipv6.network b/test/test-network/conf/dhcp-client-gateway-ipv6.network
new file mode 100644 (file)
index 0000000..058cb33
--- /dev/null
@@ -0,0 +1,9 @@
+[Match]
+Name=veth99
+
+[Network]
+DHCP=ipv6
+
+[Route]
+Gateway=dhcp
+Destination=2001:1234:5:9fff:ff:ff:ff:ff/128
index 90b1a8b14072cbaf8f06d51af0c1abae9b0d5b7a..d9b5df18dfe66231fc64f3fb405bfdce71e2d09f 100755 (executable)
@@ -2659,6 +2659,8 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         '25-vrf.network',
         'dhcp-client-anonymize.network',
         'dhcp-client-decline.network',
+        'dhcp-client-gateway-ipv4.network',
+        'dhcp-client-gateway-ipv6.network',
         'dhcp-client-gateway-onlink-implicit.network',
         'dhcp-client-ipv4-dhcp-settings.network',
         'dhcp-client-ipv4-only-ipv6-disabled.network',
@@ -3145,6 +3147,30 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
         print(output)
         self.assertEqual(output, '')
 
+    def test_dhcp_client_gateway_ipv4(self):
+        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
+                                        'dhcp-client-gateway-ipv4.network')
+        start_networkd()
+        self.wait_online(['veth-peer:carrier'])
+        start_dnsmasq()
+        self.wait_online(['veth99:routable', 'veth-peer:routable'])
+
+        output = check_output('ip route list dev veth99 10.0.0.0/8')
+        print(output)
+        self.assertRegex(output, '10.0.0.0/8 via 192.168.5.1 proto static')
+
+    def test_dhcp_client_gateway_ipv6(self):
+        copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
+                                        'dhcp-client-gateway-ipv6.network')
+        start_networkd()
+        self.wait_online(['veth-peer:carrier'])
+        start_dnsmasq()
+        self.wait_online(['veth99:routable', 'veth-peer:routable'])
+
+        output = check_output('ip -6 route list dev veth99 2001:1234:5:9fff:ff:ff:ff:ff')
+        print(output)
+        self.assertRegex(output, 'via fe80::1034:56ff:fe78:9abd')
+
     def test_dhcp_client_gateway_onlink_implicit(self):
         copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
                                         'dhcp-client-gateway-onlink-implicit.network')
index c809011fc5ea6e4dc457d5f31f708830c20bc913..4ad64d12f255f7a6fc4cb3413cc48dbadab656a6 100644 (file)
@@ -35,6 +35,7 @@ units = [
         ['local-fs.target',                     ''],
         ['machine.slice',                       'ENABLE_MACHINED'],
         ['machines.target',                     'ENABLE_MACHINED'],
+        ['modprobe@.service',                   ''],
         ['multi-user.target',                   '',
          'runlevel2.target runlevel3.target runlevel4.target'],
         ['network-online.target',               ''],
diff --git a/units/modprobe@.service b/units/modprobe@.service
new file mode 100644 (file)
index 0000000..4c5bd63
--- /dev/null
@@ -0,0 +1,16 @@
+#  SPDX-License-Identifier: LGPL-2.1+
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Load kernel module %i
+Documentation=man:modprobe(8)
+
+[Service]
+Type=oneshot
+ExecStart=-/sbin/modprobe -abq %I
index ccbe6315860d0107b40f8f511587fa03e3dbc12b..23aa828591c434939679b796166237fde60dcf2e 100644 (file)
@@ -12,8 +12,8 @@ Description=Login Service
 Documentation=man:systemd-logind.service(8) man:logind.conf(5)
 Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
 Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
-Wants=user.slice
-After=nss-user-lookup.target user.slice
+Wants=user.slice modprobe@drm.service
+After=nss-user-lookup.target user.slice modprobe@drm.service
 
 # Ask for the dbus socket.
 Wants=dbus.socket
@@ -29,7 +29,6 @@ DeviceAllow=char-input rw
 DeviceAllow=char-tty rw
 DeviceAllow=char-vcs rw
 # Make sure the DeviceAllow= lines above can work correctly when referenceing char-drm
-ExecStartPre=-/sbin/modprobe -abq drm
 ExecStart=@rootlibexecdir@/systemd-logind
 FileDescriptorStoreMax=512
 IPAddressDeny=any
index 669fea3c12ca0f0b01cffb82e2d5c9e008e93828..5367ee44105b3bf7dddd21e2773f5473bdee7a64 100644 (file)
 [Unit]
 Description=Container %i
 Documentation=man:systemd-nspawn(1)
+Wants=modprobe@tun.service modprobe@loop.service modprobe@dm-mod.service
 PartOf=machines.target
 Before=machines.target
-After=network.target systemd-resolved.service
+After=network.target systemd-resolved.service modprobe@tun.service modprobe@loop.service modprobe@dm-mod.service
 RequiresMountsFor=/var/lib/machines
 
 [Service]
 # Make sure the DeviceAllow= lines below can properly resolve the 'block-loop' expression (and others)
-ExecStartPre=-/sbin/modprobe -abq tun loop dm-mod
 ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth -U --settings=override --machine=%i
 KillMode=mixed
 Type=notify