]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #22983 from yuwata/login-use-symlinks-under-static_node-tags
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 6 Apr 2022 14:11:56 +0000 (23:11 +0900)
committerGitHub <noreply@github.com>
Wed, 6 Apr 2022 14:11:56 +0000 (23:11 +0900)
login: shorten code a bit

47 files changed:
.semaphore/semaphore-runner.sh
.semaphore/semaphore.yml
README
docs/sysvinit/meson.build
factory/templates/meson.build
man/kernel-install.xml
man/meson.build
man/systemd.net-naming-scheme.xml
meson.build
rules.d/meson.build
shell-completion/bash/meson.build
shell-completion/zsh/meson.build
src/basic/def.h
src/core/main.c
src/core/manager.c
src/core/meson.build
src/firstboot/firstboot.c
src/hwdb/hwdb.c
src/journal-remote/meson.build
src/kernel-install/kernel-install.in [moved from src/kernel-install/kernel-install with 95% similarity]
src/kernel-install/meson.build
src/libsystemd/meson.build
src/libudev/meson.build
src/login/meson.build
src/resolve/meson.build
src/rpm/meson.build
src/shared/netif-naming-scheme.c
src/shared/netif-naming-scheme.h
src/timesync/meson.build
src/udev/meson.build
src/udev/udev-builtin-net_id.c
src/udev/udev-event.c
src/udev/udev-node.c
src/udev/udev-node.h
src/udev/udev-rules.c
src/udev/udevadm-lock.c
src/udev/udevd.c
src/vconsole/meson.build
sysctl.d/meson.build
sysusers.d/meson.build
test/test-network/conf/25-ip6tnl-tunnel-external.netdev [moved from test/test-network/conf/25-ip6tnl-external.netdev with 100% similarity]
test/test-network/systemd-networkd-tests.py
tmpfiles.d/meson.build
tools/check-help.sh
tools/check-version.sh [new file with mode: 0755]
tools/meson-render-jinja2.py
units/meson.build

