]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #11046 from keszybz/generator-mains
authorLennart Poettering <lennart@poettering.net>
Thu, 13 Dec 2018 21:39:23 +0000 (22:39 +0100)
committerGitHub <noreply@github.com>
Thu, 13 Dec 2018 21:39:23 +0000 (22:39 +0100)
Macroify generators a bit more

47 files changed:
NEWS
docs/ENVIRONMENT.md
man/resolved.conf.xml
man/rules/meson.build
man/sd_bus_attach_event.xml
man/sd_bus_get_fd.xml
man/sd_bus_process.xml
man/sd_bus_wait.xml [new file with mode: 0644]
man/systemctl.xml
man/systemd-udevd.service.xml
man/systemd.mount.xml
man/tmpfiles.d.xml
meson.build
meson_options.txt
src/basic/fileio.c
src/basic/tmpfile-util.c
src/boot/bootctl.c
src/core/cgroup.c
src/core/dynamic-user.c
src/core/job.c
src/core/job.h
src/core/load-fragment.c
src/core/manager.c
src/core/manager.h
src/core/mount-setup.c
src/core/smack-setup.c
src/core/unit.c
src/core/unit.h
src/coredump/coredump.c
src/fsck/fsck.c
src/machine/machine-dbus.c
src/machine/machined-dbus.c
src/network/test-routing-policy-rule.c
src/nspawn/nspawn-setuid.c
src/portable/portable.c
src/portable/portabled-image-bus.c
src/resolve/resolved-manager.c
src/resolve/resolved.conf.in
src/shared/dissect-image.c
src/shared/exec-util.c
src/shared/install.c
src/shared/os-util.c
src/systemctl/systemctl.c
src/timedate/timedatectl.c
src/timedate/timedated.c
src/udev/udev-builtin-net_id.c
src/vconsole/vconsole-setup.c

diff --git a/NEWS b/NEWS
index 4a511099da679817efb77080b1d4ee3307089831..4c32d86139652d67ed646d067f75e86e6bfd65e8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,24 +3,25 @@ systemd System and Service Manager
 CHANGES WITH 240 in spe:
 
         * A new service type has been added: Type=exec. It's very similar to
-          Type=simple and ensures the service manager will wait for both fork()
+          Type=simple but ensures the service manager will wait for both fork()
           and execve() of the main service binary to complete before proceeding
           with follow-up units. This is primarily useful so that the manager
           propagates any errors in the preparation phase of service execution
           back to the job that requested the unit to be started. For example,
           consider a service that has ExecStart= set to a file system binary
-          that doesn't exist. With Type=simple starting the unit would
-          typically succeed instantly, as only fork() has to complete
-          successfully and execve() is not waited for, and hence its failure is
-          seen "too late". With the new Type=exec service type starting the
-          unit will fail, as the execve() will be waited for and will fail,
-          which is then propagated back to the start job.
+          that doesn't exist. With Type=simple starting the unit would be
+          considered instantly successful, as only fork() has to complete
+          successfully and the manager does not wait for execve(), and hence
+          its failure is seen "too late". With the new Type=exec service type
+          starting the unit will fail, as the manager will wait for the
+          execve() and notice its failure, which is then propagated back to the
+          start job.
 
           NOTE: with the next release 241 of systemd we intend to change the
           systemd-run tool to default to Type=exec for transient services
           started by it. This should be mostly safe, but in specific corner
           cases might result in problems, as the systemd-run tool will then
-          block on NSS calls (such as user name lookups due to User=) done
+          block on NSS calls (such as user name look-ups due to User=) done
           between the fork() and execve(), which under specific circumstances
           might cause problems. It is recommended to specify "-p Type=simple"
           explicitly in the few cases where this applies. For regular,
@@ -46,23 +47,22 @@ CHANGES WITH 240 in spe:
           kernels and allocating large numbers of them should be much cheaper
           both in memory and in performance than it used to be. Programs that
           want to take benefit of the increased limit have to "opt-in" into
-          high file descriptors explicitly by setting their soft limit to the
-          hard limit during initialization. Of course, when doing that they
-          must do this acknowledging the fact that they cannot use select()
-          anymore (and neither can any shared library they use — or any shared
-          library used by any shared library they use and so on). Which default
-          hard limit is most appropriate is of course hard to decide. However,
-          given reports that ~300K file descriptors are used in real-life
-          applications we believe 512K is sufficiently high as new default for
-          now. Note that there are also reports that using very high hard
-          limits (e.g. 1G) is problematic: some software allocates large arrays
-          with one element for each potential file descriptor (Java, …) — a
-          high hard limit thus triggers excessively large memory allocations in
-          these applications. Hopefully, the new default of 512K is a good
-          middle ground: higher than what real-life applications currently
-          need, and low enough for not triggering excessively large allocations
-          in problematic software. (And yes, somebody should fix Java, to not
-          require such excessive allocations.)
+          high file descriptors explicitly by raising their soft limit. Of
+          course, when they do that they must acknowledge that they cannot use
+          select() anymore (and neither can any shared library they use — or
+          any shared library used by any shared library they use and so on).
+          Which default hard limit is most appropriate is of course hard to
+          decide. However, given reports that ~300K file descriptors are used
+          in real-life applications we believe 512K is sufficiently high as new
+          default for now. Note that there are also reports that using very
+          high hard limits (e.g. 1G) is problematic: some software allocates
+          large arrays with one element for each potential file descriptor
+          (Java, …) — a high hard limit thus triggers excessively large memory
+          allocations in these applications. Hopefully, the new default of 512K
+          is a good middle ground: higher than what real-life applications
+          currently need, and low enough for avoid triggering excessively large
+          allocations in problematic software. (And yes, somebody should fix
+          Java.)
 
         * The fs.nr_open and fs.file-max sysctls are now automatically bumped
           to the highest possible values, as separate accounting of file
@@ -88,16 +88,343 @@ CHANGES WITH 240 in spe:
           that have multiple links with routes to the same networks (e.g.
           a client with a Wi-Fi and Ethernet both connected to the internet).
 
-          Consult the kernel documetnation for details on this sysctl:
+          Consult the kernel documentation for details on this sysctl:
           https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
 
         * CPUAccounting=yes no longer enables the CPU controller when using
           kernel 4.15+ and the unified cgroup hierarchy, as required accounting
           statistics are now provided independently from the CPU controller.
 
-        * Support for disabling a particular cgroup controller within a subtree
+        * Support for disabling a particular cgroup controller within a sub-tree
           has been added through the DisableControllers= directive.
 
