]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #31243 from YHNdnzj/systemctl-disable-now-template
authorLuca Boccassi <bluca@debian.org>
Fri, 9 Feb 2024 14:29:50 +0000 (14:29 +0000)
committerGitHub <noreply@github.com>
Fri, 9 Feb 2024 14:29:50 +0000 (14:29 +0000)
systemctl: support disable/mask --now with unit template

25 files changed:
.packit.yml
.semaphore/semaphore-runner.sh
README.md
man/kernel-command-line.xml
man/systemd-cryptenroll.xml
man/systemd-debug-generator.xml
man/systemd.network.xml
mkosi.images/system/mkosi.conf.d/10-arch.conf
src/basic/process-util.c
src/basic/process-util.h
src/debug-generator/debug-generator.c
src/libsystemd/sd-bus/bus-common-errors.c
src/libsystemd/sd-bus/bus-common-errors.h
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-manager-bus.c
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-setlink.c
src/sysext/sysext.c
src/test/test-path.c
src/test/test-seccomp.c
test/test-network/systemd-networkd-tests.py
test/units/testsuite-74.networkctl.sh
test/units/testsuite-81.debug-generator.sh

index 2dcc9e86ca448483d84bf1f80ea160bd8a569802..fa86c5fa05e5bf95a7ce6f9605316630b1ac1cb8 100644 (file)
@@ -44,6 +44,10 @@ actions:
     # Temporarily add libarchive-devel build dep and libarchive runtime dep
     # until the change propagates to Rawhide's specfile
     - "sed -ri '0,/^BuildRequires: .+$/s//&\\nBuildRequires: libarchive-devel\\nRequires: libarchive/' .packit_rpm/systemd.spec"
+    # FIXME: temporarily build without BPF stuff, since there's currently no
+    #        bpftool package in Rawhide (at least not until [0] lands)
+    # [0] https://bodhi.fedoraproject.org/updates/FEDORA-2024-bb73636f1d
+    - "sed -nri '1N;2N;/\\nBuildRequires:\\s+bpftool$/{N;N;d};P;N;D' .packit_rpm/systemd.spec"
 
 jobs:
 - job: copr_build
index 13456609ad04370e73ab12e13a14c47a682d2ee3..521917257001f7382adbb0d420ed834ae10d2d1d 100755 (executable)
@@ -63,7 +63,7 @@ for phase in "${PHASES[@]}"; do
             sudo apt-get install -y -t "$UBUNTU_RELEASE-backports" lxc
             sudo apt-get install -y python3-debian git dpkg-dev fakeroot python3-jinja2
 
-            [ -d "$AUTOPKGTEST_DIR" ] || git clone --quiet --depth=1 https://salsa.debian.org/ci-team/autopkgtest.git "$AUTOPKGTEST_DIR"
+            [ -d "$AUTOPKGTEST_DIR" ] || git clone --quiet --branch=debian/5.32 --depth=1 https://salsa.debian.org/ci-team/autopkgtest.git "$AUTOPKGTEST_DIR"
 
             create_container
         ;;