index 6ccf271a82fe269b26bea3cf51c6fcb001217c54..ec95f65315b208bb8ec0c9078bb025e34b68f67d 100755 (executable)
@@ -21,7 +21,7 @@ UBUNTU_RELEASE="$(lsb_release -cs)"
 create_container() {
     # Create autopkgtest LXC image; this sometimes fails with "Unable to fetch
     # GPG key from keyserver", so retry a few times with different keyservers.
-    for keyserver in "" "keys.gnupg.net" "keys.openpgp.org" "keyserver.ubuntu.com"; do
+    for keyserver in "keys.openpgp.org" "" "keyserver.ubuntu.com" "keys.gnupg.net"; do
         for retry in {1..5}; do
             sudo lxc-create -n "$CONTAINER" -t download -- -d "$DISTRO" -r "$RELEASE" -a "$ARCH" ${keyserver:+--keyserver "$keyserver"} && break 2
             sleep $((retry*retry))
@@ -36,8 +36,16 @@ create_container() {
     # enable source repositories so that apt-get build-dep works
     sudo lxc-attach -n "$CONTAINER" -- sh -ex <<EOF
 sed 's/^deb/deb-src/' /etc/apt/sources.list >> /etc/apt/sources.list.d/sources.list
-# wait until online
-while [ -z "\$(ip route list 0/0)" ]; do sleep 1; done
+# We might attach the console too soon
+while ! systemctl --quiet --wait is-system-running; do sleep 1; done
+# Manpages database trigger takes a lot of time and is not useful in a CI
+echo 'man-db man-db/auto-update boolean false' | debconf-set-selections
+# Speed up dpkg, image is thrown away after the test
+mkdir -p /etc/dpkg/dpkg.cfg.d/
+echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/unsafe_io
+# For some reason, it is necessary to run this manually or the interface won't be configured
+# Note that we avoid networkd, as some of the tests will break it later on
+dhclient
 apt-get -q --allow-releaseinfo-change update
 apt-get -y dist-upgrade
 apt-get install -y eatmydata
@@ -88,6 +96,10 @@ EOF
             rm -rf debian/patches
             # disable autopkgtests which are not for upstream
             sed -i '/# NOUPSTREAM/ q' debian/tests/control
+            # TODO: rebooting via autopkgtest-reboot seems to be broken, disable these tests for now
+            sed -i -n '1,/Tests: boot-and-services/p;/Tests: udev/,$p' debian/tests/control
+            sed -i '/Tests: boot-and-services/d' debian/tests/control
+            sed -i '/Tests: boot-smoke/,$d' debian/tests/control
             # enable more unit tests
             sed -i '/^CONFFLAGS =/ s/=/= --werror -Dtests=unsafe -Dsplit-usr=true -Dslow-tests=true -Dfuzz-tests=true -Dman=true /' debian/rules
             # no orig tarball
index bd5d135e9e1291206929de25191f3409a74e2049..07742337e8a0bf25a7086e56233965d18ec65325 100644 (file)
@@ -7,7 +7,7 @@ name: Debian autopkgtest (LXC)
 agent:
   machine:
     type: e1-standard-2
-    os_image: ubuntu1804
+    os_image: ubuntu2004
 
 # Cancel any running or queued job for the same ref
 auto_cancel:
diff --git a/README b/README
index 420276eda8951ce6e323559d0a0a6562e025f451..4c9d9ae1bd864ff8bd1b771f42a32f46baea3580 100644 (file)
--- a/README
+++ b/README
@@ -30,14 +30,21 @@ LICENSE:
         LGPL-2.1-or-later for all code, exceptions noted in LICENSES/README.md
 
 REQUIREMENTS:
-        Linux kernel >= 3.15
-        Linux kernel >= 4.2 for unified cgroup hierarchy support
-        Linux kernel >= 4.10 for cgroup-bpf egress and ingress hooks
-        Linux kernel >= 4.15 for cgroup-bpf device hook
-        Linux kernel >= 4.17 for cgroup-bpf socket address hooks
-        Linux kernel >= 5.3 for bounded-loops in BPF program
-        Linux kernel >= 5.4 for signed Verity images support
-        Linux kernel >= 5.7 for BPF links and the BPF LSM hook
+        Linux kernel ≥ 3.15
+                     ≥ 4.5 for pids controller in cgroup v2
+                     ≥ 4.6 for cgroup namespaces
+                     ≥ 4.9 for RENAME_NOREPLACE support in vfat
+                     ≥ 4.10 for cgroup-bpf egress and ingress hooks
+                     ≥ 4.15 for cgroup-bpf device hook and cpu controller in cgroup v2
+                     ≥ 4.17 for cgroup-bpf socket address hooks
+                     ≥ 5.3 for bounded loops in BPF program
+                     ≥ 5.4 for signed Verity images
+                     ≥ 5.7 for BPF links and the BPF LSM hook
+
+        Kernel versions below 4.15 have significant gaps in functionality and
+        are not recommended for use with this version of systemd. Taint flag
+        'old-kernel' will be set. Systemd will most likely still function, but
+        upstream support and testing are limited.
 
         Kernel Config Options:
           CONFIG_DEVTMPFS
@@ -330,24 +337,41 @@ SYSV INIT.D SCRIPTS:
         Please see src/systemctl/systemd-sysv-install.SKELETON for how this
         needs to look like, and provide an implementation at the marked places.
 
-WARNINGS:
+WARNINGS and TAINT FLAGS:
         systemd will warn during early boot if /usr is not already mounted at
         this point (that means: either located on the same file system as / or
         already mounted in the initrd). While in systemd itself very little
-        will break if /usr is on a separate, late-mounted partition, many of
-        its dependencies very likely will break sooner or later in one form or
+        will break if /usr is on a separate late-mounted partition, many of its
+        dependencies very likely will break sooner or later in one form or
         another. For example, udev rules tend to refer to binaries in /usr,
         binaries that link to libraries in /usr or binaries that refer to data
         files in /usr. Since these breakages are not always directly visible,
-        systemd will warn about this, since this kind of file system setup is
-        not really supported anymore by the basic set of Linux OS components.
-
-        systemd requires that the /run mount point exists. systemd also
-        requires that /var/run is a symlink to /run.
+        systemd will warn about this. Such setups are not really supported by
+        the basic set of Linux OS components. Taint flag 'split-usr' will be
+        set when this condition is detected.
 
         For more information on this issue consult
         https://www.freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
 
+        systemd requires that the /run mount point exists. systemd also
+        requires that /var/run is a symlink to /run. Taint flag 'var-run-bad'
+        will be set when this condition is detected.
+
+        Systemd will also warn when the cgroup support is unavailable in the
+        kernel (taint flag 'cgroups-missing'), the system is using the old
+        cgroup hierarchy (taint flag 'cgroupsv1'), the hardware clock is
+        running in non-UTC mode (taint flag 'local-hwclock'), the kernel
+        overflow UID or GID are not 65534 (taint flags 'overflowuid-not-65534'
+        and 'overflowgid-not-65534'), the UID or GID range assigned to the
+        running systemd instance covers less than 0…65534 (taint flags
+        'short-uid-range' and 'short-gid-range').
+
+        Taint conditions are logged during boot, but may also be checked at any
+        time with:
+
+          busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager Tainted
+
+VALGRIND:
         To run systemd under valgrind, compile with meson option
         -Dvalgrind=true and have valgrind development headers installed
         (i.e. valgrind-devel or equivalent). Otherwise, false positives will be
index cd3015ca4b4954c9236303c8a43246b9a9ea33b0..64476a5d76f3c99b5e8f881143c22c6bf1a27817 100644 (file)
@@ -4,6 +4,6 @@ custom_target(
         'README',
         input : 'README.in',
         output : 'README',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : conf.get('HAVE_SYSV_COMPAT') == 1,
         install_dir : sysvinit_path)
index 821f176a747a4b010186b065dc19db926e7d5040..ece2c644ff21faac690feb71521e7d6d777a05eb 100644 (file)
@@ -6,6 +6,6 @@ custom_target(
         'locale.conf',
         input : 'locale.conf.in',
         output : 'locale.conf',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : true,
         install_dir : factory_etc_dir)
index 974d6984de32dd6c1ca79ff0e26c3867ba66e419..5ae86aca1801c0f53520e10dc5764d6def78a24d 100644 (file)
       </varlistentry>
 
       <xi:include href="standard-options.xml" xpointer="help" />
+      <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
   </refsect1>
 
index 83b368115b4b552a67669c9ed237520b426abf2c..d9c706b4abab403fd4d9566d2c6f82ae2dea68be 100644 (file)
@@ -30,7 +30,7 @@ custom_entities_ent = custom_target(
         'custom-entities.ent',
         input : 'custom-entities.ent.in',
         output : 'custom-entities.ent',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'])
 
 man_pages = []
 html_pages = []
index 41408411fccb0b70964f2a7fd0f11ec9a8d27f23..e5a3d7a3139dad6bf7bb888f2435ee820d2fadff 100644 (file)
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><constant>v251</constant></term>
+
+          <listitem><para>Since version <constant>v247</constant> we no longer set
+          <varname>ID_NET_NAME_SLOT</varname> if we detect that a PCI device associated with a slot is a PCI
+          bridge as that would create naming conflict when there are more child devices on that bridge. Now,
+          this is relaxed and we will use slot information to generate the name based on it but only if
+          the PCI device has multiple functions. This is safe because distinct function number is a part of
+          the device name for multifunction devices.</para>
+          </listitem>
+        </varlistentry>
+
       </variablelist>
 
     <para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
index 0455d89b78c8c8c682f41d5037027908661d8cdc..4a154850db10c9c552739a0b6da0219e566679ea 100644 (file)
@@ -1826,6 +1826,8 @@ config_h = configure_file(
 
 add_project_arguments('-include', 'config.h', language : 'c')
 
+jinja2_cmdline = [meson_render_jinja2, config_h, version_h]
+
 ############################################################
 
 # binaries that have --help and are intended for use by humans,
@@ -2113,7 +2115,7 @@ endforeach
 
 ############################################################
 
-dbus_programs += executable(
+exe = executable(
         'systemd',
         systemd_sources,
         include_directories : includes,
@@ -2124,6 +2126,8 @@ dbus_programs += executable(
         install_rpath : rootlibexecdir,
         install : true,
         install_dir : rootlibexecdir)
+dbus_programs += exe
+public_programs += exe
 
 meson.add_install_script(meson_make_symlink,
                          rootlibexecdir / 'systemd',
@@ -2680,7 +2684,7 @@ if conf.get('HAVE_LIBCRYPTSETUP') == 1
                 install : true,
                 install_dir : systemgeneratordir)
 
-        executable(
+        public_programs += executable(
                 'systemd-cryptenroll',
                 systemd_cryptenroll_sources,
                 include_directories : includes,
@@ -3115,7 +3119,7 @@ if conf.get('ENABLE_RANDOMSEED') == 1
 endif
 
 if conf.get('ENABLE_FIRSTBOOT') == 1
-        executable(
+        public_programs += executable(
                 'systemd-firstboot',
                 'src/firstboot/firstboot.c',
                 include_directories : includes,
@@ -3605,7 +3609,7 @@ if conf.get('ENABLE_NETWORKD') == 1
                 install : true,
                 install_dir : rootlibexecdir)
 
-        executable(
+        public_programs += executable(
                 'systemd-networkd-wait-online',
                 systemd_networkd_wait_online_sources,
                 include_directories : includes,
@@ -3651,6 +3655,15 @@ executable(
         install : true,
         install_dir : rootlibexecdir)
 
+public_programs += custom_target(
+        'kernel-install',
+        input : kernel_install_in,
+        output : 'kernel-install',
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
+        install : want_kernel_install,
+        install_mode : 'rwxr-xr-x',
+        install_dir : bindir)
+
 ############################################################
 
 runtest_env = custom_target(
@@ -3891,6 +3904,7 @@ endif
 ############################################################
 
 check_help = find_program('tools/check-help.sh')
+check_version = find_program('tools/check-version.sh')
 
 foreach exec : public_programs
         name = exec.full_path().split('/')[-1]
@@ -3899,6 +3913,12 @@ foreach exec : public_programs
                      check_help,
                      args : exec.full_path(),
                      depends: exec)
+
+                test('check-version-' + name,
+                     check_version,
+                     args : [exec.full_path(),
+                             meson.project_version()],
+                     depends: exec)
         endif
 endforeach
 
index e6533e001a5fc484ce40908c4e3e2bb7fbf1783a..f725e14d95d0bd5f8537d8d9835b48ab6949f524 100644 (file)
@@ -51,7 +51,7 @@ foreach file : rules_in
                 file,
                 input : file + '.in',
                 output: file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : true,
                 install_dir : udevrulesdir)
 endforeach
index ae6a61e555415e66e3c0ca28c31555aec074ac47..fb7314348a4aace76c475181f2971b0e81d278d6 100644 (file)
@@ -14,7 +14,7 @@ custom_target(
         'systemctl',
         input : 'systemctl.in',
         output : 'systemctl',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : bashcompletiondir != 'no',
         install_dir : bashcompletiondir)
 
index bac531798cce162bbb0eb21b0ae4201388094c39..b39f933ea4cfa2898a0d37852c6f3d071c98b065 100644 (file)
@@ -9,7 +9,7 @@ custom_target(
         '_systemctl',
         input : '_systemctl.in',
         output : '_systemctl',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : zshcompletiondir != 'no',
         install_dir : zshcompletiondir)
 
index 54a82c7c49a2501df438f5cf49df2797aa863334..0a1ae023a37cf263556e3a879cf760b5e8ae783c 100644 (file)
@@ -74,4 +74,4 @@
 /* Path where systemd-oomd listens for varlink connections from user managers to report changes in ManagedOOM settings. */
 #define VARLINK_ADDR_PATH_MANAGED_OOM_USER "/run/systemd/oom/io.system.ManagedOOM"
 
-#define KERNEL_BASELINE_VERSION "3.15"
+#define KERNEL_BASELINE_VERSION "4.15"
index 6567cdfb280111cf41c3ab432da2ee3114db920c..c6e9e9b0342b54d77ed5fc709f761239bfd238a6 100644 (file)
@@ -1075,9 +1075,8 @@ static int help(void) {
                "  -h --help                      Show this help\n"
                "     --version                   Show version\n"
                "     --test                      Determine initial transaction, dump it and exit\n"
-               "     --system                    In combination with --test: operate as system service manager\n"
-               "     --user                      In combination with --test: operate as per-user service manager\n"
-               "     --no-pager                  Do not pipe output into a pager\n"
+               "     --system                    Combined with --test: operate in system mode\n"
+               "     --user                      Combined with --test: operate in user mode\n"
                "     --dump-configuration-items  Dump understood unit configuration items\n"
                "     --dump-bus-properties       Dump exposed bus properties\n"
                "     --bus-introspect=PATH       Write XML introspection data\n"
@@ -1087,14 +1086,17 @@ static int help(void) {
                "     --crash-reboot[=BOOL]       Reboot on crash\n"
                "     --crash-shell[=BOOL]        Run shell on crash\n"
                "     --confirm-spawn[=BOOL]      Ask for confirmation when spawning processes\n"
-               "     --show-status[=BOOL]        Show status updates on the console during bootup\n"
-               "     --log-target=TARGET         Set log target (console, journal, kmsg, journal-or-kmsg, null)\n"
-               "     --log-level=LEVEL           Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
+               "     --show-status[=BOOL]        Show status updates on the console during boot\n"
+               "     --log-target=TARGET         Set log target (console, journal, kmsg,\n"
+               "                                                 journal-or-kmsg, null)\n"
+               "     --log-level=LEVEL           Set log level (debug, info, notice, warning,\n"
+               "                                                err, crit, alert, emerg)\n"
                "     --log-color[=BOOL]          Highlight important log messages\n"
                "     --log-location[=BOOL]       Include code location in log messages\n"
                "     --log-time[=BOOL]           Prefix log messages with current time\n"
                "     --default-standard-output=  Set default standard output for services\n"
                "     --default-standard-error=   Set default standard error output for services\n"
+               "     --no-pager                  Do not pipe output into a pager\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                ansi_highlight(),
index e92004edf33a4998a2d47f2e6557c041449b7bd8..9d82537407e75f96de3860a2cf04d1f363f85708 100644 (file)
@@ -4384,7 +4384,7 @@ char *manager_taint_string(Manager *m) {
 
         buf = new(char, sizeof("split-usr:"
                                "cgroups-missing:"
-                               "cgrousv1:"
+                               "cgroupsv1:"
                                "local-hwclock:"
                                "var-run-bad:"
                                "overflowuid-not-65534:"
index f5e04b37ca2b90403eff8d43d36a57fb32102f0b..ee2f8774bf36fc639fed375de7f7ce52a34257ff 100644 (file)
@@ -151,7 +151,7 @@ load_fragment_gperf_gperf = custom_target(
         'load-fragment-gperf.gperf',
         input : 'load-fragment-gperf.gperf.in',
         output: 'load-fragment-gperf.gperf',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'])
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'])
 
 load_fragment_gperf_c = custom_target(
         'load-fragment-gperf.c',
@@ -217,7 +217,7 @@ foreach item : in_files
                 file,
                 input : file + '.in',
                 output: file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : (dir == pkgsysconfdir) ? install_sysconfdir_samples : (dir != 'no'),
                 install_dir : dir)
 endforeach
index d28a416e5d48ad6d0a9fe594e2779ed09261d12f..39160182ef5a7681e4a27e4c003c0e9dd6a4c209 100644 (file)
@@ -984,37 +984,37 @@ static int help(void) {
 
         printf("%s [OPTIONS...]\n\n"
                "Configures basic settings of the system.\n\n"
-               "  -h --help                                 Show this help\n"
-               "     --version                              Show package version\n"
-               "     --root=PATH                            Operate on an alternate filesystem root\n"
-               "     --image=PATH                           Operate on an alternate filesystem image\n"
-               "     --locale=LOCALE                        Set primary locale (LANG=)\n"
-               "     --locale-messages=LOCALE               Set message locale (LC_MESSAGES=)\n"
-               "     --keymap=KEYMAP                        Set keymap\n"
-               "     --timezone=TIMEZONE                    Set timezone\n"
-               "     --hostname=NAME                        Set hostname\n"
-               "     --machine-ID=ID                        Set machine ID\n"
-               "     --root-password=PASSWORD               Set root password from plaintext password\n"
-               "     --root-password-file=FILE              Set root password from file\n"
-               "     --root-password-hashed=HASHED_PASSWORD Set root password from hashed password\n"
-               "     --root-shell=SHELL                     Set root shell\n"
-               "     --prompt-locale                        Prompt the user for locale settings\n"
-               "     --prompt-keymap                        Prompt the user for keymap settings\n"
-               "     --prompt-timezone                      Prompt the user for timezone\n"
-               "     --prompt-hostname                      Prompt the user for hostname\n"
-               "     --prompt-root-password                 Prompt the user for root password\n"
-               "     --prompt-root-shell                    Prompt the user for root shell\n"
-               "     --prompt                               Prompt for all of the above\n"
-               "     --copy-locale                          Copy locale from host\n"
-               "     --copy-keymap                          Copy keymap from host\n"
-               "     --copy-timezone                        Copy timezone from host\n"
-               "     --copy-root-password                   Copy root password from host\n"
-               "     --copy-root-shell                      Copy root shell from host\n"
-               "     --copy                                 Copy locale, keymap, timezone, root password\n"
-               "     --setup-machine-id                     Generate a new random machine ID\n"
-               "     --force                                Overwrite existing files\n"
-               "     --delete-root-password                 Delete root password\n"
-               "     --welcome=no                           Disable the welcome text\n"
+               "  -h --help                       Show this help\n"
+               "     --version                    Show package version\n"
+               "     --root=PATH                  Operate on an alternate filesystem root\n"
+               "     --image=PATH                 Operate on an alternate filesystem image\n"
+               "     --locale=LOCALE              Set primary locale (LANG=)\n"
+               "     --locale-messages=LOCALE     Set message locale (LC_MESSAGES=)\n"
+               "     --keymap=KEYMAP              Set keymap\n"
+               "     --timezone=TIMEZONE          Set timezone\n"
+               "     --hostname=NAME              Set hostname\n"
+               "     --machine-ID=ID              Set machine ID\n"
+               "     --root-password=PASSWORD     Set root password from plaintext password\n"
+               "     --root-password-file=FILE    Set root password from file\n"
+               "     --root-password-hashed=HASH  Set root password from hashed password\n"
+               "     --root-shell=SHELL           Set root shell\n"
+               "     --prompt-locale              Prompt the user for locale settings\n"
+               "     --prompt-keymap              Prompt the user for keymap settings\n"
+               "     --prompt-timezone            Prompt the user for timezone\n"
+               "     --prompt-hostname            Prompt the user for hostname\n"
+               "     --prompt-root-password       Prompt the user for root password\n"
+               "     --prompt-root-shell          Prompt the user for root shell\n"
+               "     --prompt                     Prompt for all of the above\n"
+               "     --copy-locale                Copy locale from host\n"
+               "     --copy-keymap                Copy keymap from host\n"
+               "     --copy-timezone              Copy timezone from host\n"
+               "     --copy-root-password         Copy root password from host\n"
+               "     --copy-root-shell            Copy root shell from host\n"
+               "     --copy                       Copy locale, keymap, timezone, root password\n"
+               "     --setup-machine-id           Generate a new random machine ID\n"
+               "     --force                      Overwrite existing files\n"
+               "     --delete-root-password       Delete root password\n"
+               "     --welcome=no                 Disable the welcome text\n"
                "\nSee the %s for details.\n",
                program_invocation_short_name,
                link);
index e70354e44450b2dece82f1c285ef6b5658811b8f..17ac7e4fbe080396b85cad374e9a7a7fe3497cc8 100644 (file)
@@ -73,7 +73,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 0);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "ust:r:h", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "sr:h", options, NULL)) >= 0)
                 switch (c) {
 
                 case 'h':
index 4bbbc1431fd04a624676112c585a0ded37b4a946..f81d906616da8c5cc18fcb1020329e46c2b95565 100644 (file)
@@ -54,7 +54,7 @@ foreach tuple : in_files
                 file,
                 input : file + '.in',
                 output: file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : tuple[1],
                 install_dir : pkgsysconfdir)
 endforeach
similarity index 95%
rename from src/kernel-install/kernel-install
rename to src/kernel-install/kernel-install.in
index a09b998362195a788ef6b6f07cc2973847abb29d..f6d262f5226bc40d17d502ca504b86767d3f948a 100755 (executable)
@@ -23,11 +23,12 @@ skip_remaining=77
 usage()
 {
     echo "Usage:"
-    echo "  $0 [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE ...]"
-    echo "  $0 [OPTIONS...] remove KERNEL-VERSION"
-    echo "  $0 [OPTIONS...] inspect"
+    echo "  kernel-install [OPTIONS...] add KERNEL-VERSION KERNEL-IMAGE [INITRD-FILE...]"
+    echo "  kernel-install [OPTIONS...] remove KERNEL-VERSION"
+    echo "  kernel-install [OPTIONS...] inspect"
     echo "Options:"
-    echo "  -h, --help     Print this help"
+    echo "  -h, --help     Print this help and exit"
+    echo "      --version  Print version string and exit"
     echo "  -v, --verbose  Increase verbosity"
 }
 
@@ -59,6 +60,13 @@ for i; do
     fi
 done
 
+for i; do
+    if [ "$i" = "--version" ]; then
+        echo "kernel-install {{PROJECT_VERSION}} ({{GIT_VERSION}})"
+        exit 0
+    fi
+done
+
 export KERNEL_INSTALL_VERBOSE=0
 if [ "$1" = "--verbose" ] || [ "$1" = "-v" ]; then
     shift
index abc3520b6257d5326adcec18b831f855a9395d08..06c1c3aafb02ea78360ea344f72ea7a39d32a506 100644 (file)
@@ -1,10 +1,8 @@
 # SPDX-License-Identifier: LGPL-2.1-or-later
 
-if want_kernel_install
-        install_data('kernel-install',
-                     install_mode : 'rwxr-xr-x',
-                     install_dir : bindir)
+kernel_install_in = files('kernel-install.in')
 
+if want_kernel_install
         install_data('50-depmod.install',
                      '90-loaderentry.install',
                      install_mode : 'rwxr-xr-x',
index 67b439a5dd56c54838938a4cdbdac46629bc9a90..a86b8f896b633e362b103cfec7d218604b8f0982 100644 (file)
@@ -186,7 +186,7 @@ custom_target(
         'libsystemd.pc',
         input : 'libsystemd.pc.in',
         output : 'libsystemd.pc',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : pkgconfiglibdir != 'no',
         install_dir : pkgconfiglibdir)
 
index 2d51ff7c5837c757857f12aa9a2f9e1e8caeced9..a831391cc1fb93352f67bb4703b4cc82d35a350d 100644 (file)
@@ -38,7 +38,7 @@ custom_target(
         'libudev.pc',
         input : 'libudev.pc.in',
         output : 'libudev.pc',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : pkgconfiglibdir != 'no',
         install_dir : pkgconfiglibdir)
 
index 1a2d738e840de8b8bd32861ff4ff90f60adbf85d..bd350569d56e78f044b472f45191a584f47f53c1 100644 (file)
@@ -80,7 +80,7 @@ foreach tuple : in_files
                 file,
                 input : file + '.in',
                 output: file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : tuple[2] and install,
                 install_dir : dir)
 endforeach
index b2da249c87d05c41d28bf8260ddd861f67fa26e1..e11aefce7acb7418b2fed984ab926e5924a12d92 100644 (file)
@@ -168,7 +168,7 @@ custom_target(
         'resolved.conf',
         input : 'resolved.conf.in',
         output : 'resolved.conf',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : conf.get('ENABLE_RESOLVE') == 1 and install_sysconfdir_samples,
         install_dir : pkgsysconfdir)
 
index 4bfeda8883c4059c666453b98523bf0ba8928362..817665912a9fd8eb2e422a57b929c726256fd111 100644 (file)
@@ -18,7 +18,7 @@ foreach tuple : in_files
                 file,
                 input : file + '.in',
                 output : file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : tuple[1],
                 install_dir : tuple.length() > 2 ? tuple[2] : '',
                 build_by_default : true)
index a2bc4fa55ab2f7fdde1b97e93665ac424fdbfa7c..e95072e048904ab9e56fd18510acbb891972a37a 100644 (file)
@@ -23,6 +23,7 @@ static const NamingScheme naming_schemes[] = {
         { "v247", NAMING_V247 },
         { "v249", NAMING_V249 },
         { "v250", NAMING_V250 },
+        { "v251", NAMING_V251 },
         /* … add more schemes here, as the logic to name devices is updated … */
 
         EXTRA_NET_NAMING_MAP
index 16b304ce10be6f5a09470147c312f71015228209..5303348e063e832474b723b4801843b24452323f 100644 (file)
  * OS versions, but not fully stabilize them. */
 typedef enum NamingSchemeFlags {
         /* First, the individual features */
-        NAMING_SR_IOV_V            = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
-        NAMING_NPAR_ARI            = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
-        NAMING_INFINIBAND          = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
-        NAMING_ZERO_ACPI_INDEX     = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
-        NAMING_ALLOW_RERENAMES     = 1 << 4, /* Allow re-renaming of devices, see #9006 */
-        NAMING_STABLE_VIRTUAL_MACS = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
-        NAMING_NETDEVSIM           = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
-        NAMING_LABEL_NOPREFIX      = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
-        NAMING_NSPAWN_LONG_HASH    = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation  */
-        NAMING_BRIDGE_NO_SLOT      = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
-        NAMING_SLOT_FUNCTION_ID    = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
-        NAMING_16BIT_INDEX         = 1 << 11, /* Allow full 16-bit for the onboard index */
-        NAMING_REPLACE_STRICTLY    = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
-        NAMING_XEN_VIF             = 1 << 13, /* GEnerate names for Xen netfront devices */
+        NAMING_SR_IOV_V                  = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
+        NAMING_NPAR_ARI                  = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
+        NAMING_INFINIBAND                = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
+        NAMING_ZERO_ACPI_INDEX           = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
+        NAMING_ALLOW_RERENAMES           = 1 << 4, /* Allow re-renaming of devices, see #9006 */
+        NAMING_STABLE_VIRTUAL_MACS       = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
+        NAMING_NETDEVSIM                 = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
+        NAMING_LABEL_NOPREFIX            = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
+        NAMING_NSPAWN_LONG_HASH          = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation  */
+        NAMING_BRIDGE_NO_SLOT            = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
+        NAMING_SLOT_FUNCTION_ID          = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
+        NAMING_16BIT_INDEX               = 1 << 11, /* Allow full 16-bit for the onboard index */
+        NAMING_REPLACE_STRICTLY          = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
+        NAMING_XEN_VIF                   = 1 << 13, /* Generate names for Xen netfront devices */
+        NAMING_BRIDGE_MULTIFUNCTION_SLOT = 1 << 14, /* Use PCI hotplug slot information associated with bridge, but only if PCI device is multifunction */
 
         /* And now the masks that combine the features above */
         NAMING_V238 = 0,
@@ -47,6 +48,7 @@ typedef enum NamingSchemeFlags {
         NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
         NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY,
         NAMING_V250 = NAMING_V249 | NAMING_XEN_VIF,
+        NAMING_V251 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
 
         EXTRA_NET_NAMING_SCHEMES
 
index 8ecfbfab828e2e5e89abc0883b7b326e44a92a3e..35467026a84f7086748dfab883d7889e4adb2351 100644 (file)
@@ -39,7 +39,7 @@ custom_target(
         'timesyncd.conf',
         input : 'timesyncd.conf.in',
         output : 'timesyncd.conf',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : conf.get('ENABLE_TIMESYNCD') == 1 and install_sysconfdir_samples,
         install_dir : pkgsysconfdir)
 
index 354b9232914e843e636bba08ee542132ab06f4f9..79964a7d8e9f90d6a254e805b19311857bbd6b3b 100644 (file)
@@ -166,7 +166,7 @@ custom_target(
         'udev.pc',
         input : 'udev.pc.in',
         output : 'udev.pc',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : pkgconfigdatadir != 'no',
         install_dir : pkgconfigdatadir)
 
index 9e4297adaf6ffd71f38a8dd5bbb329f9fe759c90..114fda663ee2139808af516c23251e6a85a2b362 100644 (file)
@@ -451,8 +451,15 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
                                  * devices that will try to claim the same index and that would create name
                                  * collision. */
                                 if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(hotplug_slot_dev)) {
-                                        log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
-                                        return 0;
+                                        if (naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT) && !is_pci_multifunction(names->pcidev)) {
+                                                log_device_debug(dev, "Not using slot information because the PCI device associated with the hotplug slot is a bridge and the PCI device has single function.");
+                                                return 0;
+                                        }
+
+                                        if (!naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT)) {
+                                                log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
+                                                return 0;
+                                        }
                                 }
 
                                 break;
index d9af8bfd203fedd6534c12205b752e435ee765b0..78e8f3018c59558002018fb8813731600c7bbf90 100644 (file)
@@ -966,9 +966,6 @@ static int update_devnode(UdevEvent *event) {
                 if (r < 0 && r != -ENOENT)
                         return log_device_error_errno(dev, r, "Failed to get devnode mode: %m");
         }
-        if (event->mode == MODE_INVALID && gid_is_valid(event->gid) && event->gid > 0)
-                /* If group is set, but mode is not set, "upgrade" mode for the group. */
-                event->mode = 0660;
 
         bool apply_mac = device_for_action(dev, SD_DEVICE_ADD);
 
index c313181041660edd92fed79f95b17a20c23c8130..deacbc31c56ab301d1f18625c8d27a49803591f0 100644 (file)
@@ -13,6 +13,7 @@
 #include "device-private.h"
 #include "device-util.h"
 #include "dirent-util.h"
+#include "escape.h"
 #include "fd-util.h"
 #include "format-util.h"
 #include "fs-util.h"
@@ -590,51 +591,30 @@ int udev_node_remove(sd_device *dev) {
         return 0;
 }
 
-int udev_node_apply_permissions(
-                sd_device *dev,
+static int udev_node_apply_permissions_impl(
+                sd_device *dev, /* can be NULL, only used for logging. */
+                int node_fd,
+                const char *devnode,
                 bool apply_mac,
                 mode_t mode,
                 uid_t uid,
                 gid_t gid,
                 OrderedHashmap *seclabel_list) {
 
-        const char *devnode, *subsystem;
         bool apply_mode, apply_uid, apply_gid;
-        _cleanup_close_ int node_fd = -1;
         struct stat stats;
-        dev_t devnum;
         int r;
 
-        assert(dev);
-
-        r = sd_device_get_devname(dev, &devnode);
-        if (r < 0)
-                return log_device_debug_errno(dev, r, "Failed to get devname: %m");
-        r = sd_device_get_subsystem(dev, &subsystem);
-        if (r < 0)
-                return log_device_debug_errno(dev, r, "Failed to get subsystem: %m");
-        r = sd_device_get_devnum(dev, &devnum);
-        if (r < 0)
-                return log_device_debug_errno(dev, r, "Failed to get devnum: %m");
-
-        if (streq(subsystem, "block"))
-                mode |= S_IFBLK;
-        else
-                mode |= S_IFCHR;
-
-        node_fd = sd_device_open(dev, O_PATH|O_CLOEXEC);
-        if (node_fd < 0) {
-                if (ERRNO_IS_DEVICE_ABSENT(node_fd)) {
-                        log_device_debug_errno(dev, node_fd, "Device node %s is missing, skipping handling.", devnode);
-                        return 0; /* This is necessarily racey, so ignore missing the device */
-                }
-
-                return log_device_debug_errno(dev, node_fd, "Cannot open node %s: %m", devnode);
-        }
+        assert(node_fd >= 0);
+        assert(devnode);
 
         if (fstat(node_fd, &stats) < 0)
                 return log_device_debug_errno(dev, errno, "cannot stat() node %s: %m", devnode);
 
+        /* If group is set, but mode is not set, "upgrade" mode for the group. */
+        if (mode == MODE_INVALID && gid_is_valid(gid) && gid > 0)
+                mode = 0660;
+
         apply_mode = mode != MODE_INVALID && (stats.st_mode & 0777) != (mode & 0777);
         apply_uid = uid_is_valid(uid) && stats.st_uid != uid;
         apply_gid = gid_is_valid(gid) && stats.st_gid != gid;
@@ -708,3 +688,95 @@ int udev_node_apply_permissions(
 
         return 0;
 }
+
+int udev_node_apply_permissions(
+                sd_device *dev,
+                bool apply_mac,
+                mode_t mode,
+                uid_t uid,
+                gid_t gid,
+                OrderedHashmap *seclabel_list) {
+
+        const char *devnode;
+        _cleanup_close_ int node_fd = -1;
+        int r;
+
+        assert(dev);
+
+        r = sd_device_get_devname(dev, &devnode);
+        if (r < 0)
+                return log_device_debug_errno(dev, r, "Failed to get devname: %m");
+
+        node_fd = sd_device_open(dev, O_PATH|O_CLOEXEC);
+        if (node_fd < 0) {
+                if (ERRNO_IS_DEVICE_ABSENT(node_fd)) {
+                        log_device_debug_errno(dev, node_fd, "Device node %s is missing, skipping handling.", devnode);
+                        return 0; /* This is necessarily racey, so ignore missing the device */
+                }
+
+                return log_device_debug_errno(dev, node_fd, "Cannot open node %s: %m", devnode);
+        }
+
+        return udev_node_apply_permissions_impl(dev, node_fd, devnode, apply_mac, mode, uid, gid, seclabel_list);
+}
+
+int static_node_apply_permissions(
+                const char *name,
+                mode_t mode,
+                uid_t uid,
+                gid_t gid,
+                char **tags) {
+
+        _cleanup_free_ char *unescaped_filename = NULL;
+        _cleanup_close_ int node_fd = -1;
+        const char *devnode;
+        struct stat stats;
+        int r;
+
+        assert(name);
+
+        if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID && !tags)
+                return 0;
+
+        devnode = strjoina("/dev/", name);
+
+        node_fd = open(devnode, O_PATH|O_CLOEXEC);
+        if (node_fd < 0) {
+                if (errno != ENOENT)
+                        return log_error_errno(errno, "Failed to open %s: %m", devnode);
+                return 0;
+        }
+
+        if (fstat(node_fd, &stats) < 0)
+                return log_error_errno(errno, "Failed to stat %s: %m", devnode);
+
+        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) {
+                log_warning("%s is neither block nor character device, ignoring.", devnode);
+                return 0;
+        }
+
+        if (!strv_isempty(tags)) {
+                unescaped_filename = xescape(name, "/.");
+                if (!unescaped_filename)
+                        return log_oom();
+        }
+
+        /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
+        STRV_FOREACH(t, tags) {
+                _cleanup_free_ char *p = NULL;
+
+                p = path_join("/run/udev/static_node-tags/", *t, unescaped_filename);
+                if (!p)
+                        return log_oom();
+
+                r = mkdir_parents(p, 0755);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to create parent directory for %s: %m", p);
+
+                r = symlink(devnode, p);
+                if (r < 0 && errno != EEXIST)
+                        return log_error_errno(errno, "Failed to create symlink %s -> %s: %m", p, devnode);
+        }
+
+        return udev_node_apply_permissions_impl(NULL, node_fd, devnode, false, mode, uid, gid, NULL);
+}
index a34af771462897ca7ff3df04207eb3b7b9f2026d..86a829545a533138087cb9f2f3e14d69612f6fab 100644 (file)
@@ -15,6 +15,13 @@ int udev_node_apply_permissions(
                 uid_t uid,
                 gid_t gid,
                 OrderedHashmap *seclabel_list);
+int static_node_apply_permissions(
+                const char *name,
+                mode_t mode,
+                uid_t uid,
+                gid_t gid,
+                char **tags);
+
 int udev_node_remove(sd_device *dev);
 int udev_node_update(sd_device *dev, sd_device *dev_old);
 
index b46cb0f9066981baa9cd4042ca662c919d6fa4b5..1c20775f0826cc68bb9c7cfb2470e9d6e9ae2427 100644 (file)
@@ -9,7 +9,6 @@
 #include "device-private.h"
 #include "device-util.h"
 #include "dirent-util.h"
-#include "escape.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "format-util.h"
@@ -30,6 +29,7 @@
 #include "udev-builtin.h"
 #include "udev-event.h"
 #include "udev-netlink.h"
+#include "udev-node.h"
 #include "udev-rules.h"
 #include "udev-util.h"
 #include "user-util.h"
@@ -2536,72 +2536,6 @@ int udev_rules_apply_to_event(
         return 0;
 }
 
-static int apply_static_dev_perms(const char *devnode, uid_t uid, gid_t gid, mode_t mode, char **tags) {
-        char device_node[UDEV_PATH_SIZE], tags_dir[UDEV_PATH_SIZE], tag_symlink[UDEV_PATH_SIZE];
-        _cleanup_free_ char *unescaped_filename = NULL;
-        struct stat stats;
-        int r;
-
-        assert(devnode);
-
-        if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID && !tags)
-                return 0;
-
-        strscpyl(device_node, sizeof(device_node), "/dev/", devnode, NULL);
-        if (stat(device_node, &stats) < 0) {
-                if (errno != ENOENT)
-                        return log_error_errno(errno, "Failed to stat %s: %m", device_node);
-                return 0;
-        }
-
-        if (!S_ISBLK(stats.st_mode) && !S_ISCHR(stats.st_mode)) {
-                log_warning("%s is neither block nor character device, ignoring.", device_node);
-                return 0;
-        }
-
-        if (!strv_isempty(tags)) {
-                unescaped_filename = xescape(devnode, "/.");
-                if (!unescaped_filename)
-                        return log_oom();
-        }
-
-        /* export the tags to a directory as symlinks, allowing otherwise dead nodes to be tagged */
-        STRV_FOREACH(t, tags) {
-                strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL);
-                r = mkdir_p(tags_dir, 0755);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to create %s: %m", tags_dir);
-
-                strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL);
-                r = symlink(device_node, tag_symlink);
-                if (r < 0 && errno != EEXIST)
-                        return log_error_errno(errno, "Failed to create symlink %s -> %s: %m",
-                                               tag_symlink, device_node);
-        }
-
-        /* don't touch the permissions if only the tags were set */
-        if (uid == UID_INVALID && gid == GID_INVALID && mode == MODE_INVALID)
-                return 0;
-
-        if (mode == MODE_INVALID)
-                mode = gid_is_valid(gid) ? 0660 : 0600;
-        if (!uid_is_valid(uid))
-                uid = 0;
-        if (!gid_is_valid(gid))
-                gid = 0;
-
-        r = chmod_and_chown(device_node, mode, uid, gid);
-        if (r == -ENOENT)
-                return 0;
-        if (r < 0)
-                return log_error_errno(r, "Failed to chown '%s' %u %u: %m", device_node, uid, gid);
-        else
-                log_debug("chown '%s' %u:%u with mode %#o", device_node, uid, gid, mode);
-
-        (void) utimensat(AT_FDCWD, device_node, NULL, 0);
-        return 0;
-}
-
 static int udev_rule_line_apply_static_dev_perms(UdevRuleLine *rule_line) {
         _cleanup_strv_free_ char **tags = NULL;
         uid_t uid = UID_INVALID;
@@ -2626,7 +2560,7 @@ static int udev_rule_line_apply_static_dev_perms(UdevRuleLine *rule_line) {
                         if (r < 0)
                                 return log_oom();
                 } else if (token->type == TK_A_OPTIONS_STATIC_NODE) {
-                        r = apply_static_dev_perms(token->value, uid, gid, mode, tags);
+                        r = static_node_apply_permissions(token->value, mode, uid, gid, tags);
                         if (r < 0)
                                 return r;
                 }
index 3e5d7b356f2072532e6a94ec1690fd7dc0dbe137..951711f1203d0bcee4a2a368ae0667bfcd38759b 100644 (file)
@@ -144,6 +144,7 @@ static int find_devno(
                 const char *device,
                 bool backing) {
 
+        _cleanup_close_ int fd = -1;
         dev_t devt, whole_devt;
         struct stat st;
         int r;
@@ -153,7 +154,11 @@ static int find_devno(
         assert(*devnos || *n_devnos == 0);
         assert(device);
 
-        if (stat(device, &st) < 0)
+        fd = open(device, O_CLOEXEC|O_PATH);
+        if (fd < 0)
+                return log_error_errno(errno, "Failed to open '%s': %m", device);
+
+        if (fstat(fd, &st) < 0)
                 return log_error_errno(errno, "Failed to stat '%s': %m", device);
 
         if (S_ISBLK(st.st_mode))
@@ -166,20 +171,13 @@ static int find_devno(
                 devt = st.st_dev;
         else {
                 _cleanup_close_ int regfd = -1;
-                struct stat st2;
 
                 /* If major(st.st_dev) is zero, this might mean we are backed by btrfs, which needs special
                  * handing, to get the backing device node. */
 
-                regfd = open(device, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+                regfd = fd_reopen(fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
                 if (regfd < 0)
-                        return log_error_errno(errno, "Failed to open '%s': %m", device);
-
-                /* Extra safety: let's check we are still looking at the same file */
-                if (fstat(regfd, &st2) < 0)
-                        return log_error_errno(errno, "Failed to stat '%s': %m", device);
-                if (!stat_inode_same(&st, &st2))
-                        return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "File '%s' was replaced while we were looking at it.", device);
+                        return log_error_errno(regfd, "Failed to open '%s': %m", device);
 
                 r = btrfs_get_block_device_fd(regfd, &devt);
                 if (r == -ENOTTY)
index 4a37a769247465296fa75049a3ec3b366077c790..078cd960b429f17e4a1fa163460934be37e4366b 100644 (file)
@@ -442,6 +442,12 @@ static int device_get_whole_disk(sd_device *dev, sd_device **ret_device, const c
         if (r < 0)
                 return log_device_debug_errno(dev, r, "Failed to get sysname: %m");
 
+        /* Exclude the following devices:
+         * For "dm-", see the comment added by e918a1b5a94f270186dca59156354acd2a596494.
+         * For "md", see the commit message of 2e5b17d01347d3c3118be2b8ad63d20415dbb1f0,
+         * but not sure the assumption is still valid even when partitions are created on the md
+         * devices, surprisingly which seems to be possible, see PR #22973.
+         * For "drbd", see the commit message of fee854ee8ccde0cd28e0f925dea18cce35f3993d. */
         if (STARTSWITH_SET(val, "dm-", "md", "drbd"))
                 goto irrelevant;
 
index eb22358c20530824cf223a9e32e6172c5940665f..bb3c3c5a03b7521bac11a63d31639a5e526a170b 100644 (file)
@@ -4,6 +4,6 @@ custom_target(
         '90-vconsole.rules',
         input : '90-vconsole.rules.in',
         output : '90-vconsole.rules',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : conf.get('ENABLE_VCONSOLE') == 1,
         install_dir : udevrulesdir)
index 1745a13bfbd2bdac81447968b726e5b29200a8e9..ecec903d1bf6f7140f5a6496821deb1a750022cc 100644 (file)
@@ -16,7 +16,7 @@ custom_target(
         '50-coredump.conf',
         input : '50-coredump.conf.in',
         output : '50-coredump.conf',
-        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
         install : conf.get('ENABLE_COREDUMP') == 1,
         install_dir : sysctldir)
 
index 73d507f1f15fb6e10b1d99e11c16d59e8c2999c4..608c4b744a5558ef21ba7e224bf4a70ad7694c36 100644 (file)
@@ -33,7 +33,7 @@ foreach tuple : in_files
                 file,
                 input : file + '.in',
                 output: file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : tuple[1],
                 install_dir : sysusersdir)
 endforeach
index 0a8349fd5b8a0c1c0a067796382dbc50d3dcd3c1..d626e4b641e84d2da8544a29a15380096e386566 100755 (executable)
@@ -1711,7 +1711,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
                                         '25-ip6tnl-tunnel-remote-any.netdev', '25-tunnel-remote-any.network',
                                         '25-veth.netdev', '25-ip6tnl-slaac.network', '25-ipv6-prefix.network',
                                         '25-ip6tnl-tunnel-local-slaac.netdev', '25-ip6tnl-tunnel-local-slaac.network',
-                                        '25-ip6tnl-external.netdev', '26-netdev-link-local-addressing-yes.network')
+                                        '25-ip6tnl-tunnel-external.netdev', '26-netdev-link-local-addressing-yes.network')
         start_networkd()
         self.wait_online(['ip6tnl99:routable', 'ip6tnl98:routable', 'ip6tnl97:routable',
                           'ip6tnl-slaac:degraded', 'ip6tnl-external:degraded',
index b8d3919025910588de4fe7fb31b21c68ad528095..306e066f22603fa5267872b38b2c2e881635ed5e 100644 (file)
@@ -41,7 +41,7 @@ foreach pair : in_files
                         pair[0],
                         input : pair[0] + '.in',
                         output: pair[0],
-                        command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                         install : enable_tmpfiles,
                         install_dir : tmpfilesdir)
         else
index 76ac2926750f9e00c01ecdfcd85e7d064a044ea0..f97429364ecc58de9afe1367e65f4ed8ca374293 100755 (executable)
@@ -3,8 +3,8 @@
 set -eu
 set -o pipefail
 
-# Note: `grep ... >/dev/null` instead of just `grep -q` is used intentionally
-#       here, since `grep -q` exits on the first match causing SIGPIPE being
+# Note: 'grep ... >/dev/null' instead of just 'grep -q' is used intentionally
+#       here, since 'grep -q' exits on the first match causing SIGPIPE being
 #       sent to the sender.
 
 BINARY="${1:?}"
@@ -24,11 +24,11 @@ fi
 
 # --help prints something. Also catches case where args are ignored.
 if ! "$BINARY" --help | grep . >/dev/null; then
-    echo "$(basename "$BINARY") --help output is empty."
+    echo "$(basename "$BINARY") --help output is empty"
     exit 2
 fi
 
-# no --help output to stdout
+# no --help output to stderr
 if "$BINARY" --help 2>&1 1>/dev/null | grep .; then
     echo "$(basename "$BINARY") --help prints to stderr"
     exit 3
@@ -39,3 +39,9 @@ if ! ("$BINARY" --no-such-parameter 2>&1 1>/dev/null || :) | grep . >/dev/null;
     echo "$(basename "$BINARY") with an unknown parameter does not print to stderr"
     exit 4
 fi
+
+# --help and -h are equivalent
+if ! diff <("$BINARY" -h) <("$BINARY" --help); then
+    echo "$(basename "$BINARY") --help and -h are not identical"
+    exit 5
+fi
diff --git a/tools/check-version.sh b/tools/check-version.sh
new file mode 100755 (executable)
index 0000000..faefb46
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env bash
+# SPDX-License-Identifier: LGPL-2.1-or-later
+set -eu
+set -o pipefail
+
+# Note: 'grep ... >/dev/null' instead of just 'grep -q' is used intentionally
+#       here, since 'grep -q' exits on the first match causing SIGPIPE being
+#       sent to the sender.
+
+BINARY="${1:?}"
+VERSION="${2:?}"
+export SYSTEMD_LOG_LEVEL=info
+
+if [[ ! -x "$BINARY" ]]; then
+    echo "$BINARY is not an executable"
+    exit 1
+fi
+
+# --version prints something. Also catches case where args are ignored.
+if ! "$BINARY" --version | grep . >/dev/null; then
+    echo "$(basename "$BINARY") --version output is empty"
+    exit 2
+fi
+
+# no --version output to stderr
+if "$BINARY" --version 2>&1 1>/dev/null | grep .; then
+    echo "$(basename "$BINARY") --version prints to stderr"
+    exit 3
+fi
+
+# project version appears in version output
+out="$("$BINARY" --version)"
+if ! grep -F "$VERSION" >/dev/null <<<"$out"; then
+    echo "$(basename "$BINARY") --version output does not match '$VERSION': $out"
+    exit 4
+fi
index 89735c70ed26d6c89b604f157659a7c5f09f2559..fbaae596de6b651978558ad21f2ef5c27abace87 100755 (executable)
@@ -28,9 +28,10 @@ def render(filename, defines):
 
 if __name__ == '__main__':
     defines = parse_config_h(sys.argv[1])
-    output = render(sys.argv[2], defines)
-    with open(sys.argv[3], 'w') as f:
+    defines.update(parse_config_h(sys.argv[2]))
+    output = render(sys.argv[3], defines)
+    with open(sys.argv[4], 'w') as f:
         f.write(output)
         f.write('\n')
-    info = os.stat(sys.argv[2])
-    os.chmod(sys.argv[3], info.st_mode)
+    info = os.stat(sys.argv[3])
+    os.chmod(sys.argv[4], info.st_mode)
index 8a3bd0da51281f758893589e23a3be572b0e89c0..e8f81f22302f57186ec419e61efd1db255b3f50b 100644 (file)
@@ -276,7 +276,7 @@ foreach tuple : in_units
                 file,
                 input : file + '.in',
                 output : file,
-                command : [meson_render_jinja2, config_h, '@INPUT@', '@OUTPUT@'],
+                command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
                 install : install,
                 install_dir : systemunitdir)