+        * The new "MemoryMin=" unit file property may now be used to set the
+          memory usage protection limit of processes invoked by the unit. This
+          controls the cgroupsv2 memory.min attribute. Similarly, the new
+          "IODeviceLatencyTargetSec=" property has been added, wrapping the new
+          cgroupsv2 io.latency cgroup property for configuring per-service I/O
+          latency.
+
+        * systemd now supports the cgroupsv2 devices BPF logic, as counterpart
+          to the cgroupsv1 "devices" cgroup controller.
+
+        * systemd-escape now is able to combine --unescape with --template. It
+          also learnt a new option --instance for extracting and unescaping the
+          instance part of a unit name.
+
+        * sd-bus now provides the sd_bus_message_readv() which is similar to
+          sd_bus_message_read() but takes a va_list object. The pair
+          sd_bus_set_method_call_timeout() and sd_bus_get_method_call_timeout()
+          has been added for configuring the default method call timeout to
+          use. sd_bus_error_move() may be used to efficiently move the contents
+          from one sd_bus_error structure to another, invalidating the
+          source. sd_bus_set_close_on_exit() and sd_bus_get_close_on_exit() may
+          be used to control whether a bus connection object is automatically
+          flushed when an sd-event loop is exited.
+
+        * When processing classic BSD syslog log messages, journald will now
+          save the original time-stamp string supplied in the new
+          SYSLOG_TIMESTAMP= journal field. This permits consumers to
+          reconstruct the original BSD syslog message more correctly.
+
+        * StandardOutput=/StandardError= in service files gained support for
+          new "append:…" parameters, for connecting STDOUT/STDERR of a service
+          to a file, and appending to it.
+
+        * The signal to use as last step of killing of unit processes is now
+          configurable. Previously it was hard-coded to SIGKILL, which may now
+          be overridden with the new KillSignal= setting. Note that this is the
+          signal used when regular termination (i.e. SIGTERM) does suffice.
+          Similarly, the signal used when aborting a program in case of a
+          watchdog timeout may now be configured too (WatchdogSignal=).
+
+        * The XDG_SESSION_DESKTOP environment variable may now be configured in
+          the pam_systemd argument line, using the new desktop= switch. This is
+          useful to initialize it properly from a display manager without
+          having to touch C code.
+
+        * Most configuration options that previously accepted percentage values
+          now also accept permille values with the '‰' suffix (instead of '%').
+
+        * systemd-logind will offer hibernation only if the currently used
+          kernel image is still available on disk.
+
+        * systemd-resolved may now optionally use OpenSSL instead of GnuTLS for
+          DNS-over-TLS.
+
+        * systemd-resolved's configuration file resolved.conf gained a new
+          option ReadEtcHosts= which may be used to turn off processing and
+          honoring /etc/hosts entries.
+
+        * The "--wait" switch may now be passed to "systemctl
+          is-system-running", in which case the tool will synchronously wait
+          until the system finished start-up.
+
+        * hostnamed gained a new bus call to determine the DMI product UUID.
+
+        * On x86-64 systemd will now prefer using the RDRAND processor
+          instruction over /dev/urandom whenever it requires randomness that
+          neither has to be crypto-grade nor should be reproducible. This
+          should substantially reduce the amount of entropy systemd requests
+          from the kernel during initialization on such systems, though not
+          reduce it to zero. (Why not zero? systemd still needs to allocate
+          UUIDs and such uniquely, which require high-quality randomness.)
+
+        * networkd gained support for Foo-Over-UDP, ERSPAN and ISATAP
+          tunnels. It also gained a new option ForceDHCPv6PDOtherInformation=
+          for forcing the "Other Information" bit in IPv6 RA messages. The
+          bonding logic gained three new options AdActorSystemPriority=,
+          AdUserPortKey=, AdActorSystem= for configuring various 802.3ad
+          aspects. The tunnel logic gained a new IPv6RapidDeploymentPrefix=
+          option for configuring IPv6 Rapid Deployment. The policy rule logic
+          gained four new options IPProtocol=, SourcePort= and
+          DestinationPort=, InvertRule=. The bridge logic gained support for
+          the MulticastToUnicast= option. networkd also gained support for
+          configuring static IPv4 ARP or IPv6 neighbor entries.
+
+        * .preset files (as read by 'systemctl preset') may now be used to
+          instantiate services.
+
+        * /etc/crypttab now understands the sector-size= option to configure
+          the sector size for an encrypted partition.
+
+        * Key material for encrypted disks may now be placed on a formatted
+          medium, and referenced from /etc/crypttab by the UUID of the file
+          system, followed by "=" suffixed by the path to the key file.
+
+        * The "collect" udev component has been removed without replacement, as
+          it is neither used nor maintained.
+
+        * When the RuntimeDirectory=, StateDirectory=, CacheDirectory=,
+          LogsDirectory=, ConfigurationDirectory= settings are used in a
+          service the executed processes will now receive a set of environment
+          variables containing the full paths of these directories.
+          Specifically, RUNTIME_DIRECTORY=, STATE_DIRECTORY, CACHE_DIRECTORY,
+          LOGS_DIRECTORY, CONFIGURATION_DIRECTORY are now set if these options
+          are used. Note that these options may be used multiple times per
+          service in which case the resulting paths will be concatenated and
+          separated by colons.
+
+        * Predictable interface naming has been extended to cover InfiniBand
+          NICs. They will be exposed with an "ib" prefix.
+
+        * tmpfiles.d/ line types may now be suffixed with a '-' character, in
+          which case the respective line failing is ignored.
+
+        * .link files may now be used to configure the equivalent to the
+          "ethtool advertise" commands.
+
+        * The sd-device.h and sd-hwdb.h APIs are now exported, as an
+          alternative to libudev.h. Previously, the latter was just an internal
+          wrapper around the former, but now these two APIs are exposed
+          directly.
+
+        * sd-id128.h gained a new function sd_id128_get_boot_app_specific()
+          which calculates an app-specific boot ID similar to how
+          sd_id128_get_machine_app_specific() generates an app-specific machine
+          ID.
+
+        * A new tool systemd-id128 has been added that can be used to determine
+          and generate various 128bit IDs.
+
+        * /etc/os-release gained two new standardized fields DOCUMENTATION_URL=
+          and LOGO=.
+
+        * systemd-hibernate-resume-generator will now honor the "noresume"
+          kernel command line option, in which case it will bypass resuming
+          from any hibernated image.
+
+        * The systemd-sleep.conf configuration file gained new options
+          AllowSuspend=, AllowHibernation=, AllowSuspendThenHibernate=,
+          AllowHybridSleep= for prohibiting specific sleep modes even if the
+          kernel exports them.
+
+        * portablectl is now officially supported and has thus moved to
+          /usr/bin/.
+
+        * bootctl learnt the two new commands "set-default" and "set-oneshot"
+          for setting the default boot loader item to boot to (either
+          persistently or only for the next boot). This is currently only
+          compatible with sd-boot, but may be implemented on other boot loaders
+          too, that follow the boot loader interface. The updated interface is
+          now documented here:
+
+          https://systemd.io/BOOT_LOADER_INTERFACE
+
+        * A new kernel command line option systemd.early_core_pattern= is now
+          understood which may be used to influence the core_pattern PID 1
+          installs during early boot.
+
+        * busctl learnt two new options -j and --json= for outputting method
+          call replies, properties and monitoring output in JSON.
+
+        * journalctl's JSON output now supports simple ANSI coloring as well as
+          a new "json-seq" mode for generating RFC7464 output.
+
+        * Unit files now support the %g/%G specifiers that resolve to the UNIX
+          group/GID of the service manager runs as, similar to the existing
+          %u/%U specifiers that resolve to the UNIX user/UID.
+
+        * systemd-logind learnt a new global configuration option
+          UserStopDelaySec= that may be set in logind.conf. It specifies how
+          long the systemd --user instance shall remain started after a user
+          logs out. This is useful to speed up repetitive re-connections of the
+          same user, as it means the user's service manager doesn't have to be
+          stopped/restarted on each iteration, but can be reused between
+          subsequent options. This setting defaults to 10s. systemd-logind also
+          exports two new properties on its Manager D-Bus objects indicating
+          whether the system's lid is currently closed, and whether the system
+          is on AC power.
+
+        * systemd gained support for a generic boot counting logic, which
+          generically permits automatic reverting to older boot loader entries
+          if newer updated ones don't work. The boot loader side is implemented
+          in sd-boot, but is kept open for other boot loaders too. For details
+          see:
+
+          https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT
+
+        * The SuccessAction=/FailureAction= unit file settings now learnt two
+          new parameters: "exit" and "exit-force", which result in immediate
+          exiting of the service manager, and are only useful in systemd --user
+          and container environments.
+
+        * Unit files gained support for a pair of options
+          FailureActionExitStatus=/SuccessActionExitStatus= for configuring the
+          exit status to use as service manager exit status when
+          SuccessAction=/FailureAction= is set to exit or exit-force.
+
+        * A pair of LogRateLimitIntervalSec=/LogRateLimitBurst= per-service
+          options may now be used to configure the log rate limiting applied by
+          journald per-service.
+
+        * systemd-analyze gained a new verb "timespan" for parsing and
+          normalizing time span values (i.e. strings like "5min 7s 8us").
+
+        * systemd-analyze also gained a new verb "security" for analyzing the
+          security and sand-boxing settings of services in order to determine an
+          "exposure level" for them, indicating whether a service would benefit
+          from more sand-boxing options turned on for them.
+
+        * "systemd-analyze syscall-filter" will now also show system calls
+          supported by the local kernel but not included in any of the defined
+          groups.
+
+        * .nspawn files now understand the Ephemeral= setting, matching the
+          --ephemeral command line switch.
+
+        * sd-event gained the new APIs sd_event_source_get_floating() and
+          sd_event_source_set_floating() for controlling whether a specific
+          event source is "floating", i.e. destroyed along with the even loop
+          object itself.
+
+        * Unit objects on D-Bus gained a new "Refs" property that lists all
+          clients that currently have a reference on the unit (to ensure it is
+          not unloaded).
+
+        * The JoinControllers= option in system.conf is no longer supported, as
+          it didn't work correctly, is hard to support properly, is legacy (as
+          the concept only exists on cgroupsv1) and apparently wasn't used.
+
+        * Journal messages that are generated whenever a unit enters the failed
+          state are now tagged with a unique MESSAGE_ID. Similarly, messages
+          generated whenever a service process exits are now made recognizable,
+          too. A taged message is also emitted whenever a unit enters the
+          "dead" state on success.
+
+        * systemd-run gained a new switch --working-directory= for configuring
+          the working directory of the service to start. A shortcut -d is
+          equivalent, setting the working directory of the service to the
+          current working directory of the invoking program. The new --shell
+          (or just -S) option has been added for invoking the $SHELL of the
+          caller as a service, and implies --pty --same-dir --wait --collect
+          --service-type=exec. Or in other words, "systemd-run -S" is now the
+          quickest way to quickly get an interactive in a fully clean and
+          well-defined system service context.
+
+        * machinectl gained a new verb "import-fs" for importing an OS tree
+          from a directory. Moreover, when a directory or tarball is imported
+          and single top-level directory found with the OS itself below the OS
+          tree is automatically mangled and moved one level up.
+
+        * systemd-importd will no longer set up an implicit btrfs loop-back
+          file system on /var/lib/machines. If one is already set up, it will
+          continue to be used.
+
+        * A new generator "systemd-run-generator" has been added. It will
+          synthesize a unit from one or more program command lines included in
+          the kernel command line. This is very useful in container managers
+          for example:
+
+          # systemd-nspawn -i someimage.raw -b systemd.run='"some command line"'
+
+          This will run "systemd-nspawn" on an image, invoke the specified
+          command line and immediately shut down the container again, returning
+          the command line's exit code.
+
+        * The block device locking logic is now documented:
+
+          https://systemd.io/BLOCK_DEVICE_LOCKING
+
+        * loginctl and machinectl now optionally output the various tables in
+          JSON using the --output= switch. It is our intention to add similar
+          support to systemctl and all other commands.
+
+        * udevadm's query and trigger verb now optionally take a .device unit
+          name as argument.
+
+        * systemd-udevd's network naming logic now understands a new
+          net.naming-scheme= kernel command line switch, which may be used to
+          pick a specific version of the naming scheme. This helps stabilizing
+          interface names even as systemd/udev are updated and the naming logic
+          is improved.
+
+        Contributions from: afg, Alan Jenkins, Aleksei Timofeyev, Alexander
+        Filippov, Alexander Kurtz, Alexey Bogdanenko, Andreas Henriksson,
+        Andrew Jorgensen, Anita Zhang, apnix-uk, Arkan49, Arseny Maslennikov,
+        asavah, Asbjørn Apeland, aszlig, Bastien Nocera, Ben Boeckel, Benedikt
+        Morbach, Benjamin Berg, Carlo Caione, Cedric Viou, Chen Qi, ChenQi1989,
+        Chris Chiu, Chris Down, Chris Morin, Christian Rebischke, Claudius
+        Ellsel, ColinGuthrie, dana, Daniel, Daniele Medri, Daniel Kahn Gillmor,
+        Daniel Rusek, Daniel van Vugt, Dariusz Gadomski, Dave Reisner, David
+        Anderson, Davide Cavalca, David Leeds, David Malcolm, David Strauss,
+        David Tardon, Dimitri John Ledkov, dj-kaktus, Dongsu Park, Elias
+        Probst, Emil Soleyman, Erik Kooistra, Ervin Peters, Evgeni Golov,
+        Evgeny Vereshchagin, Fabrice Fontaine, Faheel Ahmad, faizalluthfi,
+        Felix Yan, Filipe Brandenburger, Franck Bui, Frank Schaefer, Frantisek
+        Sumsal, Gianluca Boiano, Giuseppe Scrivano, glitsj16, Hans de Goede,
+        Harald Hoyer, Harry Mallon, Harshit Jain, hellcp, Helmut Grohne, Henry
+        Tung, Hui Yiqun, imayoda, Insun Pyo, INSUN PYO, Iwan Timmer,
+        jambonmcyeah, Jan Janssen, Jan Pokorný, Jan Synacek, Jason
+        A. Donenfeld, javitoom, Jérémy Nouhaud, Jiuyang liu, João Paulo Rechi
+        Vita, Joe Hershberger, Joe Rayhawk, Joerg Behrmann, Joerg Steffens,
+        Jonas DOREL, Jon Ringle, Josh Soref, Julian Andres Klode, Jürg
+        Billeter, Keith Busch, killermoehre, Kirill Marinushkin, Lennart
+        Poettering, LennartPoettering, Liberasys, Lion Yang, Li Song, Lorenz
+        Hübschle-Schneider, Lubomir Rintel, Lucas Werkmeister, Ludwin Janvier,
+        Lukáš Nykrýn, Luke Shumaker, mal, Marc-Antoine Perennou, Marcin
+        Skarbek, Marco Trevisan (Treviño), Marian Cepok, Mario Hros, Marko
+        Myllynen, Markus Grimm, Martin Pitt, Martin Sobotka, Martin Wilck,
+        Mathieu Trudel-Lapierre, Matthew Leeds, Michael Biebl, Michael Olbrich,
+        Michael 'pbone' Pobega, Michal Koutný, Michal Sekletar, Michal Soltys,
+        Mike Gilbert, Mike Palmer, Muhammet Kara, Neal Gompa, Network Silence,
+        nikolas, NOGISAKA Sadata, Oliver Smith, Patrik Flykt, Pavel Hrdina,
+        Paweł Szewczyk, Peter Hutterer, Piotr Drąg, Ray Strode, remueller,
+        Renaud Métrich, Roman Gushchin, Ronny Chevalier, Rubén Suárez Alvarez,
+        Ruixin Bao, RussianNeuroMancer, Ryutaroh Matsumoto, Saleem Rashid,
+        Samuel Morris, Sandy, scootergrisen, seb128, Sergey Ptashnick, Shawn
+        Landden, Shengyao Xue, Shih-Yuan Lee (FourDollars), Sjoerd Simons,
+        Stephen Gallagher, Steven Allen, Steve Ramage, Susant Sahani, Sven
+        Joachim, Sylvain Plantefève, TanuKaskinen, Tejun Heo, Thiago Macieira,
+        Thomas Blume, Thomas Haller, Thomas H. P. Andersen, Tim Ruffing, TJ,
+        Tobias Jungel, Todd Walton, Tommi Rantala, Tomsod M, Tony Novak,
+        Trevonn, Victor Laskurain, Victor Tapia, Violet Halo, Vojtech Trefny,
+        welaq, William A. Kennington III, William Douglas, Wyatt Ward, Xiang
+        Fan, Xi Ruoyao, Xuanwo, Yann E. MORIN, YmrDtnJu, Yu Watanabe, Zbigniew
+        Jędrzejewski-Szmek, Zhang Xianwei, Zsolt Dollenstein
+
+        — Somewhere, 2018-xx-yy
+
 CHANGES WITH 239:
 
         * NETWORK INTERFACE DEVICE NAMING CHANGES: systemd-udevd's "net_id"