index c0e6310d9b45320a4394099448ff671b1bd6946c..c4522a2bac635b07cc790dda5c5eea58588aa717 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ System and Service Manager
 [![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/systemd.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#systemd)<br/>
 [![CIFuzz](https://github.com/systemd/systemd/workflows/CIFuzz/badge.svg)](https://github.com/systemd/systemd/actions)<br/>
 [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1369/badge)](https://bestpractices.coreinfrastructure.org/projects/1369)<br/>
-[![CentOS CI - CentOS 8](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20CentOS%208&job=upstream-centos8)](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/job/upstream-centos8/)<br/>
+[![CentOS CI - CentOS 9](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20CentOS%209&job=upstream-centos9s)](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/job/upstream-centos9s/)<br/>
 [![CentOS CI - Arch](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20Arch&job=upstream-vagrant-archlinux)](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/job/upstream-vagrant-archlinux/)<br/>
 [![CentOS CI - Arch (sanitizers)](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/buildStatus/icon?subject=CentOS%20CI%20-%20Arch%20(sanitizers)&job=upstream-vagrant-archlinux-sanitizers)](https://jenkins-systemd.apps.ocp.cloud.ci.centos.org/job/upstream-vagrant-archlinux-sanitizers/)<br/>
 [![Fossies codespell report](https://fossies.org/linux/test/systemd-main.tar.gz/codespell.svg)](https://fossies.org/linux/test/systemd-main.tar.gz/codespell.html)</br>
index 8f179deec83d39a75e22c63ce89d8727ec231a2f..d4b005f8769f581f458ceb8e6b634f066e2a4172 100644 (file)
@@ -86,6 +86,7 @@
         <term><varname>systemd.mask=</varname></term>
         <term><varname>systemd.wants=</varname></term>
         <term><varname>systemd.debug_shell</varname></term>
+        <term><varname>systemd.default_debug_tty=</varname></term>
         <listitem>
           <para>Additional parameters understood by
           <citerefentry><refentrytitle>systemd-debug-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
index 95f5a450b6d5a8436468f9cde3c3bea8ebaa70cc..dfc6d31cf4b2e07202c9407a51d2c77ab478cfec 100644 (file)
       <varlistentry>
         <term><option>--unlock-tpm2-device=</option><replaceable>PATH</replaceable></term>
 
-        <listitem><para>Use a TPM2 device insteaad of a password/passhprase read from stdin to unlock the
+        <listitem><para>Use a TPM2 device instead of a password/passhprase read from stdin to unlock the
         volume. Expects a device node path referring to the TPM2 chip (e.g. <filename>/dev/tpmrm0</filename>).
         Alternatively the special value <literal>auto</literal> may be specified, in order to automatically
         determine the device node of a currently discovered TPM2 device (of which there must be exactly one).
index 5d2dbe2cd5f284a0ed613e19bb707a50973e306f..2f27f0fe4eeb304e0a960064bd83ce170a57eb9d 100644 (file)
     RAM disk (initrd) while <option>systemd.wants=</option> is
     honored only in the main system.</para>
 
-    <para>If the <option>systemd.debug_shell</option> or
-    <option>rd.systemd.debug_shell</option> option is
-    specified, the debug shell service
-    <literal>debug-shell.service</literal> is pulled into the boot
-    transaction and a debug shell will be spawned during early boot.
-    By default, <filename>&DEBUGTTY;</filename> is used, but a specific tty can also be set,
-    either with or without the <filename>/dev/</filename> prefix.
-    Note that the shell may also be turned on persistently by enabling it with
-    <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
-    <command>enable</command> command.
-    <option>rd.systemd.debug_shell=</option> is honored only by initial
-    RAM disk (initrd) while <option>systemd.debug_shell</option> is
-    honored only in the main system.</para>
+    <para>If the <option>systemd.debug_shell</option> or <option>rd.systemd.debug_shell</option> option is
+    specified, the debug shell service <literal>debug-shell.service</literal> is pulled into the boot
+    transaction and a debug shell will be spawned during early boot. By default,
+    <filename>&DEBUGTTY;</filename> is used, but a specific tty can also be specified, either with or without
+    the <filename>/dev/</filename> prefix. To set the tty to use without enabling the debug shell, the
+    <option>systemd.default_debug_tty=</option> option can be used which also takes a tty with or without the
+    <filename>/dev/</filename> prefix. Note that the shell may also be turned on persistently by enabling it
+    with <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+    <command>enable</command> command. <option>rd.systemd.debug_shell=</option> is honored only by initial
+    RAM disk (initrd) while <option>systemd.debug_shell</option> is honored only in the main system.</para>
 
     <para><filename>systemd-debug-generator</filename> implements
     <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
index cf4456ef0ccbce2f1bd925200de8b5a12b87ba45..b739e709f53dcc507778649ec5219099e97ec179 100644 (file)
@@ -2341,7 +2341,7 @@ NFTSet=prefix:netdev:filter:eth_ipv4_prefix</programlisting>
           are implied and these settings in the .network file are silently ignored. Also,
           <varname>Hostname=</varname>,
           <varname>MUDURL=</varname>,
-          <varname>RequestAddress</varname>,
+          <varname>RequestAddress=</varname>,
           <varname>RequestOptions=</varname>,
           <varname>SendOption=</varname>,
           <varname>SendVendorOption=</varname>,
index 0b15677ff29d3bd8d9fd8063e7332b92ea3d00fd..e1a511c9792153ee92e3467d316aec8293780c5d 100644 (file)
@@ -16,6 +16,7 @@ Packages=
         man-db
         openbsd-netcat
         openssh
+        pacman
         polkit
         python-pefile
         python-psutil
index a94ff3840915a95bb07410fb458500e858bc9054..002aea9e8aaf0f38f5a066bb94ac09ba67311239 100644 (file)
@@ -1303,7 +1303,7 @@ int opinionated_personality(unsigned long *ret) {
         if (current < 0)
                 return current;
 
-        if (((unsigned long) current & 0xffff) == PER_LINUX32)
+        if (((unsigned long) current & OPINIONATED_PERSONALITY_MASK) == PER_LINUX32)
                 *ret = PER_LINUX32;
         else
                 *ret = PER_LINUX;
index 0fc31f7086ae230d01ebf1fd96ee347e4a30a779..9ca67533349775794aa361c7cb65a54b22bc556d 100644 (file)
@@ -101,12 +101,17 @@ bool is_main_thread(void);
 bool oom_score_adjust_is_valid(int oa);
 
 #ifndef PERSONALITY_INVALID
-/* personality(7) documents that 0xffffffffUL is used for querying the
+/* personality(2) documents that 0xFFFFFFFFUL is used for querying the
  * current personality, hence let's use that here as error
  * indicator. */
-#define PERSONALITY_INVALID 0xffffffffLU
+#define PERSONALITY_INVALID 0xFFFFFFFFUL
 #endif
 
+/* The personality() syscall returns a 32-bit value where the top three bytes are reserved for flags that
+ * emulate historical or architectural quirks, and only the least significant byte reflects the actual
+ * personality we're interested in. */
+#define OPINIONATED_PERSONALITY_MASK 0xFFUL
+
 unsigned long personality_from_string(const char *p);
 const char *personality_to_string(unsigned long);
 
index 8a474c58cfa4e738a525e708ae1423ce6dd7e715..741b59f32024b3fd720d9eee74b090d6c9df74ee 100644 (file)
@@ -20,12 +20,15 @@ static const char *arg_dest = NULL;
 static char *arg_default_unit = NULL;
 static char **arg_mask = NULL;
 static char **arg_wants = NULL;
-static char *arg_debug_shell = NULL;
+static bool arg_debug_shell = false;
+static char *arg_debug_tty = NULL;
+static char *arg_default_debug_tty = NULL;
 
 STATIC_DESTRUCTOR_REGISTER(arg_default_unit, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_mask, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_wants, strv_freep);
-STATIC_DESTRUCTOR_REGISTER(arg_debug_shell, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_debug_tty, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_default_debug_tty, freep);
 
 static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
         int r;
@@ -61,15 +64,18 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                         return log_oom();
 
         } else if (proc_cmdline_key_streq(key, "systemd.debug_shell")) {
-                const char *t = NULL;
-
                 r = value ? parse_boolean(value) : 1;
-                if (r < 0)
-                        t = skip_dev_prefix(value);
-                else if (r > 0)
-                        t = skip_dev_prefix(DEBUGTTY);
+                arg_debug_shell = r != 0;
+                if (r >= 0)
+                        return 0;
+
+                return free_and_strdup_warn(&arg_debug_tty, skip_dev_prefix(value));
+
+        } else if (proc_cmdline_key_streq(key, "systemd.default_debug_tty")) {
+                if (proc_cmdline_value_missing(key, value))
+                        return 0;
 
-                return free_and_strdup_warn(&arg_debug_shell, t);
+                return free_and_strdup_warn(&arg_default_debug_tty, skip_dev_prefix(value));
 
         } else if (streq(key, "systemd.unit")) {
 
@@ -136,9 +142,10 @@ static int generate_wants_symlinks(void) {
 }
 
 static void install_debug_shell_dropin(const char *dir) {
+        const char *tty = arg_debug_tty ?: arg_default_debug_tty;
         int r;
 
-        if (streq(arg_debug_shell, skip_dev_prefix(DEBUGTTY)))
+        if (!tty || path_equal(tty, skip_dev_prefix(DEBUGTTY)))
                 return;
 
         r = write_drop_in_format(dir, "debug-shell.service", 50, "tty",
@@ -147,7 +154,7 @@ static void install_debug_shell_dropin(const char *dir) {
                         "ConditionPathExists=\n"
                         "[Service]\n"
                         "TTYPath=/dev/%s",
-                        arg_debug_shell, arg_debug_shell);
+                        tty, tty);
         if (r < 0)
                 log_warning_errno(r, "Failed to write drop-in for debug-shell.service, ignoring: %m");
 }
index df26fd75cd19a453d09a49113a61ad5d06e27664..efdd6539ccebd017523f92d2b18878870ab64112 100644 (file)
@@ -110,6 +110,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
 
         SD_BUS_ERROR_MAP(BUS_ERROR_SPEED_METER_INACTIVE,         EOPNOTSUPP),
         SD_BUS_ERROR_MAP(BUS_ERROR_UNMANAGED_INTERFACE,          EOPNOTSUPP),
+        SD_BUS_ERROR_MAP(BUS_ERROR_NETWORK_ALREADY_RELOADING,    EBUSY),
 
         SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_HOME,                 EEXIST),
         SD_BUS_ERROR_MAP(BUS_ERROR_UID_IN_USE,                   EEXIST),
index 3a0eef49ef57b93d6c99a4037bd0b2d90c30b7db..2961ee4a9ecaba87902803cdba114752e8585045 100644 (file)
 
 #define BUS_ERROR_SPEED_METER_INACTIVE         "org.freedesktop.network1.SpeedMeterInactive"
 #define BUS_ERROR_UNMANAGED_INTERFACE          "org.freedesktop.network1.UnmanagedInterface"
+#define BUS_ERROR_NETWORK_ALREADY_RELOADING    "org.freedesktop.network1.AlreadyReloading"
 
 #define BUS_ERROR_NO_SUCH_HOME                 "org.freedesktop.home1.NoSuchHome"
 #define BUS_ERROR_UID_IN_USE                   "org.freedesktop.home1.UIDInUse"
index 621f8592061d6c2f5ab4f82e5d1b7dddfb9e67df..c0d0f83ca30f9317884932cf70dfccbc2159371b 100644 (file)
@@ -1463,6 +1463,80 @@ int link_reconfigure(Link *link, bool force) {
         return 1; /* 1 means the interface will be reconfigured. */
 }
 
+typedef struct ReconfigureData {
+        Link *link;
+        Manager *manager;
+        sd_bus_message *message;
+} ReconfigureData;
+
+static void reconfigure_data_destroy_callback(ReconfigureData *data) {
+        int r;
+
+        assert(data);
+        assert(data->link);
+        assert(data->manager);
+        assert(data->manager->reloading > 0);
+        assert(data->message);
+
+        link_unref(data->link);
+
+        data->manager->reloading--;
+        if (data->manager->reloading <= 0) {
+                r = sd_bus_reply_method_return(data->message, NULL);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to send reply for 'Reload' DBus method, ignoring: %m");
+        }
+
+        sd_bus_message_unref(data->message);
+        free(data);
+}
+
+static int reconfigure_handler_on_bus_method_reload(sd_netlink *rtnl, sd_netlink_message *m, ReconfigureData *data) {
+        assert(data);
+        assert(data->link);
+        return link_reconfigure_handler_internal(rtnl, m, data->link, /* force = */ false);
+}
+
+int link_reconfigure_on_bus_method_reload(Link *link, sd_bus_message *message) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        _cleanup_free_ ReconfigureData *data = NULL;
+        int r;
+
+        assert(link);
+        assert(link->manager);
+        assert(link->manager->rtnl);
+        assert(message);
+
+        /* See comments in link_reconfigure() above. */
+        if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_INITIALIZED, LINK_STATE_LINGER))
+                return 0;
+
+        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK, link->ifindex);
+        if (r < 0)
+                return r;
+
+        data = new(ReconfigureData, 1);
+        if (!data)
+                return -ENOMEM;
+
+        r = netlink_call_async(link->manager->rtnl, NULL, req,
+                               reconfigure_handler_on_bus_method_reload,
+                               reconfigure_data_destroy_callback, data);
+        if (r < 0)
+                return r;
+
+        *data = (ReconfigureData) {
+                .link = link_ref(link),
+                .manager = link->manager,
+                .message = sd_bus_message_ref(message),
+        };
+
+        link->manager->reloading++;
+
+        TAKE_PTR(data);
+        return 0;
+}
+
 static int link_initialized_and_synced(Link *link) {
         int r;
 
index d81b45bd643e5319d5fc4c35524912a659b11dc1..0167b1988d3ca535e69ef525cfdc7e384d2302ed 100644 (file)
@@ -252,6 +252,7 @@ LinkState link_state_from_string(const char *s) _pure_;
 
 int link_reconfigure_impl(Link *link, bool force);
 int link_reconfigure(Link *link, bool force);
+int link_reconfigure_on_bus_method_reload(Link *link, sd_bus_message *message);
 
 int manager_udev_process_link(Manager *m, sd_device *device, sd_device_action_t action);
 int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
index 035537c869aa73ca33ecd94e060bc5fa250ee955..3c3d815a4afa6a98e5577ebdf6e702f4873d8b07 100644 (file)
@@ -198,9 +198,12 @@ static int bus_method_reconfigure_link(sd_bus_message *message, void *userdata,
 }
 
 static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
-        Manager *manager = userdata;
+        Manager *manager = ASSERT_PTR(userdata);
         int r;
 
+        if (manager->reloading > 0)
+                return sd_bus_error_set(error, BUS_ERROR_NETWORK_ALREADY_RELOADING, "Already reloading.");
+
         r = bus_verify_polkit_async(
                         message,
                         "org.freedesktop.network1.reload",
@@ -212,10 +215,13 @@ static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_err
         if (r == 0)
                 return 1; /* Polkit will call us back */
 
-        r = manager_reload(manager);
+        r = manager_reload(manager, message);
         if (r < 0)
                 return r;
 
+        if (manager->reloading > 0)
+                return 1; /* Will reply later. */
+
         return sd_bus_reply_method_return(message, NULL);
 }
 
index 6f3d90d64c9debe56a4637a61d9fa97051784aad..42c6371be5b18cbc98607f4242ad31f2a92424ef 100644 (file)
@@ -453,7 +453,7 @@ static int signal_restart_callback(sd_event_source *s, const struct signalfd_sig
 static int signal_reload_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
         Manager *m = ASSERT_PTR(userdata);
 
-        manager_reload(m);
+        (void) manager_reload(m, /* message = */ NULL);
 
         return 0;
 }
@@ -1085,7 +1085,7 @@ int manager_set_timezone(Manager *m, const char *tz) {
         return 0;
 }
 
-int manager_reload(Manager *m) {
+int manager_reload(Manager *m, sd_bus_message *message) {
         Link *link;
         int r;
 
@@ -1105,9 +1105,14 @@ int manager_reload(Manager *m) {
                 goto finish;
 
         HASHMAP_FOREACH(link, m->links_by_index) {
-                r = link_reconfigure(link, /* force = */ false);
-                if (r < 0)
-                        goto finish;
+                if (message)
+                        r = link_reconfigure_on_bus_method_reload(link, message);
+                else
+                        r = link_reconfigure(link, /* force = */ false);
+                if (r < 0) {
+                        log_link_warning_errno(link, r, "Failed to reconfigure the interface: %m");
+                        link_enter_failed(link);
+                }
         }
 
         r = 0;
index a97ae8ea213e67149a0d902cab6a2381a40b847d..7788ce7d6f0835cf16775bf4f05de7f679db0062 100644 (file)
@@ -105,6 +105,8 @@ struct Manager {
         OrderedSet *remove_request_queue;
 
         Hashmap *tuntap_fds_by_name;
+
+        unsigned reloading;
 };
 
 int manager_new(Manager **ret, bool test_mode);
@@ -125,6 +127,6 @@ int manager_enumerate(Manager *m);
 int manager_set_hostname(Manager *m, const char *hostname);
 int manager_set_timezone(Manager *m, const char *timezone);
 
-int manager_reload(Manager *m);
+int manager_reload(Manager *m, sd_bus_message *message);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
index 38f90969ec498dffcf9a0c6d337efb25d7594f6b..eb65429a783ff0b6d31b5931baf8cbb1dc5d7f78 100644 (file)
@@ -486,7 +486,7 @@ static int link_is_ready_to_set_link(Link *link, Request *req) {
                 return link->bridge_vlan_set;
 
         case REQUEST_TYPE_SET_LINK_CAN:
-                /* Do not check link->set_flgas_messages here, as it is ok even if link->flags
+                /* Do not check link->set_flags_messages here, as it is ok even if link->flags
                  * is outdated, and checking the counter causes a deadlock. */
                 if (FLAGS_SET(link->flags, IFF_UP)) {
                         /* The CAN interface must be down to configure bitrate, etc... */
@@ -532,15 +532,6 @@ static int link_is_ready_to_set_link(Link *link, Request *req) {
                         if (!netdev_is_ready(link->network->bond))
                                 return false;
                         m = link->network->bond->ifindex;
-
-                        /* Do not check link->set_flgas_messages here, as it is ok even if link->flags
-                         * is outdated, and checking the counter causes a deadlock. */
-                        if (FLAGS_SET(link->flags, IFF_UP)) {
-                                /* link must be down when joining to bond master. */
-                                r = link_down_now(link);
-                                if (r < 0)
-                                        return r;
-                        }
                 } else if (link->network->bridge) {
                         if (ordered_set_contains(link->manager->request_queue, &req_mac))
                                 return false;
@@ -559,6 +550,15 @@ static int link_is_ready_to_set_link(Link *link, Request *req) {
                         return -EALREADY; /* indicate to cancel the request. */
                 }
 
+                /* Do not check link->set_flags_messages here, as it is ok even if link->flags is outdated,
+                 * and checking the counter causes a deadlock. */
+                if (link->network->bond && FLAGS_SET(link->flags, IFF_UP)) {
+                        /* link must be down when joining to bond master. */
+                        r = link_down_now(link);
+                        if (r < 0)
+                                return r;
+                }
+
                 req->userdata = UINT32_TO_PTR(m);
                 break;
         }
@@ -1046,6 +1046,8 @@ static int link_up_or_down(Link *link, bool up, Request *req) {
         assert(link->manager->rtnl);
         assert(req);
 
+        /* The log message is checked in the test. Please also update test_bond_active_slave() in
+         * test/test-network/systemd-networkd-tests.py. when the log message below is modified. */
         log_link_debug(link, "Bringing link %s", up_or_down(up));
 
         r = sd_rtnl_message_new_link(link->manager->rtnl, &m, RTM_SETLINK, link->ifindex);
index 49cedcc24bfe52896dee83a2d47c1bbfbc07357f..6c1bfdb77e19d320010de61124b17eb0448186b5 100644 (file)
@@ -68,10 +68,12 @@ STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
 
 /* Helper struct for naming simplicity and reusability */
 static const struct {
-        const char *dot_directory_name;
-        const char *directory_name;
+        const char *full_identifier;
         const char *short_identifier;
         const char *short_identifier_plural;
+        const char *blurb;
+        const char *dot_directory_name;
+        const char *directory_name;
         const char *level_env;
         const char *scope_env;
         const char *name_env;
@@ -79,10 +81,11 @@ static const struct {
         unsigned long default_mount_flags;
 } image_class_info[_IMAGE_CLASS_MAX] = {
         [IMAGE_SYSEXT] = {
-                .dot_directory_name = ".systemd-sysext",
-                .directory_name = "systemd-sysext",
+                .full_identifier = "systemd-sysext",
                 .short_identifier = "sysext",
                 .short_identifier_plural = "extensions",
+                .blurb = "Merge system extension images into /usr/ and /opt/.",
+                .dot_directory_name = ".systemd-sysext",
                 .level_env = "SYSEXT_LEVEL",
                 .scope_env = "SYSEXT_SCOPE",
                 .name_env = "SYSTEMD_SYSEXT_HIERARCHIES",
@@ -90,10 +93,11 @@ static const struct {
                 .default_mount_flags = MS_RDONLY|MS_NODEV,
         },
         [IMAGE_CONFEXT] = {
-                .dot_directory_name = ".systemd-confext",
-                .directory_name = "systemd-confext",
+                .full_identifier = "systemd-confext",
                 .short_identifier = "confext",
                 .short_identifier_plural = "confexts",
+                .blurb = "Merge configuration extension images into /etc/.",
+                .dot_directory_name = ".systemd-confext",
                 .level_env = "CONFEXT_LEVEL",
                 .scope_env = "CONFEXT_SCOPE",
                 .name_env = "SYSTEMD_CONFEXT_HIERARCHIES",
@@ -1366,13 +1370,13 @@ static int verb_help(int argc, char **argv, void *userdata) {
         _cleanup_free_ char *link = NULL;
         int r;
 
-        r = terminal_urlify_man("systemd-sysext", "8", &link);
+        r = terminal_urlify_man(image_class_info[arg_image_class].full_identifier, "8", &link);
         if (r < 0)
                 return log_oom();
 
         printf("%1$s [OPTIONS...] COMMAND\n"
-                "\n%5$sMerge extension images into /usr/ and /opt/ hierarchies for\n"
-               " sysext and into the /etc/ hierarchy for confext.%6$s\n"
+               "\n%5$s%7$s%6$s\n"
+               "\n%3$sCommands:%4$s\n"
                "  status                  Show current merge status (default)\n"
                "  merge                   Merge extensions into relevant hierarchies\n"
                "  unmerge                 Unmerge extensions from relevant hierarchies\n"
@@ -1397,7 +1401,8 @@ static int verb_help(int argc, char **argv, void *userdata) {
                ansi_underline(),
                ansi_normal(),
                ansi_highlight(),
-               ansi_normal());
+               ansi_normal(),
+               image_class_info[arg_image_class].blurb);
 
         return 0;
 }
index 22ed88f7e716789166c1c6e94e7275373f18348d..e49653a2404b3173cd085dc00ecae0fc82c70db6 100644 (file)
@@ -100,7 +100,8 @@ static int _check_states(unsigned line,
                          service_state_to_string(service->state),
                          service_result_to_string(service->result));
 
-                if (service->state == SERVICE_FAILED && service->main_exec_status.status == EXIT_CGROUP) {
+                if (service->state == SERVICE_FAILED &&
+                    (service->main_exec_status.status == EXIT_CGROUP || service->result == SERVICE_FAILURE_RESOURCES)) {
                         const char *ci = ci_environment();
 
                         /* On a general purpose system we may fail to start the service for reasons which are
index 279a155cb0a98e4be33d13496ab6d3a56c8ac377..4d3021cf9bd8b73ad02d83069231747b5fd7890c 100644 (file)
@@ -937,7 +937,7 @@ TEST(native_syscalls_filtered) {
 }
 
 TEST(lock_personality) {
-        unsigned long current;
+        unsigned long current_opinionated;
         pid_t pid;
 
         if (!is_seccomp_available()) {
@@ -949,24 +949,21 @@ TEST(lock_personality) {
                 return;
         }
 
-        assert_se(opinionated_personality(&current) >= 0);
-        /* On ppc64le sanitizers disable ASLR (i.e. by setting ADDR_NO_RANDOMIZE),
-         * which opinionated_personality() doesn't return. Let's tweak the current
-         * personality ourselves in such cases.
-         * See: https://github.com/llvm/llvm-project/commit/78f7a6eaa601bfdd6ae70ffd3da2254c21ff77f9
-         */
-        if (FLAGS_SET(safe_personality(PERSONALITY_INVALID), ADDR_NO_RANDOMIZE))
-                current |= ADDR_NO_RANDOMIZE;
+        assert_se(opinionated_personality(&current_opinionated) >= 0);
 
-        log_info("current personality=0x%lX", current);
+        log_info("current personality=0x%lX", (unsigned long) safe_personality(PERSONALITY_INVALID));
+        log_info("current opinionated personality=0x%lX", current_opinionated);
 
         pid = fork();
         assert_se(pid >= 0);
 
         if (pid == 0) {
-                assert_se(seccomp_lock_personality(current) >= 0);
+                unsigned long current;
 
-                assert_se((unsigned long) safe_personality(current) == current);
+                assert_se(seccomp_lock_personality(current_opinionated) >= 0);
+
+                current = safe_personality(current_opinionated);
+                assert_se((current & OPINIONATED_PERSONALITY_MASK) == current_opinionated);
 
                 /* Note, we also test that safe_personality() works correctly, by checking whether errno is properly
                  * set, in addition to the return value */
@@ -981,14 +978,15 @@ TEST(lock_personality) {
                 assert_se(safe_personality(PER_LINUX_32BIT) == -EPERM);
                 assert_se(safe_personality(PER_SVR4) == -EPERM);
                 assert_se(safe_personality(PER_BSD) == -EPERM);
-                assert_se(safe_personality(current == PER_LINUX ? PER_LINUX32 : PER_LINUX) == -EPERM);
+                assert_se(safe_personality(current_opinionated == PER_LINUX ? PER_LINUX32 : PER_LINUX) == -EPERM);
                 assert_se(safe_personality(PER_LINUX32_3GB) == -EPERM);
                 assert_se(safe_personality(PER_UW7) == -EPERM);
                 assert_se(safe_personality(0x42) == -EPERM);
 
                 assert_se(safe_personality(PERSONALITY_INVALID) == -EPERM); /* maybe remove this later */
 
-                assert_se((unsigned long) personality(current) == current);
+                current = safe_personality(current_opinionated);
+                assert_se((current & OPINIONATED_PERSONALITY_MASK) == current_opinionated);
                 _exit(EXIT_SUCCESS);
         }
 
index 1700732e343acc3e68b6b79b47a596c0292f34b8..346ed4b2b33cc08b43c30395c007c32790a45c29 100755 (executable)
@@ -789,12 +789,8 @@ def networkctl_json(*args):
 def networkctl_reconfigure(*links):
     networkctl('reconfigure', *links)
 
-def networkctl_reload(sleep_time=1):
+def networkctl_reload():
     networkctl('reload')
-    # 'networkctl reload' asynchronously reconfigure links.
-    # Hence, we need to wait for a short time for link to be in configuring state.
-    if sleep_time > 0:
-        time.sleep(sleep_time)
 
 def resolvectl(*args):
     return check_output(*(resolvectl_cmd + list(args)), env=env)
@@ -4597,6 +4593,12 @@ class NetworkdBondTests(unittest.TestCase, Utilities):
         print(output)
         self.assertIn('active_slave dummy98', output)
 
+        # test case for issue #31165.
+        since = datetime.datetime.now()
+        networkctl_reconfigure('dummy98')
+        self.wait_online(['dummy98:enslaved', 'bond199:degraded'])
+        self.assertNotIn('dummy98: Bringing link down', read_networkd_log(since=since))
+
     def test_bond_primary_slave(self):
         copy_network_unit('23-primary-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
         start_networkd()
index 06a3c39e776a6c60971a3583ffcc619d6a05329f..6cd5267b721abe94da7d78d1c12573aa83a15a71 100755 (executable)
@@ -104,7 +104,6 @@ networkctl cat @test2:network | cmp - <(networkctl cat "$NETWORK_NAME")
 EDITOR='cp' script -ec 'networkctl edit @test2 --drop-in test2.conf' /dev/null
 cmp "+4" "/etc/systemd/network/${NETWORK_NAME}.d/test2.conf"
 
-sleep 1
 (! EDITOR='true' script -ec 'networkctl edit @test2 --runtime --drop-in test2.conf' /dev/null)
 
 ip_link="$(ip link show test2)"
index fddf85a54c661510eb1587f765d491571a9d99e3..ef1e205aacfeee6fda2048b391374d81a20e177a 100755 (executable)
@@ -62,6 +62,13 @@ SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
 link_endswith "$OUT_DIR/early/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
 grep -F "/dev/tty666" "$OUT_DIR/early/debug-shell.service.d/50-tty.conf"
 
+# Same thing, but with custom tty using systemd.default_debug_tty
+: "debug-shell: regular + systemd.default_debug_tty=/dev/tty666 systemd.debug_shell=yes"
+CMDLINE="$CMDLINE systemd.default_debug_tty=/dev/tty666 systemd.debug_shell=yes"
+SYSTEMD_PROC_CMDLINE="$CMDLINE" run_and_list "$GENERATOR_BIN" "$OUT_DIR"
+link_endswith "$OUT_DIR/early/default.target.wants/debug-shell.service" /lib/systemd/system/debug-shell.service
+grep -F "/dev/tty666" "$OUT_DIR/early/debug-shell.service.d/50-tty.conf"
+
 # Now override the default target via systemd.unit=
 : "debug-shell: regular + systemd.unit="
 CMDLINE="$CMDLINE systemd.unit=my-fancy.target"