index e9e82cfca448186f26cd30c894413450b423a216..eaac288ec585d5881d37142713a83c652b2c77b4 100644 (file)
@@ -92,13 +92,14 @@ systemd-logind:
   for it.
 
 * `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of
-  v238, v239, v240 …) as parameter. If specified udev's net_id builtin will
-  follow the specified naming scheme when determining stable network interface
-  names. This may be used to revert to naming schemes of older udev versions,
-  in order to provide more stable naming across updates. This environment
-  variable takes precedence over the kernel command line option
-  `net.naming-scheme=`, except if the value is prefixed with `:` in which case
-  the kernel command line option takes precedence, if it is specified as well.
+  "v238", "v239", "v240"…, or the special value "latest") as parameter. If
+  specified udev's net_id builtin will follow the specified naming scheme when
+  determining stable network interface names. This may be used to revert to
+  naming schemes of older udev versions, in order to provide more stable naming
+  across updates. This environment variable takes precedence over the kernel
+  command line option `net.naming-scheme=`, except if the value is prefixed
+  with `:` in which case the kernel command line option takes precedence, if it
+  is specified as well.
 
 installed systemd tests:
 
index eb2794c4180389a2dc425312efe14f1079557a27..d37bf0d3ad658d313ab18fae337d94d4b8e091db 100644 (file)
       <varlistentry>
         <term><varname>DNSStubListener=</varname></term>
         <listitem><para>Takes a boolean argument or one of <literal>udp</literal> and <literal>tcp</literal>. If
-        <literal>udp</literal> (the default), a DNS stub resolver will listen for UDP requests on address 127.0.0.53
+        <literal>udp</literal>, a DNS stub resolver will listen for UDP requests on address 127.0.0.53
         port 53. If <literal>tcp</literal>, the stub will listen for TCP requests on the same address and port. If
-        <literal>yes</literal>, the stub listens for both UDP and TCP requests.  If <literal>no</literal>, the stub
+        <literal>yes</literal> (the default), the stub listens for both UDP and TCP requests.  If <literal>no</literal>, the stub
         listener is disabled.</para>
 
         <para>Note that the DNS stub listener is turned off implicitly when its listening address and port are already
index b091859829e68be4e433be72890d02fe280d9d38..0c990a0c5d340e3c43213a8c97094979b1732bbe 100644 (file)
@@ -194,7 +194,7 @@ manpages = [
   '3',
   ['SD_BUS_ERROR_END', 'SD_BUS_ERROR_MAP', 'sd_bus_error_map'],
   ''],
- ['sd_bus_get_fd', '3', [], ''],
+ ['sd_bus_get_fd', '3', ['sd_bus_get_events', 'sd_bus_get_timeout'], ''],
  ['sd_bus_get_n_queued_read', '3', ['sd_bus_get_n_queued_write'], ''],
  ['sd_bus_is_open', '3', ['sd_bus_is_ready'], ''],
  ['sd_bus_message_append', '3', ['sd_bus_message_appendv'], ''],
@@ -347,6 +347,7 @@ manpages = [
    'sd_bus_track_unref',
    'sd_bus_track_unrefp'],
   ''],
+ ['sd_bus_wait', '3', [], ''],
  ['sd_event_add_child',
   '3',
   ['sd_event_child_handler_t', 'sd_event_source_get_child_pid'],
index 45f034910febd41fd417baa9cce7fd8701af667c..a2f7297f21515f10ea0082f325b5365f6171a25f 100644 (file)
 
     <para>The <function>sd_bus_get_event()</function> returns the event loop object the specified bus object is
     currently attached to, or <constant>NULL</constant> if it is currently not attached to any.</para>
+
+    <para>Note that <function>sd_bus_attach_event()</function> is only one of three supported ways to implement I/O
+    event handling for bus connections. Alternatively use
+    <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry> for hooking up a
+    bus connection object with external or manual event loops. Or use
+    <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry> as a simple
+    synchronous, blocking I/O waiting call.</para>
   </refsect1>
 
   <refsect1>
       <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd_event_source_set_priority</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd_bus_set_close_on_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+      <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     </para>
   </refsect1>
 
index 6f709df4c04bf6e1b6617588450d578787c58e6c..2a81bddaa04653b432710047e392ce2bc566f4b6 100644 (file)
@@ -8,7 +8,7 @@
   Copyright © 2016 Julian Orth
 -->
 
-<refentry id="sd_bus_get_fd">
+<refentry id="sd_bus_get_fd" xmlns:xi="http://www.w3.org/2001/XInclude">
 
   <refentryinfo>
     <title>sd_bus_get_fd</title>
 
   <refnamediv>
     <refname>sd_bus_get_fd</refname>
+    <refname>sd_bus_get_events</refname>
+    <refname>sd_bus_get_timeout</refname>
 
-    <refpurpose>Get the file descriptor connected to the message bus</refpurpose>
+    <refpurpose>Get the file descriptor, I/O events and time-out to wait for from a message bus object</refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
         <funcdef>int <function>sd_bus_get_fd</function></funcdef>
         <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
       </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_events</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+      </funcprototype>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_get_timeout</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>uint64_t *<parameter>timeout_usec</parameter></paramdef>
+      </funcprototype>
     </funcsynopsis>
   </refsynopsisdiv>
 
   <refsect1>
     <title>Description</title>
 
-    <para>
-      <function>sd_bus_get_fd()</function> returns the file descriptor used to
-      communicate with the message bus. This descriptor can be used with
-      <citerefentry
-        project='die-net'><refentrytitle>select</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      <citerefentry
-        project='die-net'><refentrytitle>poll</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
-      or similar functions to wait for incoming messages.
-    </para>
-
-    <para>
-      If the bus was created with the
-      <citerefentry><refentrytitle>sd_bus_set_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-      function, then the <parameter>input_fd</parameter> used in that call is
-      returned.
-    </para>
+    <para><function>sd_bus_get_fd()</function> returns the file descriptor used to communicate from a message bus
+    object. This descriptor can be used with <citerefentry
+    project='man-pages'><refentrytitle>poll</refentrytitle><manvolnum>3</manvolnum></citerefentry> or a similar
+    function to wait for I/O events on the specified bus connection object. If the bus object was configured with the
+    <citerefentry><refentrytitle>sd_bus_set_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry> function, then
+    the <parameter>input_fd</parameter> file descriptor used in that call is returned.</para>
+
+    <para><function>sd_bus_get_events()</function> returns the I/O events to wait for, suitable for passing to
+    <function>poll()</function> or a similar call. Returns a combination of <constant>POLLIN</constant>,
+    <constant>POLLOUT</constant>, … events, or negative on error.</para>
+
+    <para><function>sd_bus_get_timeout()</function> returns the time-out in µs to pass to to
+    <function>poll()</function> or a similar call when waiting for events on the specified bus connection. The returned
+    time-out may be zero, in which case a subsequent I/O polling call should be invoked in non-blocking mode. The
+    returned timeout may be <constant>UINT64_MAX</constant> in which case the I/O polling call may block indefinitely,
+    without any applied time-out. Note that the returned time-out should be considered only a maximum sleeping time. It
+    is permissible (and even expected) that shorter time-outs are used by the calling program, in case other event
+    sources are polled in the same event loop. Note that the returned time-value is relative and specified in
+    microseconds. When converting this value in order to pass it as third argument to <function>poll()</function>
+    (which expects milliseconds), care should be taken to use a division that rounds up to ensure the I/O polling
+    operation doesn't sleep for shorter than necessary, which might result in unintended busy looping (alternatively,
+    use <citerefentry project='man-pages'><refentrytitle>ppoll</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    instead of plain <function>poll()</function>, which understands time-outs with nano-second granularity).</para>
+
+    <para>These three functions are useful to hook up a bus connection object with an external or manual event loop
+    involving <function>poll()</function> or a similar I/O polling call. Before each invocation of the I/O polling
+    call, all three functions should be invoked: the file descriptor returned by <function>sd_bus_get_fd()</function>
+    should be polled for the events indicated by <function>sd_bus_get_events()</function>, and the I/O call should
+    block for that up to the time-out returned by <function>sd_bus_get_timeout()</function>. After each I/O polling
+    call the bus connection needs to process incoming or outgoing data, by invoking
+    <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+
+    <para>Note that these function are only one of three supported ways to implement I/O event handling for bus
+    connections. Alternatively use
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry> to attach a
+    bus connection to an <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    event loop. Or use <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    as a simple synchronous, blocking I/O waiting call.</para>
   </refsect1>
 
   <refsect1>
     <title>Return Value</title>
 
-    <para>
-      Returns the file descriptor used for incoming messages from the message
-      bus.
-    </para>
+    <para><function>sd_bus_get_fd()</function> returns the file descriptor used for communication, or a negative
+    <varname>errno</varname>-style error code on error.</para>
+
+    <para><function>sd_bus_get_events()</function> returns the I/O event mask to use for I/O event watching, or a
+    negative <varname>errno</varname>-style error code on error.</para>
+
+    <para><function>sd_bus_get_timeout()</function> returns zero or positive on success, or a negative
+    <varname>errno</varname>-style error code on error.</para>
   </refsect1>
 
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>-EINVAL</constant></term>
+
+        <listitem><para>An invalid bus object was passed.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ECHILD</constant></term>
+
+        <listitem><para>The bus connection was allocated in a parent process and is being reused in a child process
+        after <function>fork()</function>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ENOTCONN</constant></term>
+
+        <listitem><para>The bus connection has been terminated.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-EPERM</constant></term>
+
+        <listitem><para>Two distinct file descriptors were passed for input and output using
+        <function>sd_bus_set_fd()</function>, which <function>sd_bus_get_fd()</function> cannot
+        return.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <xi:include href="libsystemd-pkgconfig.xml" />
+
   <refsect1>
     <title>See Also</title>
 
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd_bus_set_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry project='man-pages'><refentrytitle>poll</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     </para>
   </refsect1>
 
index b78192990c96b4f1be534d117855fe8a457cf517..66f22c29a62b24e037c0713aff6dbc0429f9a548 100644 (file)
@@ -8,7 +8,7 @@
   Copyright © 2016 Julian Orth
 -->
 
-<refentry id="sd_bus_process">
+<refentry id="sd_bus_process" xmlns:xi="http://www.w3.org/2001/XInclude">
 
   <refentryinfo>
     <title>sd_bus_process</title>
@@ -33,7 +33,7 @@
       <funcprototype>
         <funcdef>int <function>sd_bus_process</function></funcdef>
         <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
-        <paramdef>sd_bus_message **<parameter>r</parameter></paramdef>
+        <paramdef>sd_bus_message **<parameter>ret</parameter></paramdef>
       </funcprototype>
     </funcsynopsis>
   </refsynopsisdiv>
   <refsect1>
     <title>Description</title>
 
-    <para>
-      <function>sd_bus_process()</function> drives the connection between the
-      message bus and the client. That is, it handles connecting,
-      authentication, and message processing. It should be called in a loop
-      until no further progress can be made or an error occurs.
-    </para>
-
-    <para>
-      Once no further progress can be made,
-      <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-      should be called. Alternatively the user can wait for incoming data on
-      the file descriptor returned by
-      <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+    <para><function>sd_bus_process()</function> drives the connection between the client and the message bus. That is,
+    it handles connecting, authentication, and message processing. When invoked pending I/O work is executed, and
+    queued incoming messages are dispatched to registered callbacks. Each time it is invoked a single operation is
+    executed. It returns zero when no operations were pending and positive if a message was processed. When zero is
+    returned the caller should synchronously poll for I/O events before calling into
+    <function>sd_bus_process()</function> again. For that either user the simple, synchronous
+    <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry> call, or hook up
+    the bus connection object to an external or manual event loop using
+    <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
     </para>
 
-    <para>
-      <function>sd_bus_process</function> processes at most one incoming
-      message per call.  If the parameter <parameter>r</parameter> is not NULL
-      and the call processed a message, <code>*r</code> is set to this message.
-      The caller owns a reference to this message and should call
-      <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-      when the message is no longer needed. If <parameter>r</parameter> is not
-      NULL, progress was made, but no message was processed, <code>*r</code> is
-      set to NULL.
-    </para>
+    <para><function>sd_bus_process()</function> processes at most one incoming message per call.  If the parameter
+    <parameter>ret</parameter> is not <constant>NULL</constant> and the call processed a message,
+    <parameter>*ret</parameter> is set to this message.  The caller owns a reference to this message and should call
+    <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> when the
+    message is no longer needed. If <parameter>ret</parameter> is not NULL, progress was made, but no message was
+    processed, <parameter>*ret</parameter> is set to <constant>NULL</constant>.</para>
+
+    <para>If a the bus object is connected to an
+    <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry> event loop (with
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>), it is not
+    necessary to call <function>sd_bus_process()</function> directly as it is invoked automatically when
+    necessary.</para>
   </refsect1>
 
   <refsect1>
     <title>Return Value</title>
 
-    <para>
-      If progress was made, a positive integer is returned. If no progress was
-      made, 0 is returned. If an error occurs, a negative errno-style error code
-      is returned.
-    </para>
+    <para>If progress was made, a positive integer is returned. If no progress was made, 0 is returned. If an error
+    occurs, a negative <varname>errno</varname>-style error code is returned.</para>
   </refsect1>
 
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>-EINVAL</constant></term>
+
+        <listitem><para>An invalid bus object was passed.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ECHILD</constant></term>
+
+        <listitem><para>The bus connection was allocated in a parent process and is being reused in a child process
+        after <function>fork()</function>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ENOTCONN</constant></term>
+
+        <listitem><para>The bus connection has been terminated already.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ECONNRESET</constant></term>
+
+        <listitem><para>The bus connection has been terminated just now.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-EBUSY</constant></term>
+
+        <listitem><para>This function is already being called, i.e. <function>sd_bus_process()</function> has been
+        called from a callback function that itself was called by
+        <function>sd_bus_process()</function>.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <xi:include href="libsystemd-pkgconfig.xml" />
+
   <refsect1>
     <title>See Also</title>
 
     <para>
       <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
       <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     </para>
   </refsect1>
 
diff --git a/man/sd_bus_wait.xml b/man/sd_bus_wait.xml
new file mode 100644 (file)
index 0000000..e866eeb
--- /dev/null
@@ -0,0 +1,113 @@
+<?xml version='1.0'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+  SPDX-License-Identifier: LGPL-2.1+
+
+  Copyright © 2016 Julian Orth
+-->
+
+<refentry id="sd_bus_wait" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+  <refentryinfo>
+    <title>sd_bus_wait</title>
+    <productname>systemd</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>sd_bus_wait</refentrytitle>
+    <manvolnum>3</manvolnum>
+  </refmeta>
+
+  <refnamediv>
+    <refname>sd_bus_wait</refname>
+
+    <refpurpose>Wait for I/O on a bus connection</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+      <funcprototype>
+        <funcdef>int <function>sd_bus_wait</function></funcdef>
+        <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+        <paramdef>uint64_t <parameter>timeout_usec</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>sd_bus_wait()</function> synchronously waits for I/O on the specified bus connection object. This
+    function is supposed to be called whenever
+    <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry> returns zero,
+    indicating that no work is pending on the connection. Internally, this call invokes <citerefentry
+    project='man-pages'><refentrytitle>ppoll</refentrytitle><manvolnum>3</manvolnum></citerefentry>, to wait for I/O on
+    the bus connection. If the <parameter>timeout_sec</parameter> parameter is specified, the call will block at most
+    for the specified amount of time in µs. Pass <constant>UINT64_MAX</constant> to permit it to sleep
+    indefinitely.</para>
+
+    <para>After each invocation of <function>sd_bus_wait()</function> the <function>sd_bus_process()</function> call
+    should be invoked in order to process any now pending I/O work.</para>
+
+    <para>Note that <function>sd_bus_wait()</function> is suitable only for simple programs as it does not permit
+    waiting for other I/O events. For more complex programs either connect the bus connection object to an external
+    event loop using <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    or to an <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry> event loop
+    using
+    <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>If any I/O was seen, a positive value is returned, zero otherwise. If an error occurs, a negative
+    <varname>errno</varname>-style error code is returned.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Errors</title>
+
+    <para>Returned errors may indicate the following problems:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><constant>-EINVAL</constant></term>
+
+        <listitem><para>An invalid bus object was passed.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ECHILD</constant></term>
+
+        <listitem><para>The bus connection was allocated in a parent process and is being reused in a child process
+        after <function>fork()</function>.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><constant>-ENOTCONN</constant></term>
+
+        <listitem><para>The bus connection has been terminated already.</para></listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <xi:include href="libsystemd-pkgconfig.xml" />
+
+  <refsect1>
+    <title>See Also</title>
+
+    <para>
+      <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_process</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+      <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+    </para>
+  </refsect1>
+
+</refentry>
index 2be5a838e010a119b71bc9ce33e84fcd62173aaa..b9077c55a1a8458ce4bf779e640c4d8ab52fd9c5 100644 (file)
         <term><option>--runtime</option></term>
 
         <listitem>
-          <para>When used with <command>set-property</command>, make changes only
-          temporarily, so that they are lost on the next reboot.</para>
-
-          <para>Similarily, when used with <command>enable</command>, <command>mask</command>,
-          <command>edit</command> and related commands, make temporary changes, which are lost on
-          the next reboot. Changes are not made in subdirectories of <filename>/etc</filename>, but
-          in <filename>/run</filename>. The immediate effect is identical, however since the latter
+          <para>When used with <command>enable</command>,
+          <command>disable</command>, <command>edit</command>,
+          (and related commands), make changes only temporarily, so
+          that they are lost on the next reboot. This will have the
+          effect that changes are not made in subdirectories of
+          <filename>/etc</filename> but in <filename>/run</filename>,
+          with identical immediate effects, however, since the latter
           is lost on reboot, the changes are lost too.</para>
 
-          <para>Note: this option cannot be used with <command>disable</command>,
-          <command>unmask</command>, <command>preset</command>, or <command>preset-all</command>,
-          because those operations sometimes need to remove symlinks under <filename>/etc</filename>
-          to have the desired effect, which would cause a persistent change.</para>
+          <para>Similarly, when used with
+          <command>set-property</command>, make changes only
+          temporarily, so that they are lost on the next
+          reboot.</para>
         </listitem>
       </varlistentry>
 
index b1409698ab500e054467dbf80fa1b472cbd7c482..330700d7dd1972db8e53cb7291dbec900896d837 100644 (file)
         <term><varname>net.naming-scheme=</varname></term>
         <listitem>
           <para>Network interfaces are renamed to give them predictable names when possible (unless
-          <varname>net.ifnames=0</varname> is specified, see above). The names are derived from various device metadata
-          fields. Newer versions of <filename>systemd-udevd.service</filename> take more of these fields into account,
-          improving (and thus possibly changing) the names used for the same devices. With this kernel command line
-          option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as
-          argument. Currently the following identifiers are known: <literal>v238</literal>, <literal>v239</literal>,
-          <literal>v240</literal> which each implement the naming scheme that was the default in the indicated systemd
-          version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the
-          naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated,
-          previously missing attributes <filename>systemd-udevd.service</filename> is checking might appear, which
-          affects older name derivation algorithms, too.</para>
+          <varname>net.ifnames=0</varname> is specified, see above). The names are derived from various
+          device metadata fields. Newer versions of <filename>systemd-udevd.service</filename> take more of
+          these fields into account, improving (and thus possibly changing) the names used for the same
+          devices. With this kernel command line option it is possible to pick a specific version of this
+          algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers
+          are known: <literal>v238</literal>, <literal>v239</literal>, <literal>v240</literal> which each
+          implement the naming scheme that was the default in the indicated systemd version. In addition,
+          <literal>latest</literal> may be used to designate the latest scheme known (to this particular
+          version of <filename>systemd-udevd.service</filename>).</para>
+
+          <para>Note that selecting a specific scheme is not sufficient to fully stabilize interface naming:
+          the naming is generally derived from driver attributes exposed by the kernel. As the kernel is
+          updated, previously missing attributes <filename>systemd-udevd.service</filename> is checking might
+          appear, which affects older name derivation algorithms, too.</para>
         </listitem>
       </varlistentry>
     </variablelist>
index abd43ee68481c35268922cb2f767cb4e0e8289fe..6d8c873ca52a6ecb3b328efb14d8cc78241a61a5 100644 (file)
     is detected by <command>systemd-fstab-generator</command> and the options
     are transformed so that systemd fulfills the job-control implications of
     that option.  Specifically <command>systemd-fstab-generator</command> acts
-    as though <literal>x-systemd.mount-timout=infinity,retry=10000</literal> was
+    as though <literal>x-systemd.mount-timeout=infinity,retry=10000</literal> was
     prepended to the option list, and <literal>fg,nofail</literal> was appended.
     Depending on specific requirements, it may be appropriate to provide some of
     these options explicitly, or to make use of the
index 7641b790af1c399c086386cd543e8e8e3079d246..5d393f3984053070fdc10fd14cb2af27f07ef969 100644 (file)
   <refsect1>
     <title>Description</title>
 
-    <para><command>systemd-tmpfiles</command> uses the configuration
-    files from the above directories to describe the creation,
-    cleaning and removal of volatile and temporary files and
-    directories which usually reside in directories such as
-    <filename>/run</filename> or <filename>/tmp</filename>.</para>
-
-    <para>Volatile and temporary files and directories are those located in <filename>/run</filename>,
-    <filename>/tmp</filename>, <filename>/var/tmp</filename>, the API file systems such as <filename>/sys</filename> or
-    <filename>/proc</filename>, as well as some other directories below <filename>/var</filename>.</para>
-
-    <para>System daemons frequently require private runtime
-    directories below <filename>/run</filename> to place communication
-    sockets and similar in. For these, consider declaring them in
-    their unit files using <varname>RuntimeDirectory=</varname> (see
-    <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
-    for details), if this is feasible.</para>
+    <para><filename>tmpfiles.d</filename> configuration files provide a generic mechanism to define the
+    <emphasis>creation</emphasis> of regular files, directories, pipes, and device nodes, adjustments to
+    their <emphasis>access mode, ownership, attributes, quota assignments, and contents</emphasis>, and
+    finally their time-based <emphasis>removal</emphasis>. It is mostly commonly used for volatile and
+    temporary files and directories (such as those located under <filename>/run</filename>,
+    <filename>/tmp</filename>, <filename>/var/tmp</filename>, the API file systems such as
+    <filename>/sys</filename> or <filename>/proc</filename>, as well as some other directories below
+    <filename>/var</filename>).</para>
+
+    <para><command>systemd-tmpfiles</command> uses this configuration to create volatile files and
+    directories during boot and to do periodic cleanup afterwards. See
+    <citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+    the description of <filename>systemd-tmpfiles-setup.service</filename>,
+    <filename>systemd-tmpfiles-cleanup.service</filename>, and associated units.</para>
+
+    <para>System daemons frequently require private runtime directories below <filename>/run</filename> to
+    store communication sockets and similar. For these, is is better to use
+    <varname>RuntimeDirectory=</varname> in their unit files (see
+    <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
+    details), if the flexibility provided by <filename>tmpfiles.d</filename> is not required. The advantages
+    are that the configuration required by the unit is centralized in one place, and that the lifetime of the
+    directory is tied to the lifetime of the service itself. Similarly, <varname>StateDirectory=</varname>,
+    <varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, and
+    <varname>ConfigurationDirectory=</varname> should be used to create directories under
+    <filename>/var/lib/</filename>, <filename>/var/cache/</filename>, <filename>/var/log/</filename>, and
+    <filename>/etc/</filename>. <filename>tmpfiles.d</filename> should be used for files whose lifetime is
+    independent of any service or requires more complicated configuration.</para>
   </refsect1>
 
   <refsect1>
     <para>The configuration format is one line per path containing
     type, path, mode, ownership, age, and argument fields:</para>
 
-    <programlisting>#Type Path        Mode UID  GID  Age Argument
-d     /run/user   0755 root root 10d -
-L     /tmp/foobar -    -    -    -   /dev/null</programlisting>
+    <programlisting>#Type Path        Mode User Group Age Argument
+d     /run/user   0755 root root  10d -
+L     /tmp/foobar -    -    -     -   /dev/null</programlisting>
 
     <para>Fields may be enclosed within quotes and contain C-style escapes.</para>
 
@@ -135,49 +146,49 @@ L     /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
         <varlistentry>
           <term><varname>d</varname></term>
-          <listitem><para>Create a directory. The mode and ownership will be adjusted if
-          specified and the directory already exists. Contents of this directory are subject
-          to time based cleanup if the age argument is specified.</para></listitem>
+          <listitem><para>Create a directory. The mode and ownership will be adjusted if specified. Contents
+          of this directory are subject to time based cleanup if the age argument is specified.
+          </para></listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>D</varname></term>
-          <listitem><para>Similar to <varname>d</varname>, but in addition the contents
-          of the directory will be removed when <option>--remove</option> is used.
-          </para></listitem>
+          <listitem><para>Similar to <varname>d</varname>, but in addition the contents of the directory will
+          be removed when <option>--remove</option> is used.</para></listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>e</varname></term>
-          <listitem><para>Similar to <varname>d</varname>, but the directory will not be created if
-          it does not exist. Lines of this type accept shell-style globs in place of normal path
-          names. For this entry to be useful, at least one of the mode, uid, gid, or age arguments
-          must be specified, since otherwise this entry has no effect. If the age argument is
-          <literal>0</literal>, contents of the directory will be unconditionally deleted every time
-          <command>systemd-tmpfiles --clean</command> is run. This can be useful when combined with
-          <varname>!</varname>, see the examples.</para></listitem>
+          <listitem><para>Adjust the mode and ownership of existing directories and remove their contents
+          based on age.
+          Lines of this type accept shell-style globs in place of normal path names. Contents of the
+          directories are subject to time based cleanup if the age argument is specified. If the age argument
+          is <literal>0</literal>, contents will be unconditionally deleted every time
+          <command>systemd-tmpfiles --clean</command> is run.</para>
+
+          <para>For this entry to be useful, at least one of the mode, user, group, or age arguments must be
+          specified, since otherwise this entry has no effect. As an exception, an entry with no effect may
+          be useful when combined with <varname>!</varname>, see the examples.</para></listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>v</varname></term>
-          <listitem><para>Create a subvolume if the path does not
-          exist yet, the file system supports subvolumes (btrfs), and
-          the system itself is installed into a subvolume
-          (specifically: the root directory <filename>/</filename> is
-          itself a subvolume). Otherwise, create a normal directory, in
-          the same way as <varname>d</varname>. A subvolume created
-          with this line type is not assigned to any higher-level
-          quota group. For that, use <varname>q</varname> or
-          <varname>Q</varname>, which allow creating simple quota
-          group hierarchies, see below.</para></listitem>
+          <listitem><para>Create a subvolume if the path does not exist yet, the file system supports
+          subvolumes (btrfs), and the system itself is installed into a subvolume (specifically: the root
+          directory <filename>/</filename> is itself a subvolume). Otherwise, create a normal directory, in
+          the same way as <varname>d</varname>.</para>
+
+          <para>A subvolume created with this line type is not assigned to any higher-level quota group. For
+          that, use <varname>q</varname> or <varname>Q</varname>, which allow creating simple quota group
+          hierarchies, see below.</para></listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>q</varname></term>
-          <listitem><para>Similar to <varname>v</varname>. However, makes sure that the subvolume will be assigned to
-          the same higher-level quota groups as the subvolume it has been created in. This ensures that higher-level
-          limits and accounting applied to the parent subvolume also include the specified subvolume. On non-btrfs file
-          systems, this line type is identical to <varname>d</varname>.</para>
+          <listitem><para>Create a subvolume or directory the same as <varname>v</varname>, but assign the
+          subvolume to the same higher-level quota groups as the parent. This ensures that higher-level
+          limits and accounting applied to the parent subvolume also include the specified subvolume. On
+          non-btrfs file systems, this line type is identical to <varname>d</varname>.</para>
 
           <para>If the subvolume already exists, no change to the quota hierarchy is made, regardless of whether the
           subvolume is already attached to a quota group or not. Also see <varname>Q</varname> below. See <citerefentry
@@ -187,13 +198,15 @@ L     /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
         <varlistentry>
           <term><varname>Q</varname></term>
-          <listitem><para>Similar to <varname>q</varname>. However, instead of copying the higher-level quota group
-          assignments from the parent as-is, the lowest quota group of the parent subvolume is determined that is not
-          the leaf quota group. Then, an "intermediary" quota group is inserted that is one level below this level, and
-          shares the same ID part as the specified subvolume. If no higher-level quota group exists for the parent
-          subvolume, a new quota group at level 255 sharing the same ID as the specified subvolume is inserted
-          instead. This new intermediary quota group is then assigned to the parent subvolume's higher-level quota
-          groups, and the specified subvolume's leaf quota group is assigned to it.</para>
+          <listitem><para>Create the subvolume or directory the same as <varname>v</varname>, but assign the
+          new subvolume to a new leaf quota group. Instead of copying the higher-level quota group
+          assignments from the parent as is done with <varname>q</varname>, the lowest quota group of the
+          parent subvolume is determined that is not the leaf quota group. Then, an "intermediary" quota
+          group is inserted that is one level below this level, and shares the same ID part as the specified
+          subvolume. If no higher-level quota group exists for the parent subvolume, a new quota group at
+          level 255 sharing the same ID as the specified subvolume is inserted instead. This new intermediary
+          quota group is then assigned to the parent subvolume's higher-level quota groups, and the specified
+          subvolume's leaf quota group is assigned to it.</para>
 
           <para>Effectively, this has a similar effect as <varname>q</varname>, however introduces a new higher-level
           quota group for the specified subvolume that may be used to enforce limits and accounting to the specified
@@ -213,8 +226,8 @@ L     /tmp/foobar -    -    -    -   /dev/null</programlisting>
           <filename>/var/tmp</filename>. </para>
 
           <para>As with <varname>q</varname>, <varname>Q</varname> has no effect on the quota group hierarchy if the
-          subvolume already exists, regardless of whether the subvolume already belong to a quota group or
-          not.</para></listitem>
+          subvolume already exists, regardless of whether the subvolume already belong to a quota group or not.
+          </para></listitem>
         </varlistentry>
 
         <varlistentry>
@@ -320,20 +333,17 @@ L     /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
         <varlistentry>
           <term><varname>z</varname></term>
-          <listitem><para>Adjust the access mode, group and user, and
-          restore the SELinux security context of a file or directory,
-          if it exists. Lines of this type accept shell-style globs in
-          place of normal path names. Does not follow symlinks.</para></listitem>
+          <listitem><para>Adjust the access mode, user and group ownership, and restore the SELinux security
+          context of a file or directory, if it exists. Lines of this type accept shell-style globs in place
+          of normal path names. Does not follow symlinks.</para></listitem>
         </varlistentry>
 
         <varlistentry>
           <term><varname>Z</varname></term>
-          <listitem><para>Recursively set the access mode, group and
-          user, and restore the SELinux security context of a file or
-          directory if it exists, as well as of its subdirectories and
-          the files contained therein (if applicable). Lines of this
-          type accept shell-style globs in place of normal path
-          names. Does not follow symlinks.  </para></listitem>
+          <listitem><para>Recursively set the access mode, user and group ownership, and restore the SELinux
+          security context of a file or directory if it exists, as well as of its subdirectories and the
+          files contained therein (if applicable). Lines of this type accept shell-style globs in place of
+          normal path names. Does not follow symlinks.</para></listitem>
         </varlistentry>
 
         <varlistentry>
@@ -480,13 +490,14 @@ w- /proc/sys/vm/swappiness - - - - 10</programlisting></para>
     </refsect2>
 
     <refsect2>
-      <title>UID, GID</title>
-
-      <para>The user and group to use for this file or directory. This may either be a numeric user/group ID or a user or group
-      name. If omitted or when set to <literal>-</literal>, the user/group ID of the user who invokes <command>systemd-tmpfiles</command> is used.
-      For <varname>z</varname> and <varname>Z</varname> lines, when omitted or when set to <literal>-</literal>, the file ownership will not be
-      modified. These parameters are ignored for <varname>x</varname>, <varname>r</varname>, <varname>R</varname>, <varname>L</varname>,
-      <varname>t</varname>, and <varname>a</varname> lines.</para>
+      <title>User, Group</title>
+
+      <para>The user and group to use for this file or directory. This may either be a numeric ID or a
+      user/group name. If omitted or when set to <literal>-</literal>, the user and group of the user who
+      invokes <command>systemd-tmpfiles</command> is used. For <varname>z</varname> and <varname>Z</varname>
+      lines, when omitted or when set to <literal>-</literal>, the file ownership will not be modified. These
+      parameters are ignored for <varname>x</varname>, <varname>r</varname>, <varname>R</varname>,
+      <varname>L</varname>, <varname>t</varname>, and <varname>a</varname> lines.</para>
     </refsect2>
 
     <refsect2>
@@ -730,6 +741,13 @@ e! /var/cache/krb5rcache - - - 0
     </example>
   </refsect1>
 
+  <refsect1>
+    <title><filename>/run/</filename> and <filename>/var/run/</filename></title>
+    <para><filename>/var/run/</filename> is a deprecated symlink to <filename>/run/</filename>, and
+    applications should use the latter. <command>systemd-tmpfiles</command> will warn if
+    <filename>/var/run/</filename> is used.</para>
+  </refsect1>
+
   <refsect1>
     <title>See Also</title>
     <para>
index 1f44c0fe70d327f4e84d902cff359e815a203eef..d8e35e618d2507dc7ad4bff5b979314c450d4324 100644 (file)
@@ -694,6 +694,9 @@ else
         conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
 endif
 
+default_net_naming_scheme = get_option('default-net-naming-scheme')
+conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme)
+
 time_epoch = get_option('time-epoch')
 if time_epoch == -1
         NEWS = files('NEWS')
@@ -3093,6 +3096,7 @@ status = [
         'default DNSSEC mode:               @0@'.format(default_dnssec),
         'default DNS-over-TLS mode:         @0@'.format(default_dns_over_tls),
         'default cgroup hierarchy:          @0@'.format(default_hierarchy),
+        'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme),
         'default KillUserProcesses setting: @0@'.format(kill_user_processes)]
 
 alt_dns_servers = '\n                                            '.join(dns_servers.split(' '))
index 62167ae92d6b9f58895ac8919ce54746df3bc1ac..1423b8998e5d3860fa245559ee0b8184764d57e4 100644 (file)
@@ -156,6 +156,9 @@ option('compat-gateway-hostname', type : 'boolean', value : 'false',
 option('default-hierarchy', type : 'combo',
        choices : ['legacy', 'hybrid', 'unified'], value : 'hybrid',
        description : 'default cgroup hierarchy')
+option('default-net-naming-scheme', type : 'combo',
+       choices : ['latest', 'v238', 'v239', 'v240'],
+       description : 'default net.naming-scheme= value')
 option('time-epoch', type : 'integer', value : '-1',
        description : 'time epoch for time clients')
 option('system-uid-max', type : 'integer', value : '-1',
index 4c200f8393e8315637df0c563b13e0725eb06647..11972a621385fba2c4968be76aa12edee5de9940 100644 (file)
@@ -156,7 +156,7 @@ int write_string_file_ts(
                         goto fail;
                 }
 
-                f = fdopen(fd, "we");
+                f = fdopen(fd, "w");
                 if (!f) {
                         r = -errno;
                         safe_close(fd);
index dba0492ba841f79ec0bd5f88e7db23fe8578ebf1..669eb2666cee88979dfb025ecbbbda4b2661b1a2 100644 (file)
@@ -36,7 +36,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
                 return -errno;
         }
 
-        f = fdopen(fd, "we");
+        f = fdopen(fd, "w");
         if (!f) {
                 unlink_noerrno(t);
                 free(t);
index 2008341f631e1132ca6c008195625809cd917c1b..fc4726e69a0993d42fff3805839402a050f78d8a 100644 (file)
@@ -823,7 +823,7 @@ static int install_loader_config(const char *esp_path) {
         if (fd < 0)
                 return log_error_errno(fd, "Failed to open \"%s\" for writing: %m", p);
 
-        f = fdopen(fd, "we");
+        f = fdopen(fd, "w");
         if (!f) {
                 safe_close(fd);
                 return log_oom();
index 55900479767b53483ec1f62075e14f74dc71b3b9..12f9924c17584f69b5d9ba4d371f57407aa537eb 100644 (file)
@@ -1367,14 +1367,8 @@ CGroupMask unit_get_members_mask(Unit *u) {
                 Iterator i;
 
                 HASHMAP_FOREACH_KEY(v, member, u->dependencies[UNIT_BEFORE], i) {
-
-                        if (member == u)
-                                continue;
-
-                        if (UNIT_DEREF(member->slice) != u)
-                                continue;
-
-                        u->cgroup_members_mask |= unit_get_subtree_mask(member); /* note that this calls ourselves again, for the children */
+                        if (UNIT_DEREF(member->slice) == u)
+                                u->cgroup_members_mask |= unit_get_subtree_mask(member); /* note that this calls ourselves again, for the children */
                 }
         }
 
@@ -2120,9 +2114,6 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) {
                 void *v;
 
                 HASHMAP_FOREACH_KEY(v, m, u->dependencies[UNIT_BEFORE], i) {
-                        if (m == u)
-                                continue;
-
                         /* Skip units that have a dependency on the slice
                          * but aren't actually in it. */
                         if (UNIT_DEREF(m->slice) != slice)
@@ -3034,13 +3025,8 @@ void unit_invalidate_cgroup_bpf(Unit *u) {
                 void *v;
 
                 HASHMAP_FOREACH_KEY(v, member, u->dependencies[UNIT_BEFORE], i) {
-                        if (member == u)
-                                continue;
-
-                        if (UNIT_DEREF(member->slice) != u)
-                                continue;
-
-                        unit_invalidate_cgroup_bpf(member);
+                        if (UNIT_DEREF(member->slice) == u)
+                                unit_invalidate_cgroup_bpf(member);
                 }
         }
 }
index c47d1740c8dcdea02d79a02402f13655514d8256..889492aeece01439097c733ad0761f015ce5e045 100644 (file)
@@ -178,7 +178,7 @@ static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) {
          *
          * 1. Initially, we try to read the UID of a number of specified paths. If any of these UIDs works, we use
          *    them. We use in order to increase the chance of UID reuse, if StateDirectory=, CacheDirectory= or
-         *    LogDirectory= are used, as reusing the UID these directories are owned by saves us from having to
+         *    LogsDirectory= are used, as reusing the UID these directories are owned by saves us from having to
          *    recursively chown() them to new users.
          *
          * 2. If that didn't yield a currently unused UID, we hash the user name, and try to use that. This should be
index af5070b8cf9acb3c3802b4fe0bdf0ef5e4be9ab5..f635b7e933af2a8be903db35df7f15a0d4711a43 100644 (file)
@@ -89,7 +89,7 @@ void job_unlink(Job *j) {
         j->timer_event_source = sd_event_source_unref(j->timer_event_source);
 }
 
-void job_free(Job *j) {
+Job* job_free(Job *j) {
         assert(j);
         assert(!j->installed);
         assert(!j->transaction_prev);
@@ -102,7 +102,7 @@ void job_free(Job *j) {
         sd_bus_track_unref(j->bus_track);
         strv_free(j->deserialized_clients);
 
-        free(j);
+        return mfree(j);
 }
 
 static void job_set_state(Job *j, JobState state) {
@@ -151,7 +151,7 @@ void job_uninstall(Job *j) {
 
         unit_add_to_gc_queue(j->unit);
 
-        hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
+        hashmap_remove_value(j->manager->jobs, UINT32_TO_PTR(j->id), j);
         j->installed = false;
 }
 
@@ -244,23 +244,28 @@ Job* job_install(Job *j) {
 
 int job_install_deserialized(Job *j) {
         Job **pj;
+        int r;
 
         assert(!j->installed);
 
         if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION)
-                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EINVAL),
                                        "Invalid job type %s in deserialization.",
                                        strna(job_type_to_string(j->type)));
 
         pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
-        if (*pj) {
-                log_unit_debug(j->unit, "Unit already has a job installed. Not installing deserialized job.");
-                return -EEXIST;
-        }
+        if (*pj)
+                return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EEXIST),
+                                            "Unit already has a job installed. Not installing deserialized job.");
+
+        r = hashmap_put(j->manager->jobs, UINT32_TO_PTR(j->id), j);
+        if (r == -EEXIST)
+                return log_unit_debug_errno(j->unit, r, "Job ID %" PRIu32 " already used, cannot deserialize job.", j->id);
+        if (r < 0)
+                return log_unit_debug_errno(j->unit, r, "Failed to insert job into jobs hash table: %m");
 
         *pj = j;
         j->installed = true;
-        j->reloaded = true;
 
         if (j->state == JOB_RUNNING)
                 j->unit->manager->n_running_jobs++;
@@ -968,19 +973,6 @@ static void job_fail_dependencies(Unit *u, UnitDependency d) {
         }
 }
 
-static int job_save_pending_finished_job(Job *j) {
-        int r;
-
-        assert(j);
-
-        r = set_ensure_allocated(&j->manager->pending_finished_jobs, NULL);
-        if (r < 0)
-                return r;
-
-        job_unlink(j);
-        return set_put(j->manager->pending_finished_jobs, j);
-}
-
 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
         Unit *u;
         Unit *other;
@@ -1020,11 +1012,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
                 j->manager->n_failed_jobs++;
 
         job_uninstall(j);
-        /* Keep jobs started before the reload to send singal later, free all others */
-        if (!MANAGER_IS_RELOADING(j->manager) ||
-            !j->reloaded ||
-            job_save_pending_finished_job(j) < 0)
-                job_free(j);
+        job_free(j);
 
         /* Fail depending jobs on failure */
         if (result != JOB_DONE && recursive) {
index 5f9c14012ff92b22f54f5d387c8ade4ace422a74..1b9bcdd895dcd24a3f6b42d93441e11af4a31764 100644 (file)
@@ -156,13 +156,12 @@ struct Job {
         bool irreversible:1;
         bool in_gc_queue:1;
         bool ref_by_private_bus:1;
-        bool reloaded:1;
 };
 
 Job* job_new(Unit *unit, JobType type);
 Job* job_new_raw(Unit *unit);
 void job_unlink(Job *job);
-void job_free(Job *job);
+Job* job_free(Job *job);
 Job* job_install(Job *j);
 int job_install_deserialized(Job *j);
 void job_uninstall(Job *j);
@@ -223,6 +222,8 @@ void job_add_to_gc_queue(Job *j);
 int job_get_before(Job *j, Job*** ret);
 int job_get_after(Job *j, Job*** ret);
 
+DEFINE_TRIVIAL_CLEANUP_FUNC(Job*, job_free);
+
 const char* job_type_to_string(JobType t) _const_;
 JobType job_type_from_string(const char *s) _pure_;
 
index 36e874de2948cea6e7c5b342c2a75dadd91d690d..fc5644f489690e87ea8a5873248a7fa23ae9b339 100644 (file)
@@ -4415,7 +4415,7 @@ static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
                 free_and_replace(*filename, target);
         }
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f) {
                 safe_close(fd);
                 return -errno;
index 2398dcf4eaea5dbe837b903758c5ee5c1057b1f1..35d9753b1245927a7758b95db6613394819b8896 100644 (file)
@@ -3464,17 +3464,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
         return manager_deserialize_units(m, f, fds);
 }
 
-static void manager_flush_finished_jobs(Manager *m) {
-        Job *j;
-
-        while ((j = set_steal_first(m->pending_finished_jobs))) {
-                bus_job_send_removed_signal(j);
-                job_free(j);
-        }
-
-        m->pending_finished_jobs = set_free(m->pending_finished_jobs);
-}
-
 int manager_reload(Manager *m) {
         _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
         _cleanup_fdset_free_ FDSet *fds = NULL;
@@ -3560,9 +3549,6 @@ int manager_reload(Manager *m) {
 
         manager_ready(m);
 
-        if (!MANAGER_IS_RELOADING(m))
-                manager_flush_finished_jobs(m);
-
         m->send_reloading_done = true;
         return 0;
 }
index f3ad44d26e20445004ecdaa5c17615e580a51845..bce8020cfd4fa32db7dcdd94790cc2d4e96400fb 100644 (file)
@@ -337,9 +337,6 @@ struct Manager {
 
         /* non-zero if we are reloading or reexecuting, */
         int n_reloading;
-        /* A set which contains all jobs that started before reload and finished
-         * during it */
-        Set *pending_finished_jobs;
 
         unsigned n_installed_jobs;
         unsigned n_failed_jobs;
index a686b64e6680f950f027f388166aa740d8b72bd5..3ce6164b06fd0f06bd467ac62a49016ab006a19a 100644 (file)
@@ -11,7 +11,9 @@
 #include "bus-util.h"
 #include "cgroup-util.h"
 #include "dev-setup.h"
+#include "dirent-util.h"
 #include "efivars.h"
+#include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "label.h"
@@ -404,6 +406,100 @@ static int relabel_cgroup_filesystems(void) {
 
         return 0;
 }
+
+static int relabel_extra(void) {
+        _cleanup_closedir_ DIR *d = NULL;
+        int r, c = 0;
+
+        /* Support for relabelling additional files or directories after loading the policy. For this, code in the
+         * initrd simply has to drop in *.relabel files into /run/systemd/relabel-extra.d/. We'll read all such files
+         * expecting one absolute path by line and will relabel each (and everyone below that in case the path refers
+         * to a directory). These drop-in files are supposed to be absolutely minimal, and do not understand comments
+         * and such. After the operation succeeded the files are removed, and the drop-in directory as well, if
+         * possible.
+         */
+
+        d = opendir("/run/systemd/relabel-extra.d/");
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+
+                return log_warning_errno(errno, "Failed to open /run/systemd/relabel-extra.d/, ignoring: %m");
+        }
+
+        for (;;) {
+                _cleanup_fclose_ FILE *f = NULL;
+                _cleanup_close_ int fd = -1;
+                struct dirent *de;
+
+                errno = 0;
+                de = readdir_no_dot(d);
+                if (!de) {
+                        if (errno != 0)
+                                return log_error_errno(errno, "Failed read directory /run/systemd/relabel-extra.d/, ignoring: %m");
+                        break;
+                }
+
+                if (hidden_or_backup_file(de->d_name))
+                        continue;
+
+                if (!endswith(de->d_name, ".relabel"))
+                        continue;
+
+                if (!IN_SET(de->d_type, DT_REG, DT_UNKNOWN))
+                        continue;
+
+                fd = openat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
+                if (fd < 0) {
+                        log_warning_errno(errno, "Failed to open /run/systemd/relabel-extra.d/%s, ignoring: %m", de->d_name);
+                        continue;
+                }
+
+                f = fdopen(fd, "r");
+                if (!f) {
+                        log_warning_errno(errno, "Failed to convert file descriptor into file object, ignoring: %m");
+                        continue;
+                }
+                TAKE_FD(fd);
+
+                for (;;) {
+                        _cleanup_free_ char *line = NULL;
+
+                        r = read_line(f, LONG_LINE_MAX, &line);
+                        if (r < 0) {
+                                log_warning_errno(r, "Failed to read from /run/systemd/relabel-extra.d/%s, ignoring: %m", de->d_name);
+                                break;
+                        }
+                        if (r == 0) /* EOF */
+                                break;
+
+                        path_simplify(line, true);
+
+                        if (!path_is_normalized(line)) {
+                                log_warning("Path to relabel is not normalized, ignoring: %s", line);
+                                continue;
+                        }
+
+                        if (!path_is_absolute(line)) {
+                                log_warning("Path to relabel is not absolute, ignoring: %s", line);
+                                continue;
+                        }
+
+                        log_debug("Relabelling additional file/directory '%s'.", line);
+                        (void) nftw(line, nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+                        c++;
+                }
+
+                if (unlinkat(dirfd(d), de->d_name, 0) < 0)
+                        log_warning_errno(errno, "Failed to remove /run/systemd/relabel-extra.d/%s, ignoring: %m", de->d_name);
+        }
+
+        /* Remove when we completing things. */
+        if (rmdir("/run/systemd/relabel-extra.d") < 0)
+                log_warning_errno(errno, "Failed to remove /run/systemd/relabel-extra.d/ directory: %m");
+
+        return c;
+}
 #endif
 
 int mount_setup(bool loaded_policy) {
@@ -421,20 +517,22 @@ int mount_setup(bool loaded_policy) {
         if (loaded_policy) {
                 usec_t before_relabel, after_relabel;
                 char timespan[FORMAT_TIMESPAN_MAX];
+                const char *i;
+                int n_extra;
 
                 before_relabel = now(CLOCK_MONOTONIC);
 
-                (void) nftw("/dev", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
-                (void) nftw("/dev/shm", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
-                (void) nftw("/run", nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
+                FOREACH_STRING(i, "/dev", "/dev/shm", "/run")
+                        (void) nftw(i, nftw_cb, 64, FTW_MOUNT|FTW_PHYS|FTW_ACTIONRETVAL);
 
-                r = relabel_cgroup_filesystems();
-                if (r < 0)
-                        return r;
+                (void) relabel_cgroup_filesystems();
+
+                n_extra = relabel_extra();
 
                 after_relabel = now(CLOCK_MONOTONIC);
 
-                log_info("Relabelled /dev, /run and /sys/fs/cgroup in %s.",
+                log_info("Relabelled /dev, /dev/shm, /run, /sys/fs/cgroup%s in %s.",
+                         n_extra > 0 ? ", additional files" : "",
                          format_timespan(timespan, sizeof(timespan), after_relabel - before_relabel, 0));
         }
 #endif
index 4bb2051aa3deb93590b064868e887247b9f1bf9f..49b37aefc723aa128540b6ad8d70cb87bf1e898a 100644 (file)
@@ -72,7 +72,7 @@ static int write_access2_rules(const char* srcdir) {
                         continue;
                 }
 
-                policy = fdopen(fd, "re");
+                policy = fdopen(fd, "r");
                 if (!policy) {
                         if (r == 0)
                                 r = -errno;
@@ -154,7 +154,7 @@ static int write_cipso2_rules(const char* srcdir) {
                         continue;
                 }
 
-                policy = fdopen(fd, "re");
+                policy = fdopen(fd, "r");
                 if (!policy) {
                         if (r == 0)
                                 r = -errno;
@@ -227,7 +227,7 @@ static int write_netlabel_rules(const char* srcdir) {
                         continue;
                 }
 
-                policy = fdopen(fd, "re");
+                policy = fdopen(fd, "r");
                 if (!policy) {
                         if (r == 0)
                                 r = -errno;
index a9303a0f3f28335c6c491711884dad05494df17a..171567022facf098926b9ed783fc4f8b53f5a1ed 100644 (file)
@@ -2328,8 +2328,74 @@ static void unit_emit_audit_stop(Unit *u, UnitActiveState state) {
         }
 }
 
+static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags) {
+        bool unexpected = false;
+
+        assert(j);
+
+        if (j->state == JOB_WAITING)
+
+                /* So we reached a different state for this job. Let's see if we can run it now if it failed previously
+                 * due to EAGAIN. */
+                job_add_to_run_queue(j);
+
+        /* Let's check whether the unit's new state constitutes a finished job, or maybe contradicts a running job and
+         * hence needs to invalidate jobs. */
+
+        switch (j->type) {
+
+        case JOB_START:
+        case JOB_VERIFY_ACTIVE:
+
+                if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
+                        job_finish_and_invalidate(j, JOB_DONE, true, false);
+                else if (j->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
+                        unexpected = true;
+
+                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                                job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false);
+                }
+
+                break;
+
+        case JOB_RELOAD:
+        case JOB_RELOAD_OR_START:
+        case JOB_TRY_RELOAD:
+
+                if (j->state == JOB_RUNNING) {
+                        if (ns == UNIT_ACTIVE)
+                                job_finish_and_invalidate(j, (flags & UNIT_NOTIFY_RELOAD_FAILURE) ? JOB_FAILED : JOB_DONE, true, false);
+                        else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING)) {
+                                unexpected = true;
+
+                                if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                                        job_finish_and_invalidate(j, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false);
+                        }
+                }
+
+                break;
+
+        case JOB_STOP:
+        case JOB_RESTART:
+        case JOB_TRY_RESTART:
+
+                if (UNIT_IS_INACTIVE_OR_FAILED(ns))
+                        job_finish_and_invalidate(j, JOB_DONE, true, false);
+                else if (j->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
+                        unexpected = true;
+                        job_finish_and_invalidate(j, JOB_FAILED, true, false);
+                }
+
+                break;
+
+        default:
+                assert_not_reached("Job type unknown");
+        }
+
+        return unexpected;
+}
+
 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags) {
-        bool unexpected;
         const char *reason;
         Manager *m;
 
@@ -2373,81 +2439,18 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
 
         unit_update_on_console(u);
 
-        if (u->job) {
-                unexpected = false;
-
-                if (u->job->state == JOB_WAITING)
-
-                        /* So we reached a different state for this
-                         * job. Let's see if we can run it now if it
-                         * failed previously due to EAGAIN. */
-                        job_add_to_run_queue(u->job);
-
-                /* Let's check whether this state change constitutes a
-                 * finished job, or maybe contradicts a running job and
-                 * hence needs to invalidate jobs. */
-
-                switch (u->job->type) {
-
-                case JOB_START:
-                case JOB_VERIFY_ACTIVE:
-
-                        if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
-                                job_finish_and_invalidate(u->job, JOB_DONE, true, false);
-                        else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
-                                unexpected = true;
-
-                                if (UNIT_IS_INACTIVE_OR_FAILED(ns))
-                                        job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false);
-                        }
-
-                        break;
-
-                case JOB_RELOAD:
-                case JOB_RELOAD_OR_START:
-                case JOB_TRY_RELOAD:
-
-                        if (u->job->state == JOB_RUNNING) {
-                                if (ns == UNIT_ACTIVE)
-                                        job_finish_and_invalidate(u->job, (flags & UNIT_NOTIFY_RELOAD_FAILURE) ? JOB_FAILED : JOB_DONE, true, false);
-                                else if (!IN_SET(ns, UNIT_ACTIVATING, UNIT_RELOADING)) {
-                                        unexpected = true;
-
-                                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
-                                                job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true, false);
-                                }
-                        }
-
-                        break;
-
-                case JOB_STOP:
-                case JOB_RESTART:
-                case JOB_TRY_RESTART:
-
-                        if (UNIT_IS_INACTIVE_OR_FAILED(ns))
-                                job_finish_and_invalidate(u->job, JOB_DONE, true, false);
-                        else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
-                                unexpected = true;
-                                job_finish_and_invalidate(u->job, JOB_FAILED, true, false);
-                        }
-
-                        break;
-
-                default:
-                        assert_not_reached("Job type unknown");
-                }
-
-        } else
-                unexpected = true;
-
         if (!MANAGER_IS_RELOADING(m)) {
+                bool unexpected;
 
-                /* If this state change happened without being
-                 * requested by a job, then let's retroactively start
-                 * or stop dependencies. We skip that step when
-                 * deserializing, since we don't want to create any
-                 * additional jobs just because something is already
-                 * activated. */
+                /* Let's propagate state changes to the job */
+                if (u->job)
+                        unexpected = unit_process_job(u->job, ns, flags);
+                else
+                        unexpected = true;
+
+                /* If this state change happened without being requested by a job, then let's retroactively start or
+                 * stop dependencies. We skip that step when deserializing, since we don't want to create any
+                 * additional jobs just because something is already activated. */
 
                 if (unexpected) {
                         if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
@@ -3288,6 +3291,29 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
         return 0;
 }
 
+static int unit_deserialize_job(Unit *u, FILE *f) {
+        _cleanup_(job_freep) Job *j = NULL;
+        int r;
+
+        assert(u);
+        assert(f);
+
+        j = job_new_raw(u);
+        if (!j)
+                return log_oom();
+
+        r = job_deserialize(j, f);
+        if (r < 0)
+                return r;
+
+        r = job_install_deserialized(j);
+        if (r < 0)
+                return r;
+
+        TAKE_PTR(j);
+        return 0;
+}
+
 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
         int r;
 
@@ -3321,32 +3347,11 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
 
                 if (streq(l, "job")) {
                         if (v[0] == '\0') {
-                                /* new-style serialized job */
-                                Job *j;
-
-                                j = job_new_raw(u);
-                                if (!j)
-                                        return log_oom();
-
-                                r = job_deserialize(j, f);
-                                if (r < 0) {
-                                        job_free(j);
-                                        return r;
-                                }
-
-                                r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
-                                if (r < 0) {
-                                        job_free(j);
-                                        return r;
-                                }
-
-                                r = job_install_deserialized(j);
-                                if (r < 0) {
-                                        hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
-                                        job_free(j);
+                                /* New-style serialized job */
+                                r = unit_deserialize_job(u, f);
+                                if (r < 0)
                                         return r;
-                                }
-                        } else  /* legacy for pre-44 */
+                        } else  /* Legacy for pre-44 */
                                 log_unit_warning(u, "Update from too old systemd versions are unsupported, cannot deserialize job: %s", v);
                         continue;
                 } else if (streq(l, "state-change-timestamp")) {
index e300cc4f2fef413530cbb7e711cd7e01b336edda..312742f11b591ed9be2f03eabc3c129af12f60ba 100644 (file)
@@ -433,11 +433,16 @@ typedef struct UnitVTable {
         int (*load)(Unit *u);
 
         /* During deserialization we only record the intended state to return to. With coldplug() we actually put the
-         * deserialized state in effect. This is where unit_notify() should be called to start things up. */
+         * deserialized state in effect. This is where unit_notify() should be called to start things up. Note that
+         * this callback is invoked *before* we leave the reloading state of the manager, i.e. *before* we consider the
+         * reloading to be complete. Thus, this callback should just restore the exact same state for any unit that was
+         * in effect before the reload, i.e. units should not catch up with changes happened during the reload. That's
+         * what catchup() below is for. */
         int (*coldplug)(Unit *u);
 
-        /* This is called shortly after all units' coldplug() call was invoked. It's supposed to catch up state changes
-         * we missed so far (for example because they took place while we were reloading/reexecing) */
+        /* This is called shortly after all units' coldplug() call was invoked, and *after* the manager left the
+         * reloading state. It's supposed to catch up with state changes due to external events we missed so far (for
+         * example because they took place while we were reloading/reexecing) */
         void (*catchup)(Unit *u);
 
         void (*dump)(Unit *u, FILE *f, const char *prefix);
index 79d627c465cf28e3bf25a4412453a14af974091b..0c888b26f9ca158f78c4ef4f6ac229f0050dcb35 100644 (file)
@@ -553,7 +553,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
                 if (fd < 0)
                         continue;
 
-                fdinfo = fdopen(fd, "re");
+                fdinfo = fdopen(fd, "r");
                 if (!fdinfo) {
                         safe_close(fd);
                         continue;
index 7fc4a283ce838ff762a1a7f91ef82261739a06e3..ba39f596fc75b4a320a5ec3d127fc927cd3d14b0 100644 (file)
@@ -177,7 +177,7 @@ static int process_progress(int fd) {
         if (fd < 0)
                 return 0;
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f) {
                 safe_close(fd);
                 return -errno;
index 285918b4cc5c63f9badd98718a8371924e953ac9..48270b3709af628d910d997f6a5d0f9b33c698af 100644 (file)
@@ -370,7 +370,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
 
                 pair[1] = safe_close(pair[1]);
 
-                f = fdopen(pair[0], "re");
+                f = fdopen(pair[0], "r");
                 if (!f)
                         return -errno;
 
index d613414fded43b55efb3b0b6d842c2a6f1add0e5..9afae72ae5f231f80ae86ce4210ed7b3a9d49596 100644 (file)
@@ -615,7 +615,7 @@ static int clean_pool_done(Operation *operation, int ret, sd_bus_error *error) {
         if (lseek(operation->extra_fd, 0, SEEK_SET) == (off_t) -1)
                 return -errno;
 
-        f = fdopen(operation->extra_fd, "re");
+        f = fdopen(operation->extra_fd, "r");
         if (!f)
                 return -errno;
 
index f80f3c09a90f0b5f1c03165b34ef18c45c4c3d44..57bfb6af6802f5d98212eb3624f23295837cece0 100644 (file)
@@ -28,14 +28,14 @@ static void test_rule_serialization(const char *title, const char *ruleset, cons
 
         fd = mkostemp_safe(pattern);
         assert_se(fd >= 0);
-        assert_se(f = fdopen(fd, "a+e"));
+        assert_se(f = fdopen(fd, "a+"));
         assert_se(write_string_stream(f, ruleset, 0) == 0);
 
         assert_se(routing_policy_load_rules(pattern, &rules) == 0);
 
         fd2 = mkostemp_safe(pattern2);
         assert_se(fd2 >= 0);
-        assert_se(f2 = fdopen(fd2, "a+e"));
+        assert_se(f2 = fdopen(fd2, "a+"));
 
         assert_se(routing_policy_serialize_rules(rules, f2) == 0);
         assert_se(fflush_and_check(f2) == 0);
@@ -46,7 +46,7 @@ static void test_rule_serialization(const char *title, const char *ruleset, cons
 
         fd3 = mkostemp_safe(pattern3);
         assert_se(fd3 >= 0);
-        assert_se(f3 = fdopen(fd3, "we"));
+        assert_se(f3 = fdopen(fd3, "w"));
         assert_se(write_string_stream(f3, expected ?: ruleset, 0) == 0);
 
         cmd = strjoina("diff -u ", pattern3, " ", pattern2);
index 86fd9deec0fee11dd533d8a45589fd977639eabd..0026e4e3fc7a7dfe94d0f4f629cc40256294be47 100644 (file)
@@ -91,7 +91,7 @@ int change_uid_gid(const char *user, char **_home) {
         if (fd < 0)
                 return fd;
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f)
                 return log_oom();
         fd = -1;
@@ -164,7 +164,7 @@ int change_uid_gid(const char *user, char **_home) {
         if (fd < 0)
                 return fd;
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f)
                 return log_oom();
         fd = -1;
index 5b62486ea9eb023409c11c0219ea717f1a2ddefe..920bd866f56927dd959015970fcc1e5be4fcd114 100644 (file)
@@ -1089,7 +1089,7 @@ static int test_chroot_dropin(
                 return log_debug_errno(errno, "Failed to open %s/%s: %m", where, p);
         }
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f)
                 return log_debug_errno(errno, "Failed to convert file handle: %m");
         fd = -1;
index 1e618175c72b24299e0c351578d320f9ab4e1f12..360559811fa72393215f9f70ba2255897541333c 100644 (file)
@@ -73,7 +73,7 @@ static int append_fd(sd_bus_message *m, PortableMetadata *d) {
         assert(d);
         assert(d->fd >= 0);
 
-        f = fdopen(d->fd, "re");
+        f = fdopen(d->fd, "r");
         if (!f)
                 return -errno;
 
index 1f8c47ccbebe0a4bb03055292dbcc863a56419d3..b7dc09ae370ac7788d910e60dd1f5f8141c5f263 100644 (file)
@@ -580,7 +580,7 @@ int manager_new(Manager **ret) {
                 .dnssec_mode = DEFAULT_DNSSEC_MODE,
                 .dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
                 .enable_cache = true,
-                .dns_stub_listener_mode = DNS_STUB_LISTENER_UDP,
+                .dns_stub_listener_mode = DNS_STUB_LISTENER_YES,
                 .read_resolv_conf = true,
                 .need_builtin_fallbacks = true,
                 .etc_hosts_last = USEC_INFINITY,
index e559291f66ca88187203b106064851bcb253b2ab..6898c7848be92c1181824e04a4a9cc7c09e4e1de 100644 (file)
@@ -20,5 +20,5 @@
 #DNSSEC=@DEFAULT_DNSSEC_MODE@
 #DNSOverTLS=@DEFAULT_DNS_OVER_TLS_MODE@
 #Cache=yes
-#DNSStubListener=udp
+#DNSStubListener=yes
 #ReadEtcHosts=yes
index 4e572ac861c5a18c24b633f593ee46888b9b16b9..6ea8e4df8d942aaa099bffeb1c36c4b2f9844e6b 100644 (file)
@@ -1300,7 +1300,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
 
                 fds[2*k+1] = safe_close(fds[2*k+1]);
 
-                f = fdopen(fds[2*k], "re");
+                f = fdopen(fds[2*k], "r");
                 if (!f) {
                         r = -errno;
                         goto finish;
index d66b3004590a12495759cb6d50167b06db27f27d..17a278a00fcc98e8c4c6d2d4a6440a40fc58bc1a 100644 (file)
@@ -308,7 +308,7 @@ static int gather_environment_consume(int fd, void *arg) {
 
         assert(env);
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f) {
                 safe_close(fd);
                 return -errno;
index d172162a3c3121e74defa18a0772df920a439f43..51d33b80e9871799a921eb4ad8949f173c705d00 100644 (file)
@@ -1286,7 +1286,7 @@ static int unit_file_load(
         if (r < 0)
                 return r;
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f)
                 return -errno;
         fd = -1;
@@ -1939,6 +1939,7 @@ static int install_context_mark_for_removal(
                 InstallContext *c,
                 const LookupPaths *paths,
                 Set **remove_symlinks_to,
+                const char *config_path,
                 UnitFileChange **changes,
                 size_t *n_changes) {
 
@@ -1947,6 +1948,7 @@ static int install_context_mark_for_removal(
 
         assert(c);
         assert(paths);
+        assert(config_path);
 
         /* Marks all items for removal */
 
@@ -2056,7 +2058,7 @@ int unit_file_unmask(
         size_t n_todo = 0, n_allocated = 0;
         const char *config_path;
         char **i;
-        bool dry_run = !!(flags & UNIT_FILE_DRY_RUN);
+        bool dry_run;
         int r, q;
 
         assert(scope >= 0);
@@ -2066,71 +2068,73 @@ int unit_file_unmask(
         if (r < 0)
                 return r;
 
+        config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+        if (!config_path)
+                return -ENXIO;
+
+        dry_run = !!(flags & UNIT_FILE_DRY_RUN);
+
         STRV_FOREACH(i, files) {
+                _cleanup_free_ char *path = NULL;
+
                 if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
                         return -EINVAL;
 
-                FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
-                        _cleanup_free_ char *path = NULL;
-
-                        path = path_make_absolute(*i, config_path);
-                        if (!path)
-                                return -ENOMEM;
+                path = path_make_absolute(*i, config_path);
+                if (!path)
+                        return -ENOMEM;
 
-                        r = null_or_empty_path(path);
-                        if (r == -ENOENT)
-                                continue;
-                        if (r < 0)
-                                return r;
-                        if (r == 0)
-                                continue;
+                r = null_or_empty_path(path);
+                if (r == -ENOENT)
+                        continue;
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        continue;
 
-                        if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
-                                return -ENOMEM;
+                if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
+                        return -ENOMEM;
 
-                        todo[n_todo] = strdup(*i);
-                        if (!todo[n_todo])
-                                return -ENOMEM;
+                todo[n_todo] = strdup(*i);
+                if (!todo[n_todo])
+                        return -ENOMEM;
 
-                        n_todo++;
-                }
+                n_todo++;
         }
 
         strv_uniq(todo);
 
         r = 0;
-        FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
-                STRV_FOREACH(i, todo) {
-                        _cleanup_free_ char *path = NULL;
-                        const char *rp;
-
-                        path = path_make_absolute(*i, config_path);
-                        if (!path)
-                                return -ENOMEM;
+        STRV_FOREACH(i, todo) {
+                _cleanup_free_ char *path = NULL;
+                const char *rp;
 
-                        if (!dry_run && unlink(path) < 0) {
-                                if (errno != ENOENT) {
-                                        if (r >= 0)
-                                                r = -errno;
-                                        unit_file_changes_add(changes, n_changes, -errno, path, NULL);
-                                }
+                path = path_make_absolute(*i, config_path);
+                if (!path)
+                        return -ENOMEM;
 
-                                continue;
+                if (!dry_run && unlink(path) < 0) {
+                        if (errno != ENOENT) {
+                                if (r >= 0)
+                                        r = -errno;
+                                unit_file_changes_add(changes, n_changes, -errno, path, NULL);
                         }
 
-                        unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
-
-                        rp = skip_root(&paths, path);
-                        q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
-                        if (q < 0)
-                                return q;
+                        continue;
                 }
 
-                q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
-                if (r >= 0)
-                        r = q;
+                unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
+
+                rp = skip_root(&paths, path);
+                q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
+                if (q < 0)
+                        return q;
         }
 
+        q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
+        if (r >= 0)
+                r = q;
+
         return r;
 }
 
@@ -2513,7 +2517,6 @@ int unit_file_disable(
         _cleanup_(lookup_paths_free) LookupPaths paths = {};
         _cleanup_(install_context_done) InstallContext c = {};
         _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
-        bool dry_run = !!(flags & UNIT_FILE_DRY_RUN);
         const char *config_path;
         char **i;
         int r;
@@ -2525,6 +2528,10 @@ int unit_file_disable(
         if (r < 0)
                 return r;
 
+        config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+        if (!config_path)
+                return -ENXIO;
+
         STRV_FOREACH(i, files) {
                 if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
                         return -EINVAL;
@@ -2534,17 +2541,11 @@ int unit_file_disable(
                         return r;
         }
 
-        r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, changes, n_changes);
+        r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes);
         if (r < 0)
                 return r;
 
-        FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
-                r = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
+        return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, !!(flags & UNIT_FILE_DRY_RUN), changes, n_changes);
 }
 
 int unit_file_reenable(
@@ -3029,45 +3030,45 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
 
 static int execute_preset(
                 UnitFileScope scope,
-                UnitFileFlags flags,
                 InstallContext *plus,
                 InstallContext *minus,
                 const LookupPaths *paths,
+                const char *config_path,
                 char **files,
                 UnitFilePresetMode mode,
+                bool force,
                 UnitFileChange **changes,
                 size_t *n_changes) {
 
-        const char *config_path;
-        bool force = !!(flags & UNIT_FILE_FORCE);
-        bool runtime = !!(flags & UNIT_FILE_RUNTIME);
-        int r = 0, q;
+        int r;
 
         assert(plus);
         assert(minus);
         assert(paths);
+        assert(config_path);
 
         if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
                 _cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
 
-                q = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, changes, n_changes);
-                if (q < 0)
-                        return q;
+                r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes);
+                if (r < 0)
+                        return r;
 
-                FOREACH_STRING(config_path, paths->runtime_config, paths->persistent_config) {
-                        q = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
-                        if (r == 0)
-                                r = q;
-                }
-        }
+                r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
+        } else
+                r = 0;
 
         if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
+                int q;
+
                 /* Returns number of symlinks that where supposed to be installed. */
-                q = install_context_apply(scope, plus, paths,
-                                          runtime ? paths->runtime_config : paths->persistent_config,
-                                          force, SEARCH_LOAD, changes, n_changes);
-                if (r == 0)
-                        r = q;
+                q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
+                if (r >= 0) {
+                        if (q < 0)
+                                r = q;
+                        else
+                                r += q;
+                }
         }
 
         return r;
@@ -3139,6 +3140,7 @@ int unit_file_preset(
         _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
         _cleanup_(lookup_paths_free) LookupPaths paths = {};
         _cleanup_(presets_freep) Presets presets = {};
+        const char *config_path;
         char **i;
         int r;
 
@@ -3150,6 +3152,10 @@ int unit_file_preset(
         if (r < 0)
                 return r;
 
+        config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+        if (!config_path)
+                return -ENXIO;
+
         r = read_presets(scope, root_dir, &presets);
         if (r < 0)
                 return r;
@@ -3160,7 +3166,7 @@ int unit_file_preset(
                         return r;
         }
 
-        return execute_preset(scope, flags, &plus, &minus, &paths, files, mode, changes, n_changes);
+        return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
 }
 
 int unit_file_preset_all(
@@ -3174,6 +3180,7 @@ int unit_file_preset_all(
         _cleanup_(install_context_done) InstallContext plus = {}, minus = {};
         _cleanup_(lookup_paths_free) LookupPaths paths = {};
         _cleanup_(presets_freep) Presets presets = {};
+        const char *config_path = NULL;
         char **i;
         int r;
 
@@ -3185,6 +3192,10 @@ int unit_file_preset_all(
         if (r < 0)
                 return r;
 
+        config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
+        if (!config_path)
+                return -ENXIO;
+
         r = read_presets(scope, root_dir, &presets);
         if (r < 0)
                 return r;
@@ -3202,6 +3213,7 @@ int unit_file_preset_all(
                 }
 
                 FOREACH_DIRENT(de, d, return -errno) {
+
                         if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
                                 continue;
 
@@ -3225,7 +3237,7 @@ int unit_file_preset_all(
                 }
         }
 
-        return execute_preset(scope, flags, &plus, &minus, &paths, NULL, mode, changes, n_changes);
+        return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
 }
 
 static void unit_file_list_free_one(UnitFileList *f) {
index f7d46d3c477969e61af4a35a070e67b858cb9cfb..b2d5ce32e7771c89645d94efaa3bab898e016248 100644 (file)
@@ -74,7 +74,7 @@ int fopen_os_release(const char *root, char **ret_path, FILE **ret_file) {
         if (r < 0)
                 return r;
 
-        f = fdopen(fd, "re");
+        f = fdopen(fd, "r");
         if (!f)
                 return -errno;
         fd = -1;
index 40fcb2cae3ef962b3970516385972dc050af5206..dcea9d22a4b14bb72743d515c09870c70f4e4c1d 100644 (file)
@@ -7919,11 +7919,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                        "--wait may not be combined with --no-block.");
 
-        if (arg_runtime && STRPTR_IN_SET(argv[optind], "disable", "unmask", "preset", "preset-all"))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "--runtime cannot be used with %s",
-                                       argv[optind]);
-
         return 1;
 }
 
index 24b103bbb7473400fa8700f3ff3339c296dce202..1e7b26276a9f61a2d0f8d65bc952b7fc812fa7c5 100644 (file)
@@ -283,12 +283,27 @@ static int set_ntp(int argc, char **argv, void *userdata) {
 }
 
 static int list_timezones(int argc, char **argv, void *userdata) {
-        _cleanup_strv_free_ char **zones = NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        sd_bus *bus = userdata;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         int r;
+        char** zones;
+
+        r = sd_bus_call_method(bus,
+                               "org.freedesktop.timedate1",
+                               "/org/freedesktop/timedate1",
+                               "org.freedesktop.timedate1",
+                               "ListTimezones",
+                               &error,
+                               &reply,
+                               NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to request list of time zones: %s",
+                                       bus_error_message(&error, r));
 
-        r = get_timezones(&zones);
+        r = sd_bus_message_read_strv(reply, &zones);
         if (r < 0)
-                return log_error_errno(r, "Failed to read list of time zones: %m");
+                return bus_log_parse_error(r);
 
         (void) pager_open(arg_pager_flags);
         strv_print(zones);
index 5a432fea248c0c13496a9eb996ca55428603fe6b..e16888945c156fd69e771f9e972a1fcaba4aaf4d 100644 (file)
@@ -916,6 +916,28 @@ static int method_set_ntp(sd_bus_message *m, void *userdata, sd_bus_error *error
         return sd_bus_reply_method_return(m, NULL);
 }
 
+static int method_list_timezones(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+        _cleanup_strv_free_ char **zones = NULL;
+        int r;
+
+        assert(m);
+
+        r = get_timezones(&zones);
+        if (r < 0)
+                return sd_bus_error_set_errnof(error, r, "Failed to read list of time zones: %m");
+
+        r = sd_bus_message_new_method_return(m, &reply);
+        if (r < 0)
+                return r;
+
+        r = sd_bus_message_append_strv(reply, zones);
+        if (r < 0)
+                return r;
+
+        return sd_bus_send(NULL, reply, NULL);
+}
+
 static const sd_bus_vtable timedate_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("Timezone", "s", NULL, offsetof(Context, zone), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -929,6 +951,7 @@ static const sd_bus_vtable timedate_vtable[] = {
         SD_BUS_METHOD("SetTimezone", "sb", NULL, method_set_timezone, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetLocalRTC", "bbb", NULL, method_set_local_rtc, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("SetNTP", "bb", NULL, method_set_ntp, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("ListTimezones", NULL, "as", method_list_timezones, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_VTABLE_END,
 };
 
index 18d8d3b8e8e6f4303adff7586ef9a545170d3309..0292c4973c8b4c7f05e09f1a67aa0a2f69c13178 100644 (file)
@@ -193,6 +193,19 @@ struct virtfn_info {
         char suffix[IFNAMSIZ];
 };
 
+static const NamingScheme* naming_scheme_from_name(const char *name) {
+        size_t i;
+
+        if (streq(name, "latest"))
+                return naming_schemes + ELEMENTSOF(naming_schemes) - 1;
+
+        for (i = 0; i < ELEMENTSOF(naming_schemes); i++)
+                if (streq(naming_schemes[i].name, name))
+                        return naming_schemes + i;
+
+        return NULL;
+}
+
 static const NamingScheme* naming_scheme(void) {
         static const NamingScheme *cache = NULL;
         _cleanup_free_ char *buffer = NULL;
@@ -216,24 +229,18 @@ static const NamingScheme* naming_scheme(void) {
                 k = buffer;
 
         if (k) {
-                size_t i;
-
-                for (i = 0; i < ELEMENTSOF(naming_schemes); i++)
-                        if (streq(naming_schemes[i].name, k)) {
-                                cache = naming_schemes + i;
-                                break;
-                        }
+                cache = naming_scheme_from_name(k);
+                if (cache) {
+                        log_info("Using interface naming scheme '%s'.", cache->name);
+                        return cache;
+                }
 
-                if (!cache)
-                        log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k);
+                log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k);
         }
 
-        if (cache)
-                log_info("Using interface naming scheme '%s'.", cache->name);
-        else {
-                cache = naming_schemes + ELEMENTSOF(naming_schemes) - 1;
-                log_info("Using default interface naming scheme '%s'.", cache->name);
-        }
+        cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME);
+        assert(cache);
+        log_info("Using default interface naming scheme '%s'.", cache->name);
 
         return cache;
 }
index efaa8c28d390e9549e167abc11b204d358fb8a03..ebdeba3e8e93dda1199ccdaf1db57fcae3bca6ba 100644 (file)
@@ -298,14 +298,28 @@ static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) {
 
                 r = ioctl(fd_d, KDFONTOP, &cfo);
                 if (r < 0) {
-                        log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%u: %m", i);
+                        int last_errno, mode;
+
+                        /* The fonts couldn't have been copied. It might be due to the
+                         * terminal being in graphical mode. In this case the kernel
+                         * returns -EINVAL which is too generic for distinguishing this
+                         * specific case. So we need to retrieve the terminal mode and if
+                         * the graphical mode is in used, let's assume that something else
+                         * is using the terminal and the failure was expected as we
+                         * shouldn't have tried to copy the fonts. */
+
+                        last_errno = errno;
+                        if (ioctl(fd_d, KDGETMODE, &mode) >= 0 && mode != KD_TEXT)
+                                log_debug("KD_FONT_OP_SET skipped: tty%u is not in text mode", i);
+                        else
+                                log_warning_errno(last_errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%u: %m", i);
+
                         continue;
                 }
 
                 /*
-                 * copy unicode translation table
-                 * unimapd is a ushort count and a pointer to an
-                 * array of struct unipair { ushort, ushort }
+                 * copy unicode translation table unimapd is a ushort count and a pointer
+                 * to an array of struct unipair { ushort, ushort }
                  */
                 r = ioctl(fd_d, PIO_UNIMAPCLR, &adv);
                 if (r < 0) {