diff options
70 files changed, 776 insertions, 284 deletions
diff --git a/.gitignore b/.gitignore index 565a3a3839..c925f19f41 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ /exported /exported-* /hostnamectl +/image.raw /install-tree /journalctl /libtool diff --git a/Makefile.am b/Makefile.am index 3a617560e0..946af196f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5650,6 +5650,8 @@ libnetworkd_core_la_SOURCES = \ src/network/networkd-netdev-bond.c \ src/network/networkd-netdev-bridge.h \ src/network/networkd-netdev-bridge.c \ + src/network/networkd-netdev-vcan.h \ + src/network/networkd-netdev-vcan.c \ src/network/networkd-link-bus.c \ src/network/networkd-ipv4ll.c \ src/network/networkd-dhcp4.c \ @@ -2,11 +2,141 @@ systemd System and Service Manager CHANGES WITH 232 in spe + * The new RemoveIPC= option can be used to remove IPC objects owned by + the user or group of a service when that service exits. + + * Support for dynamically creating users for the lifetime of a service + has been added. If DynamicUser=yes is specified, user and group IDs + will be allocated from the range 61184..65519 for the lifetime of the + service. They can be resolved using the new nss-systemd.so NSS + module. The module must be enabled in /etc/nsswitch.conf. Services + started in this way have PrivateTmp= and RemoveIPC= enabled, so that + any resources allocated by the service will be cleaned up when the + service exits. + + The nss-systemd module also always resolves root and nobody, making + it possible to have no /etc/passwd or /etc/group files in minimal + container systems. + + * Services may be started with their own user namespace using the new + PrivateUsers= option. Only root, nobody, and the uid/gid under which + the service is running are mapped. All other users are mapped to + nobody. + + * Support for the cgroup namespace has been added to systemd-nspawn. If + supported by kernel, the container system started by systemd-nspawn + will have its own view of the cgroup hierarchy. This new behaviour + can be disabled using $SYSTEMD_NSPAWN_USE_CGNS environment variable. + + * The new MemorySwapMax= option can be used to limit the maximum swap + usage under the unified cgroup hierarchy. + + * Support for the CPU controller in the unified cgroup hierarchy has + been added, via the CPUWeight=, CPUStartupWeight=, CPUAccounting= + options. This controller requires out-of-tree patches for the kernel + and the support is provisional. + + * .automount units may now be transient. + + * systemd-mount is a new tool which wraps mount(8) to pull in + additional dependencies through transient .mount and .automount + units. For example, this automatically runs fsck on the block device + before mounting, and allows the automount logic to be used. + + * LazyUnmount=yes option for mount units has been added to expose the + umount --lazy option. Similarly, ForceUnmount=yes exposes the --force + option. + + * /efi will be used as the mount point of the EFI boot partition, if + the directory is present, and the mount point was not configured + through other means (e.g. fstab). If /efi directory does not exist, + /boot will be used as before. This makes it easier to automatically + mount the EFI partition on systems where /boot is used for something + else. + + * disk/by-id symlinks are now created for NVMe drives. + + * Two new user session targets have been added to support running + graphical sessions under the systemd --user instance: + graphical-session.target and graphical-session-pre.target. See + systemd.special(7) for a description of how those targets should be + used. + + * The vconsole initialization code has been significantly reworked to + use KD_FONT_OP_GET/SET ioctls insteads of KD_FONT_OP_COPY and better + support unicode keymaps. Font and keymap configuration will now be + copied to all allocated virtual consoles. + + * FreeBSD's bhyve virtiualization is now detected. + + * Information recored in the journal for core dumps now includes the + contents of /proc/mountinfo and the command line of the process at + the top of the process hierarchy (which is usually the init process + of the container). + + * systemd-journal-gatewayd learned the --directory option to serve + files from the specified location. + + * journalctl --root=… can be used to peruse the journal in the + /var/log/ directories inside of a container tree. This is similar to + the existing --machine= option, but does not require the container to + be active. + + * The hardware database has been extended to support + ID_INPUT_TRACKBALL, used in addition to ID_INPUT_MOUSE to identify + trackball devices. + + MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL hwdb property has been added to + specify the click rate for mice which include a horizontal wheel with + a click rate that is different than the one for the vertical wheel. + + * systemd-run gained a new --wait option that makes service execution + synchronous. + + * A new journal output mode "short-full" has been added which uses + timestamps with abbreviated English day names and adds a timezone + suffix. Those timestamps include more information and can be parsed + by journalctl. + + * /etc/resolv.conf will be bind-mounted into containers started by + systemd-nspawn, if possible, so any changes to resolv.conf contents + are automatically propagated to the container. + + * The number of instances for socket-activated services originating + from a single IP can be limited with MaxConnectionsPerSource=, + extending the existing setting of MaxConnections. + + * UDP Segmentation Offload, TCP Segmentation Offload, Generic + Segmentation Offload, Generic Receive Offload, Large Receive Offload + can be enabled and disabled using the new UDPSegmentationOffload=, + TCPSegmentationOffload=, GenericSegmentationOffload=, + GenericReceiveOffload=, LargeReceiveOffload= options in the + [Link] section of .link files. + + Spanning Tree Protocol enablement, Priority, Aging Time, and the + Default Port VLAN ID can be configured for bridge devices using the + new STP=, Priority=, AgeingTimeSec=, and DefaultPVID= settings in the + [Bridge] section of .netdev files. + + Address Resolution Protocol can be disabled on links managed by + systemd-networkd using the ARP=no setting in the [Link] section of + .network files. + + * $SERVICE_RESULT, $EXIT_CODE, $EXIT_STATUS are set for ExecStop= and + ExecStopPost= commands. + * Journald's SplitMode=login setting has been deprecated. It has been removed from documentation, and it's use is discouraged. In a future release it will be completely removed, and made equivalent to current default of SplitMode=uid. + * The --share-system systemd-nspawn option has been replaced with an + (undocumented) variable $SYSTEMD_NSPAWN_SHARE_SYSTEM, but the use of + this functionality is discouraged. In addition the variables + $SYSTEMD_NSPAWN_SHARE_NS_IPC, $SYSTEMD_NSPAWN_SHARE_NS_PID, + $SYSTEMD_NSPAWN_SHARE_NS_UTS may be used to control the unsharing of + individual namespaces. + CHANGES WITH 231: * In service units the various ExecXYZ= settings have been extended @@ -223,6 +353,9 @@ CHANGES WITH 231: local changes made to systemd in a pristine, defined environment. See HACKING for details. + * configure learned the --with-support-url= option to specify the + distribution's bugtracker. + Contributions from: Alban Crequy, Alessandro Puccetti, Alessio Igor Bogani, Alexander Kuleshov, Alexander Kurtz, Alex Gaynor, Andika Triwidada, Andreas Pokorny, Andreas Rammhold, Andrew Jeddeloh, Ansgar @@ -23,12 +23,11 @@ External: Janitorial Clean-ups: -* code cleanup: retire FOREACH_WORD_QUOTED, port to extract_first_word() loops instead +* code cleanup: retire FOREACH_WORD_QUOTED, port to extract_first_word() loops instead. + For example, most conf parsing callbacks should use it. * replace manual readdir() loops with FOREACH_DIRENT or FOREACH_DIRENT_ALL -* Get rid of the last strerror() invocations in favour of %m and strerror_r() - * Rearrange tests so that the various test-xyz.c match a specific src/basic/xyz.c again Features: @@ -114,8 +113,6 @@ Features: * journald: sigbus API via a signal-handler safe function that people may call from the SIGBUS handler -* when using UTF8, ellipsize with "…" rather than "...", so that we can show more contents before truncating - * move specifier expansion from service_spawn() into load-fragment.c * optionally, also require WATCHDOG=1 notifications during service start-up and shutdown @@ -200,7 +197,7 @@ Features: * synchronize console access with BSD locks: http://lists.freedesktop.org/archives/systemd-devel/2014-October/024582.html -* as soon as we have kdbus, and sender timestamps, revisit coalescing multiple parallel daemon reloads: +* as soon as we have sender timestamps, revisit coalescing multiple parallel daemon reloads: http://lists.freedesktop.org/archives/systemd-devel/2014-December/025862.html * in systemctl list-unit-files: show the install value the presets would suggest for a service in a third column @@ -240,10 +237,6 @@ Features: * timesyncd: add ugly bus calls to set NTP servers per-interface, for usage by NM -* extract_many_words() should probably be used by a lot of code that - currently uses FOREACH_WORD and friends. For example, most conf - parsing callbacks should use it. - * merge ~/.local/share and ~/.local/lib into one similar /usr/lib and /usr/share.... * systemd.show_status= should probably have a mode where only failed @@ -808,7 +801,6 @@ Features: - add reduced [Link] support to .network files - add Scope= parsing option for [Network] - properly handle routerless dhcp leases - - add more attribute support for SIT tunnel - work with non-Ethernet devices - add support for more bond options - dhcp: do we allow configuring dhcp routes on interfaces that are not the one we got the dhcp info from? @@ -825,7 +817,6 @@ Features: support Name=foo*|bar*|baz ? - duplicate address check for static IPs (like ARPCHECK in network-scripts) - allow DUID/IAID to be customized, see issue #394. - - support configuration option for TSO (tcp segmentation offload) - whenever uplink info changes, make DHCP server send out FORCERENEW * networkd-wait-online: diff --git a/hwdb/20-bluetooth-vendor-product.hwdb b/hwdb/20-bluetooth-vendor-product.hwdb index 5089ab4e04..ab6e321ff6 100644 --- a/hwdb/20-bluetooth-vendor-product.hwdb +++ b/hwdb/20-bluetooth-vendor-product.hwdb @@ -424,7 +424,7 @@ bluetooth:v008A* ID_VENDOR_FROM_DATABASE=Jawbone bluetooth:v008B* - ID_VENDOR_FROM_DATABASE=Topcorn Positioning Systems, LLC + ID_VENDOR_FROM_DATABASE=Topcon Positioning Systems, LLC bluetooth:v008C* ID_VENDOR_FROM_DATABASE=Gimbal Inc. (formerly Qualcomm Labs, Inc. and Qualcomm Retail Solutions, Inc.) @@ -1231,7 +1231,7 @@ bluetooth:v0197* ID_VENDOR_FROM_DATABASE=WiSilica Inc bluetooth:v0198* - ID_VENDOR_FROM_DATABASE=Vengit Limited + ID_VENDOR_FROM_DATABASE=VENGIT Korlátolt Felelősségű Társaság bluetooth:v0199* ID_VENDOR_FROM_DATABASE=SALTO SYSTEMS S.L. @@ -2828,3 +2828,201 @@ bluetooth:v03AB* bluetooth:v03AC* ID_VENDOR_FROM_DATABASE=Smablo LTD + +bluetooth:v03AD* + ID_VENDOR_FROM_DATABASE=XiQ + +bluetooth:v03AE* + ID_VENDOR_FROM_DATABASE=Allswell Inc. + +bluetooth:v03AF* + ID_VENDOR_FROM_DATABASE=Comm-N-Sense Corp DBA Verigo + +bluetooth:v03B0* + ID_VENDOR_FROM_DATABASE=VIBRADORM GmbH + +bluetooth:v03B1* + ID_VENDOR_FROM_DATABASE=Otodata Wireless Network Inc. + +bluetooth:v03B2* + ID_VENDOR_FROM_DATABASE=Propagation Systems Limited + +bluetooth:v03B3* + ID_VENDOR_FROM_DATABASE=Midwest Instruments & Controls + +bluetooth:v03B4* + ID_VENDOR_FROM_DATABASE=Alpha Nodus, inc. + +bluetooth:v03B5* + ID_VENDOR_FROM_DATABASE=petPOMM, Inc + +bluetooth:v03B6* + ID_VENDOR_FROM_DATABASE=Mattel + +bluetooth:v03B7* + ID_VENDOR_FROM_DATABASE=Airbly Inc. + +bluetooth:v03B8* + ID_VENDOR_FROM_DATABASE=A-Safe Limited + +bluetooth:v03B9* + ID_VENDOR_FROM_DATABASE=FREDERIQUE CONSTANT SA + +bluetooth:v03BA* + ID_VENDOR_FROM_DATABASE=Maxscend Microelectronics Company Limited + +bluetooth:v03BB* + ID_VENDOR_FROM_DATABASE=Abbott Diabetes Care + +bluetooth:v03BC* + ID_VENDOR_FROM_DATABASE=ASB Bank Ltd + +bluetooth:v03BD* + ID_VENDOR_FROM_DATABASE=amadas + +bluetooth:v03BE* + ID_VENDOR_FROM_DATABASE=Applied Science, Inc. + +bluetooth:v03BF* + ID_VENDOR_FROM_DATABASE=iLumi Solutions Inc. + +bluetooth:v03C0* + ID_VENDOR_FROM_DATABASE=Arch Systems Inc. + +bluetooth:v03C1* + ID_VENDOR_FROM_DATABASE=Ember Technologies, Inc. + +bluetooth:v03C2* + ID_VENDOR_FROM_DATABASE=Snapchat Inc + +bluetooth:v03C3* + ID_VENDOR_FROM_DATABASE=Casambi Technologies Oy + +bluetooth:v03C4* + ID_VENDOR_FROM_DATABASE=Pico Technology Inc. + +bluetooth:v03C5* + ID_VENDOR_FROM_DATABASE=St. Jude Medical, Inc. + +bluetooth:v03C6* + ID_VENDOR_FROM_DATABASE=Intricon + +bluetooth:v03C7* + ID_VENDOR_FROM_DATABASE=Structural Health Systems, Inc. + +bluetooth:v03C8* + ID_VENDOR_FROM_DATABASE=Avvel International + +bluetooth:v03C9* + ID_VENDOR_FROM_DATABASE=Gallagher Group + +bluetooth:v03CA* + ID_VENDOR_FROM_DATABASE=In2things Automation Pvt. Ltd. + +bluetooth:v03CB* + ID_VENDOR_FROM_DATABASE=SYSDEV Srl + +bluetooth:v03CC* + ID_VENDOR_FROM_DATABASE=Vonkil Technologies Ltd + +bluetooth:v03CD* + ID_VENDOR_FROM_DATABASE=Wynd Technologies, Inc. + +bluetooth:v03CE* + ID_VENDOR_FROM_DATABASE=CONTRINEX S.A. + +bluetooth:v03CF* + ID_VENDOR_FROM_DATABASE=MIRA, Inc. + +bluetooth:v03D0* + ID_VENDOR_FROM_DATABASE=Watteam Ltd + +bluetooth:v03D1* + ID_VENDOR_FROM_DATABASE=Density Inc. + +bluetooth:v03D2* + ID_VENDOR_FROM_DATABASE=IOT Pot India Private Limited + +bluetooth:v03D3* + ID_VENDOR_FROM_DATABASE=Sigma Connectivity AB + +bluetooth:v03D4* + ID_VENDOR_FROM_DATABASE=PEG PEREGO SPA + +bluetooth:v03D5* + ID_VENDOR_FROM_DATABASE=Wyzelink Systems Inc. + +bluetooth:v03D6* + ID_VENDOR_FROM_DATABASE=Yota Devices LTD + +bluetooth:v03D7* + ID_VENDOR_FROM_DATABASE=FINSECUR + +bluetooth:v03D8* + ID_VENDOR_FROM_DATABASE=Zen-Me Labs Ltd + +bluetooth:v03D9* + ID_VENDOR_FROM_DATABASE=3IWare Co., Ltd. + +bluetooth:v03DA* + ID_VENDOR_FROM_DATABASE=EnOcean GmbH + +bluetooth:v03DB* + ID_VENDOR_FROM_DATABASE=Instabeat, Inc + +bluetooth:v03DC* + ID_VENDOR_FROM_DATABASE=Nima Labs + +bluetooth:v03DD* + ID_VENDOR_FROM_DATABASE=Andreas Stihl AG & Co. KG + +bluetooth:v03DE* + ID_VENDOR_FROM_DATABASE=Nathan Rhoades LLC + +bluetooth:v03DF* + ID_VENDOR_FROM_DATABASE=Grob Technologies, LLC + +bluetooth:v03E0* + ID_VENDOR_FROM_DATABASE=Actions (Zhuhai) Technology Co., Limited + +bluetooth:v03E1* + ID_VENDOR_FROM_DATABASE=SPD Development Company Ltd + +bluetooth:v03E2* + ID_VENDOR_FROM_DATABASE=Sensoan Oy + +bluetooth:v03E3* + ID_VENDOR_FROM_DATABASE=Qualcomm Life Inc + +bluetooth:v03E4* + ID_VENDOR_FROM_DATABASE=Chip-ing AG + +bluetooth:v03E5* + ID_VENDOR_FROM_DATABASE=ffly4u + +bluetooth:v03E6* + ID_VENDOR_FROM_DATABASE=IoT Instruments Oy + +bluetooth:v03E7* + ID_VENDOR_FROM_DATABASE=TRUE Fitness Technology + +bluetooth:v03E8* + ID_VENDOR_FROM_DATABASE=Reiner Kartengeraete GmbH & Co. KG. + +bluetooth:v03E9* + ID_VENDOR_FROM_DATABASE=SHENZHEN LEMONJOY TECHNOLOGY CO., LTD. + +bluetooth:v03EA* + ID_VENDOR_FROM_DATABASE=Hello Inc. + +bluetooth:v03EB* + ID_VENDOR_FROM_DATABASE=Evollve Inc. + +bluetooth:v03EC* + ID_VENDOR_FROM_DATABASE=Jigowatts Inc. + +bluetooth:v03ED* + ID_VENDOR_FROM_DATABASE=BASIC MICRO.COM,INC. + +bluetooth:v03EE* + ID_VENDOR_FROM_DATABASE=CUBE TECHNOLOGIES diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb index 8651946db7..0b692a1b5d 100644 --- a/hwdb/60-evdev.hwdb +++ b/hwdb/60-evdev.hwdb @@ -209,6 +209,14 @@ evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*P50* EVDEV_ABS_35=::44 EVDEV_ABS_36=::67 +# Lenovo *40 series +evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPad??40:* +evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPad??40?:* + EVDEV_ABS_00=::41 + EVDEV_ABS_01=::37 + EVDEV_ABS_35=::41 + EVDEV_ABS_36=::37 + # Lenovo T460 evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460* EVDEV_ABS_00=1266:5677:44 diff --git a/hwdb/70-pointingstick.hwdb b/hwdb/70-pointingstick.hwdb index 5e2ab393bd..2b30896dff 100644 --- a/hwdb/70-pointingstick.hwdb +++ b/hwdb/70-pointingstick.hwdb @@ -108,6 +108,8 @@ evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPad??60 evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon3rd:* # Lenovo Thinkpad X1 Carbon 4th gen evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Carbon4th:* +# Lenovo Thinkpad X1 Tablet +evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX1Tablet:* POINTINGSTICK_SENSITIVITY=200 POINTINGSTICK_CONST_ACCEL=1.0 diff --git a/hwdb/parse_hwdb.py b/hwdb/parse_hwdb.py index f55562250d..e163edbc51 100755 --- a/hwdb/parse_hwdb.py +++ b/hwdb/parse_hwdb.py @@ -1,22 +1,30 @@ #!/usr/bin/python3 -# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ +# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ # -# This file is part of systemd. +# This file is part of systemd. It is distrubuted under the MIT license, see +# below. # -# Copyright 2016 Zbigniew Jędrzejewski-Szmek +# Copyright 2016 Zbigniew Jędrzejewski-Szmek # -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. +# The MIT License (MIT) # -# systemd is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: # -# You should have received a copy of the GNU Lesser General Public License -# along with systemd; If not, see <http://www.gnu.org/licenses/>. +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. import functools import glob diff --git a/man/dnssec-trust-anchors.d.xml b/man/dnssec-trust-anchors.d.xml index 4bdc167f79..9a28862ceb 100644 --- a/man/dnssec-trust-anchors.d.xml +++ b/man/dnssec-trust-anchors.d.xml @@ -160,14 +160,12 @@ <refsect1> <title>Negative Trust Anchors</title> - <para>Negative trust anchors define domains where DNSSEC - validation shall be turned off. Negative trust anchor files are - found at the same location as positive trust anchor files, and - follow the same overriding rules. They are text files with the - <filename>.negative</filename> suffix. Empty lines and lines whose - first character is <literal>;</literal> are ignored. Each line - specifies one domain name where DNSSEC validation shall be - disabled on.</para> + <para>Negative trust anchors define domains where DNSSEC validation shall be turned + off. Negative trust anchor files are found at the same location as positive trust anchor files, + and follow the same overriding rules. They are text files with the + <filename>.negative</filename> suffix. Empty lines and lines whose first character is + <literal>;</literal> are ignored. Each line specifies one domain name which is the root of a DNS + subtree where validation shall be disabled.</para> <para>Negative trust anchors are useful to support private DNS subtrees that are not referenced from the Internet DNS hierarchy, diff --git a/man/systemctl.xml b/man/systemctl.xml index 7e0ac9613a..781de0912a 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1073,8 +1073,8 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service <listitem> <para>Reenable one or more units, as specified on the command line. This is a combination of <command>disable</command> and <command>enable</command> and is useful to reset the symlinks a unit file is - enabled with to the defaults configured in its <literal>[Install]</literal> section. This commands expects - a unit uname only, it does not accept paths to unit files.</para> + enabled with to the defaults configured in its <literal>[Install]</literal> section. This command expects + a unit name only, it does not accept paths to unit files.</para> </listitem> </varlistentry> diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index 97b348b565..bf3860604c 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -1007,8 +1007,8 @@ <example> <title>Download a Fedora image and start a shell in it</title> - <programlisting># machinectl pull-raw --verify=no http://ftp.halifax.rwth-aachen.de/fedora/linux/releases/21/Cloud/Images/x86_64/Fedora-Cloud-Base-20141203-21.x86_64.raw.xz -# systemd-nspawn -M Fedora-Cloud-Base-20141203-21</programlisting> + <programlisting># machinectl pull-raw --verify=no http://ftp.halifax.rwth-aachen.de/fedora/linux/releases/24/CloudImages/x86_64/images/Fedora-Cloud-Base-24-1.2.x86_64.raw.xz +# systemd-nspawn -M Fedora-Cloud-Base-24-1.2.x86_64.raw</programlisting> <para>This downloads an image using <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> diff --git a/man/systemd-resolve.xml b/man/systemd-resolve.xml index ca26bb4d49..24f499c282 100644 --- a/man/systemd-resolve.xml +++ b/man/systemd-resolve.xml @@ -135,7 +135,7 @@ TXT).</para> <para>The <option>--openpgp</option> switch may be used to query PGP keys stored as - <ulink url="https://tools.ietf.org/html/draft-wouters-dane-openpgp-02">OPENPGPKEY</ulink> resource records. + <ulink url="https://tools.ietf.org/html/rfc7929">OPENPGPKEY</ulink> resource records. When this option is specified one or more e-mail address must be specified.</para> <para>The <option>--tlsa</option> switch maybe be used to query TLS public diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 585b924e3d..c8b5a057f8 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -170,7 +170,11 @@ <entry>A virtual extensible LAN (vxlan), for connecting Cloud computing deployments.</entry></row> <row><entry><varname>vrf</varname></entry> - <entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row> + <entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row> + + <row><entry><varname>vcan</varname></entry> + <entry>The virtual CAN driver (vcan). Similar to the network loopback devices, + vcan offers a virtual local CAN interface.</entry></row> </tbody> </tgroup> diff --git a/shell-completion/bash/systemd-run b/shell-completion/bash/systemd-run index 022331e6a9..4116ba7eca 100644 --- a/shell-completion/bash/systemd-run +++ b/shell-completion/bash/systemd-run @@ -36,7 +36,8 @@ _systemd_run() { -r --remain-after-exit --send-sighup -H --host -M --machine --service-type --on-active --on-boot --on-startup --on-unit-active --on-unit-inactive --on-calendar --timer-property -t --pty -q --quiet --no-block - --uid --gid --nice --setenv -p --property --no-ask-password' + --uid --gid --nice --setenv -p --property --no-ask-password + --wait' local mode=--system local i diff --git a/shell-completion/zsh/_systemd-run b/shell-completion/zsh/_systemd-run index 6362b97766..da9f73a6d0 100644 --- a/shell-completion/zsh/_systemd-run +++ b/shell-completion/zsh/_systemd-run @@ -57,4 +57,5 @@ _arguments \ '--on-unit-inactive=[Run after SEC seconds from the last deactivation]:SEC' \ '--on-calendar=[Realtime timer]:SPEC' \ '--timer-property=[Set timer unit property]:NAME=VALUE' \ + '--wait=[Wait until service stopped again]' \ '*::command:_command' diff --git a/src/basic/fileio.c b/src/basic/fileio.c index a5920e7d36..1cfb7a98f5 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -1043,7 +1043,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { if (r < 0) return r; - fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC); + fd = mkostemp_safe(t); if (fd < 0) { free(t); return -errno; @@ -1076,7 +1076,7 @@ int fflush_and_check(FILE *f) { } /* This is much like mkostemp() but is subject to umask(). */ -int mkostemp_safe(char *pattern, int flags) { +int mkostemp_safe(char *pattern) { _cleanup_umask_ mode_t u = 0; int fd; @@ -1084,7 +1084,7 @@ int mkostemp_safe(char *pattern, int flags) { u = umask(077); - fd = mkostemp(pattern, flags); + fd = mkostemp(pattern, O_CLOEXEC); if (fd < 0) return -errno; @@ -1289,7 +1289,7 @@ int open_tmpfile_unlinkable(const char *directory, int flags) { /* Fall back to unguessable name + unlinking */ p = strjoina(directory, "/systemd-tmp-XXXXXX"); - fd = mkostemp_safe(p, flags); + fd = mkostemp_safe(p); if (fd < 0) return fd; diff --git a/src/basic/fileio.h b/src/basic/fileio.h index 9ac497d9eb..b58c83e64a 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -71,7 +71,7 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *root int fflush_and_check(FILE *f); int fopen_temporary(const char *path, FILE **_f, char **_temp_path); -int mkostemp_safe(char *pattern, int flags); +int mkostemp_safe(char *pattern); int tempfn_xxxxxx(const char *p, const char *extra, char **ret); int tempfn_random(const char *p, const char *extra, char **ret); diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 5d4510e1b3..dc7de5dab8 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -443,7 +443,7 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le if (old_length <= 3 || old_length <= new_length) return strndup(s, old_length); - r = new0(char, new_length+1); + r = new0(char, new_length+3); if (!r) return NULL; @@ -453,12 +453,12 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le x = new_length - 3; memcpy(r, s, x); - r[x] = '.'; - r[x+1] = '.'; - r[x+2] = '.'; + r[x] = 0xe2; /* tri-dot ellipsis: … */ + r[x+1] = 0x80; + r[x+2] = 0xa6; memcpy(r + x + 3, - s + old_length - (new_length - x - 3), - new_length - x - 3); + s + old_length - (new_length - x - 1), + new_length - x - 1); return r; } diff --git a/src/basic/time-util.c b/src/basic/time-util.c index 0ef1f6393e..fedff1362c 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -40,8 +40,6 @@ #include "strv.h" #include "time-util.h" -static nsec_t timespec_load_nsec(const struct timespec *ts); - static clockid_t map_clock_id(clockid_t c) { /* Some more exotic archs (s390, ppc, …) lack the "ALARM" flavour of the clocks. Thus, clock_gettime() will @@ -198,7 +196,7 @@ usec_t timespec_load(const struct timespec *ts) { (usec_t) ts->tv_nsec / NSEC_PER_USEC; } -static nsec_t timespec_load_nsec(const struct timespec *ts) { +nsec_t timespec_load_nsec(const struct timespec *ts) { assert(ts); if (ts->tv_sec == (time_t) -1 && ts->tv_nsec == (long) -1) diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 99be5ce6ee..558b0b5b7f 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -111,6 +111,7 @@ static inline bool triple_timestamp_is_set(triple_timestamp *ts) { usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock); usec_t timespec_load(const struct timespec *ts) _pure_; +nsec_t timespec_load_nsec(const struct timespec *ts) _pure_; struct timespec *timespec_store(struct timespec *ts, usec_t u); usec_t timeval_load(const struct timeval *tv) _pure_; diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index bbf8793e57..8ba7c08eed 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -620,7 +620,7 @@ static int save_core(sd_journal *j, int fd, char **path, bool *unlink_temp) { if (!temp) return log_oom(); - fdt = mkostemp_safe(temp, O_WRONLY|O_CLOEXEC); + fdt = mkostemp_safe(temp); if (fdt < 0) return log_error_errno(fdt, "Failed to create temporary file: %m"); log_debug("Created temporary file %s", temp); diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 080a2cd138..197f905b7d 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -451,7 +451,7 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error * r = context_update_kernel_hostname(c); if (r < 0) { log_error_errno(r, "Failed to set host name: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %m"); } log_info("Changed host name to '%s'", strna(c->data[PROP_HOSTNAME])); @@ -512,13 +512,13 @@ static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_ r = context_update_kernel_hostname(c); if (r < 0) { log_error_errno(r, "Failed to set host name: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %m"); } r = context_write_data_static_hostname(c); if (r < 0) { log_error_errno(r, "Failed to write static host name: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %m"); } log_info("Changed static host name to '%s'", strna(c->data[PROP_STATIC_HOSTNAME])); @@ -593,7 +593,7 @@ static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_mess r = context_write_data_machine_info(c); if (r < 0) { log_error_errno(r, "Failed to write machine info: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %m"); } log_info("Changed %s to '%s'", diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c index c2b5a5f205..54f42b8bf3 100644 --- a/src/journal-remote/journal-gatewayd.c +++ b/src/journal-remote/journal-gatewayd.c @@ -475,20 +475,20 @@ static int request_handler_entries( r = open_journal(m); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %m"); if (request_parse_accept(m, connection) < 0) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header."); if (request_parse_range(m, connection) < 0) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Range header.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Range header."); if (request_parse_arguments(m, connection) < 0) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse URL arguments.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse URL arguments."); if (m->discrete) { if (!m->cursor) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Discrete seeks require a cursor specification.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Discrete seeks require a cursor specification."); m->n_entries = 1; m->n_entries_set = true; @@ -501,7 +501,7 @@ static int request_handler_entries( else if (m->n_skip < 0) r = sd_journal_seek_tail(m->journal); if (r < 0) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to seek in journal.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to seek in journal."); response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_entries, m, NULL); if (!response) @@ -633,14 +633,14 @@ static int request_handler_fields( r = open_journal(m); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %m"); if (request_parse_accept(m, connection) < 0) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to parse Accept header."); r = sd_journal_query_unique(m->journal, field); if (r < 0) - return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to query unique fields.\n"); + return mhd_respond(connection, MHD_HTTP_BAD_REQUEST, "Failed to query unique fields."); response = MHD_create_response_from_callback(MHD_SIZE_UNKNOWN, 4*1024, request_reader_fields, m, NULL); if (!response) @@ -699,10 +699,10 @@ static int request_handler_file( fd = open(path, O_RDONLY|O_CLOEXEC); if (fd < 0) - return mhd_respondf(connection, MHD_HTTP_NOT_FOUND, "Failed to open file %s: %m\n", path); + return mhd_respondf(connection, errno, MHD_HTTP_NOT_FOUND, "Failed to open file %s: %m", path); if (fstat(fd, &st) < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to stat file: %m\n"); + return mhd_respondf(connection, errno, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to stat file: %m"); response = MHD_create_response_from_fd_at_offset64(st.st_size, fd, 0); if (!response) @@ -766,15 +766,15 @@ static int request_handler_machine( r = open_journal(m); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to open journal: %m"); r = sd_id128_get_machine(&mid); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine machine ID: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine machine ID: %m"); r = sd_id128_get_boot(&bid); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine boot ID: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine boot ID: %m"); hostname = gethostname_malloc(); if (!hostname) @@ -782,11 +782,11 @@ static int request_handler_machine( r = sd_journal_get_usage(m->journal, &usage); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s"); r = sd_journal_get_cutoff_realtime_usec(m->journal, &cutoff_from, &cutoff_to); if (r < 0) - return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s"); if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL) == -ENOENT) (void) parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL); @@ -844,8 +844,7 @@ static int request_handler( assert(method); if (!streq(method, "GET")) - return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE, - "Unsupported method.\n"); + return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE, "Unsupported method."); if (!*connection_cls) { @@ -875,7 +874,7 @@ static int request_handler( if (streq(url, "/machine")) return request_handler_machine(connection, *connection_cls); - return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found.\n"); + return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found."); } static void help(void) { diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c index 220c71754a..a9009cfefe 100644 --- a/src/journal-remote/journal-remote.c +++ b/src/journal-remote/journal-remote.c @@ -524,13 +524,12 @@ static int process_http_upload( log_warning("Failed to process data for connection %p", connection); if (r == -E2BIG) return mhd_respondf(connection, - MHD_HTTP_REQUEST_ENTITY_TOO_LARGE, - "Entry is too large, maximum is %u bytes.\n", - DATA_SIZE_MAX); + r, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE, + "Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes."); else return mhd_respondf(connection, - MHD_HTTP_UNPROCESSABLE_ENTITY, - "Processing failed: %s.", strerror(-r)); + r, MHD_HTTP_UNPROCESSABLE_ENTITY, + "Processing failed: %m."); } } @@ -541,13 +540,14 @@ static int process_http_upload( remaining = source_non_empty(source); if (remaining > 0) { - log_warning("Premature EOFbyte. %zu bytes lost.", remaining); - return mhd_respondf(connection, MHD_HTTP_EXPECTATION_FAILED, + log_warning("Premature EOF byte. %zu bytes lost.", remaining); + return mhd_respondf(connection, + 0, MHD_HTTP_EXPECTATION_FAILED, "Premature EOF. %zu bytes of trailing data not processed.", remaining); } - return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK.\n"); + return mhd_respond(connection, MHD_HTTP_ACCEPTED, "OK."); }; static int request_handler( @@ -577,19 +577,16 @@ static int request_handler( *connection_cls); if (!streq(method, "POST")) - return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE, - "Unsupported method.\n"); + return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE, "Unsupported method."); if (!streq(url, "/upload")) - return mhd_respond(connection, MHD_HTTP_NOT_FOUND, - "Not found.\n"); + return mhd_respond(connection, MHD_HTTP_NOT_FOUND, "Not found."); header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Type"); if (!header || !streq(header, "application/vnd.fdo.journal")) return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE, - "Content-Type: application/vnd.fdo.journal" - " is required.\n"); + "Content-Type: application/vnd.fdo.journal is required."); { const union MHD_ConnectionInfo *ci; @@ -599,7 +596,7 @@ static int request_handler( if (!ci) { log_error("MHD_get_connection_info failed: cannot get remote fd"); return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - "Cannot check remote address"); + "Cannot check remote address."); } fd = ci->connect_fd; @@ -614,7 +611,7 @@ static int request_handler( r = getpeername_pretty(fd, false, &hostname); if (r < 0) return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - "Cannot check remote hostname"); + "Cannot check remote hostname."); } assert(hostname); @@ -623,8 +620,7 @@ static int request_handler( if (r == -ENOMEM) return respond_oom(connection); else if (r < 0) - return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - strerror(-r)); + return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "%m"); hostname = NULL; return MHD_YES; diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c index 2f16b02e9a..cae10203c6 100644 --- a/src/journal-remote/microhttpd-util.c +++ b/src/journal-remote/microhttpd-util.c @@ -48,7 +48,7 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) { static int mhd_respond_internal(struct MHD_Connection *connection, enum MHD_RequestTerminationCode code, - char *buffer, + const char *buffer, size_t size, enum MHD_ResponseMemoryMode mode) { struct MHD_Response *response; @@ -56,7 +56,7 @@ static int mhd_respond_internal(struct MHD_Connection *connection, assert(connection); - response = MHD_create_response_from_buffer(size, buffer, mode); + response = MHD_create_response_from_buffer(size, (char*) buffer, mode); if (!response) return MHD_NO; @@ -72,19 +72,25 @@ int mhd_respond(struct MHD_Connection *connection, enum MHD_RequestTerminationCode code, const char *message) { + const char *fmt; + + fmt = strjoina(message, "\n"); + return mhd_respond_internal(connection, code, - (char*) message, strlen(message), + fmt, strlen(message) + 1, MHD_RESPMEM_PERSISTENT); } int mhd_respond_oom(struct MHD_Connection *connection) { - return mhd_respond(connection, MHD_HTTP_SERVICE_UNAVAILABLE, "Out of memory.\n"); + return mhd_respond(connection, MHD_HTTP_SERVICE_UNAVAILABLE, "Out of memory."); } int mhd_respondf(struct MHD_Connection *connection, + int error, enum MHD_RequestTerminationCode code, const char *format, ...) { + const char *fmt; char *m; int r; va_list ap; @@ -92,8 +98,12 @@ int mhd_respondf(struct MHD_Connection *connection, assert(connection); assert(format); + if (error < 0) + error = -error; + errno = -error; + fmt = strjoina(format, "\n"); va_start(ap, format); - r = vasprintf(&m, format, ap); + r = vasprintf(&m, fmt, ap); va_end(ap); if (r < 0) diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h index ea160f212b..af26ab69fe 100644 --- a/src/journal-remote/microhttpd-util.h +++ b/src/journal-remote/microhttpd-util.h @@ -39,8 +39,9 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) _printf_(2, 0); #define respond_oom(connection) log_oom(), mhd_respond_oom(connection) int mhd_respondf(struct MHD_Connection *connection, + int error, unsigned code, - const char *format, ...) _printf_(3,4); + const char *format, ...) _printf_(4,5); int mhd_respond(struct MHD_Connection *connection, unsigned code, diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c index 4105abfccc..9e4d8a28a5 100644 --- a/src/journal/journal-verify.c +++ b/src/journal/journal-verify.c @@ -118,6 +118,11 @@ static void flush_progress(void) { log_error(OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \ } while (0) +#define error_errno(_offset, error, _fmt, ...) do { \ + flush_progress(); \ + log_error_errno(error, OFSfmt": " _fmt, (uint64_t)_offset, ##__VA_ARGS__); \ + } while (0) + static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) { uint64_t i; @@ -168,8 +173,8 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o le64toh(o->object.size) - offsetof(Object, data.payload), &b, &alloc, &b_size, 0); if (r < 0) { - error(offset, "%s decompression failed: %s", - object_compressed_to_string(compression), strerror(-r)); + error_errno(offset, r, "%s decompression failed: %m", + object_compressed_to_string(compression)); return r; } @@ -912,7 +917,7 @@ int journal_file_verify( r = journal_file_object_verify(f, p, o); if (r < 0) { - error(p, "Invalid object contents: %s", strerror(-r)); + error_errno(p, r, "Invalid object contents: %m"); goto fail; } diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 381e219390..4350925fb0 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1632,7 +1632,7 @@ static int setup_keys(void) { n /= arg_interval; safe_close(fd); - fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC); + fd = mkostemp_safe(k); if (fd < 0) { r = log_error_errno(fd, "Failed to open %s: %m", k); goto finish; @@ -1684,9 +1684,9 @@ static int setup_keys(void) { "at a safe location and should not be saved locally on disk.\n" "\n\t%s", ansi_highlight(), ansi_normal(), + p, ansi_highlight(), ansi_normal(), - ansi_highlight_red(), - p); + ansi_highlight_red()); fflush(stderr); } for (i = 0; i < seed_size; i++) { diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c index 898c876450..b7d9e7bffa 100644 --- a/src/journal/test-catalog.c +++ b/src/journal/test-catalog.c @@ -55,7 +55,7 @@ static Hashmap * test_import(const char* contents, ssize_t size, int code) { assert_se(h = hashmap_new(&catalog_hash_ops)); - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(write(fd, contents, size) == size); @@ -182,7 +182,7 @@ static void test_catalog_update(void) { static char name[] = "/tmp/test-catalog.XXXXXX"; int r; - r = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + r = mkostemp_safe(name); assert_se(r >= 0); database = name; diff --git a/src/journal/test-compress.c b/src/journal/test-compress.c index 68c9a4d76c..00e5222a1c 100644 --- a/src/journal/test-compress.c +++ b/src/journal/test-compress.c @@ -167,7 +167,7 @@ static void test_compress_stream(int compression, log_debug("/* test compression */"); - assert_se((dst = mkostemp_safe(pattern, O_RDWR|O_CLOEXEC)) >= 0); + assert_se((dst = mkostemp_safe(pattern)) >= 0); assert_se(compress(src, dst, -1) == 0); @@ -178,7 +178,7 @@ static void test_compress_stream(int compression, log_debug("/* test decompression */"); - assert_se((dst2 = mkostemp_safe(pattern2, O_RDWR|O_CLOEXEC)) >= 0); + assert_se((dst2 = mkostemp_safe(pattern2)) >= 0); assert_se(stat(srcfile, &st) == 0); diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c index 5e063f4d04..35cae23bf8 100644 --- a/src/journal/test-journal-interleaving.c +++ b/src/journal/test-journal-interleaving.c @@ -36,10 +36,9 @@ static bool arg_keep = false; -noreturn static void log_assert_errno(const char *text, int eno, const char *file, int line, const char *func) { - log_internal(LOG_CRIT, 0, file, line, func, - "'%s' failed at %s:%u (%s): %s.", - text, file, line, func, strerror(eno)); +noreturn static void log_assert_errno(const char *text, int error, const char *file, int line, const char *func) { + log_internal(LOG_CRIT, error, file, line, func, + "'%s' failed at %s:%u (%s): %m", text, file, line, func); abort(); } diff --git a/src/journal/test-mmap-cache.c b/src/journal/test-mmap-cache.c index 009aabf55e..0ad49aeb5f 100644 --- a/src/journal/test-mmap-cache.c +++ b/src/journal/test-mmap-cache.c @@ -36,15 +36,15 @@ int main(int argc, char *argv[]) { assert_se(m = mmap_cache_new()); - x = mkostemp_safe(px, O_RDWR|O_CLOEXEC); + x = mkostemp_safe(px); assert_se(x >= 0); unlink(px); - y = mkostemp_safe(py, O_RDWR|O_CLOEXEC); + y = mkostemp_safe(py); assert_se(y >= 0); unlink(py); - z = mkostemp_safe(pz, O_RDWR|O_CLOEXEC); + z = mkostemp_safe(pz); assert_se(z >= 0); unlink(pz); diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index c66bcfc092..f37c023c6a 100644 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -61,6 +61,13 @@ for i in "$@"; do fi done +# KERNEL_INSTALL_NOOP may be used by programs like lorax and rpm-ostree which +# want to install a kernel (indirectly via RPM), but control generation of the +# initramfs. In general, OSTree takes over kernel management too. +if test -n "${KERNEL_INSTALL_NOOP:-}"; then + exit 0 +fi + if [[ "${0##*/}" == 'installkernel' ]]; then COMMAND='add' else diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index 048c0d19e2..fc60830059 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -351,7 +351,7 @@ finish: static int quit_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { bool *x = userdata; - log_error("Quit callback: %s", strerror(sd_bus_message_get_errno(m))); + log_error_errno(sd_bus_message_get_errno(m), "Quit callback: %m"); *x = 1; return 1; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 566a050432..1c10dd55a7 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -21,6 +21,7 @@ #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <linux/can/netlink.h> #include <linux/in6.h> #include <linux/veth.h> #include <linux/if_bridge.h> @@ -303,49 +304,48 @@ static const char* const nl_union_link_info_data_table[] = { [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6", [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl", [NL_UNION_LINK_INFO_DATA_VRF] = "vrf", + [NL_UNION_LINK_INFO_DATA_VCAN] = "vcan", }; DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); static const NLTypeSystem rtnl_link_info_data_type_systems[] = { - [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), - .types = rtnl_link_info_data_bond_types }, - [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), - .types = rtnl_link_info_data_bridge_types }, - [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), - .types = rtnl_link_info_data_vlan_types }, - [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), - .types = rtnl_link_info_data_veth_types }, - [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), - .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), - .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), - .types = rtnl_link_info_data_vxlan_types }, - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), + .types = rtnl_link_info_data_bond_types }, + [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), + .types = rtnl_link_info_data_bridge_types }, + [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), + .types = rtnl_link_info_data_vlan_types }, + [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), + .types = rtnl_link_info_data_veth_types }, + [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_MACVTAP] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), + .types = rtnl_link_info_data_macvlan_types }, + [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), + .types = rtnl_link_info_data_ipvlan_types }, + [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), + .types = rtnl_link_info_data_vxlan_types }, + [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), - .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), - .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), - .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), - .types = rtnl_link_info_data_ip6tnl_types }, - - [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), - .types = rtnl_link_info_data_vrf_types }, - + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), + .types = rtnl_link_info_data_ipgre_types }, + [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), + .types = rtnl_link_info_data_iptun_types }, + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types }, + [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), + .types = rtnl_link_info_data_ipvti_types }, + [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), + .types = rtnl_link_info_data_ip6tnl_types }, + [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types), + .types = rtnl_link_info_data_vrf_types }, }; static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index 7c0e598b26..42e96173de 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -87,6 +87,7 @@ typedef enum NLUnionLinkInfoData { NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL, NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL, NL_UNION_LINK_INFO_DATA_VRF, + NL_UNION_LINK_INFO_DATA_VCAN, _NL_UNION_LINK_INFO_DATA_MAX, _NL_UNION_LINK_INFO_DATA_INVALID = -1 } NLUnionLinkInfoData; diff --git a/src/locale/localed.c b/src/locale/localed.c index 298f176e40..1cb049e74a 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -334,7 +334,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er r = locale_write_data(c, &settings); if (r < 0) { log_error_errno(r, "Failed to set locale: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to set locale: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to set locale: %m"); } locale_update_system_manager(c, sd_bus_message_get_bus(m)); @@ -403,7 +403,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro r = vconsole_write_data(c); if (r < 0) { log_error_errno(r, "Failed to set virtual console keymap: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to set virtual console keymap: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to set virtual console keymap: %m"); } log_info("Changed virtual console keymap to '%s' toggle '%s'", @@ -592,7 +592,7 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err r = x11_write_data(c); if (r < 0) { log_error_errno(r, "Failed to set X11 keyboard layout: %m"); - return sd_bus_error_set_errnof(error, r, "Failed to set X11 keyboard layout: %s", strerror(-r)); + return sd_bus_error_set_errnof(error, r, "Failed to set X11 keyboard layout: %m"); } log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'", diff --git a/src/login/logind-user.c b/src/login/logind-user.c index e0e73b034d..2dc5fa7665 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -354,14 +354,12 @@ static int user_mkdir_runtime_path(User *u) { r = mount("tmpfs", u->runtime_path, "tmpfs", MS_NODEV|MS_NOSUID, t); if (r < 0) { - if (errno != EPERM) { + if (errno != EPERM && errno != EACCES) { r = log_error_errno(errno, "Failed to mount per-user tmpfs directory %s: %m", u->runtime_path); goto fail; } - /* Lacking permissions, maybe - * CAP_SYS_ADMIN-less container? In this case, - * just use a normal directory. */ + log_debug_errno(errno, "Failed to mount per-user tmpfs directory %s, assuming containerized execution, ignoring: %m", u->runtime_path); r = chmod_and_chown(u->runtime_path, 0700, u->uid, u->gid); if (r < 0) { diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 5e2462cba2..e40f40a263 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -444,7 +444,9 @@ static int method_register_machine_internal(sd_bus_message *message, bool read_n r = cg_pid_get_unit(m->leader, &m->unit); if (r < 0) { - r = sd_bus_error_set_errnof(error, r, "Failed to determine unit of process "PID_FMT" : %s", m->leader, strerror(-r)); + r = sd_bus_error_set_errnof(error, r, + "Failed to determine unit of process "PID_FMT" : %m", + m->leader); goto fail; } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index aab40a0eb1..1687d9bf31 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1787,6 +1787,31 @@ static int link_down(Link *link) { return 0; } +static int link_up_can(Link *link) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(link); + + log_link_debug(link, "Bringing CAN link up"); + + r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + + r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); + if (r < 0) + return log_link_error_errno(link, r, "Could not set link flags: %m"); + + r = sd_netlink_call_async(link->manager->rtnl, req, link_up_handler, link, 0, NULL); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + link_ref(link); + + return 0; +} + static int link_handle_bound_to_list(Link *link) { Link *l; Iterator i; @@ -2431,6 +2456,19 @@ static int link_configure(Link *link) { assert(link->network); assert(link->state == LINK_STATE_PENDING); + if (streq_ptr(link->kind, "vcan")) { + + if (!(link->flags & IFF_UP)) { + r = link_up_can(link); + if (r < 0) { + link_enter_failed(link); + return r; + } + } + + return 0; + } + /* Drop foreign config, but ignore loopback or critical devices. * We do not want to remove loopback address or addresses used for root NFS. */ if (!(link->flags & IFF_LOOPBACK) && !(link->network->dhcp_critical)) { diff --git a/src/network/networkd-netdev-vcan.c b/src/network/networkd-netdev-vcan.c new file mode 100644 index 0000000000..bfce6e1962 --- /dev/null +++ b/src/network/networkd-netdev-vcan.c @@ -0,0 +1,25 @@ +/*** + This file is part of systemd. + + Copyright 2016 Susant Sahani + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "networkd-netdev-vcan.h" + +const NetDevVTable vcan_vtable = { + .object_size = sizeof(VCan), + .create_type = NETDEV_CREATE_INDEPENDENT, +}; diff --git a/src/network/networkd-netdev-vcan.h b/src/network/networkd-netdev-vcan.h new file mode 100644 index 0000000000..6ba47fd70e --- /dev/null +++ b/src/network/networkd-netdev-vcan.h @@ -0,0 +1,34 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2016 Susant Sahani + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +typedef struct VCan VCan; + +#include <linux/can/netlink.h> + +#include "networkd-netdev.h" + +struct VCan { + NetDev meta; +}; + +DEFINE_NETDEV_CAST(VCAN, VCan); + +extern const NetDevVTable vcan_vtable; diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index ece4ea2e64..a210ba1242 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -34,7 +34,6 @@ #include "string-util.h" const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { - [NETDEV_KIND_BRIDGE] = &bridge_vtable, [NETDEV_KIND_BOND] = &bond_vtable, [NETDEV_KIND_VLAN] = &vlan_vtable, @@ -56,7 +55,7 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = { [NETDEV_KIND_TAP] = &tap_vtable, [NETDEV_KIND_IP6TNL] = &ip6tnl_vtable, [NETDEV_KIND_VRF] = &vrf_vtable, - + [NETDEV_KIND_VCAN] = &vcan_vtable, }; static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { @@ -81,7 +80,7 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = { [NETDEV_KIND_TAP] = "tap", [NETDEV_KIND_IP6TNL] = "ip6tnl", [NETDEV_KIND_VRF] = "vrf", - + [NETDEV_KIND_VCAN] = "vcan", }; DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind); @@ -516,7 +515,7 @@ static int netdev_create(NetDev *netdev, Link *link, r = sd_netlink_message_close_container(m); if (r < 0) - return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m"); + return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m"); r = sd_netlink_message_close_container(m); if (r < 0) diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h index 09863e72b4..31b55e2791 100644 --- a/src/network/networkd-netdev.h +++ b/src/network/networkd-netdev.h @@ -56,6 +56,7 @@ typedef enum NetDevKind { NETDEV_KIND_TUN, NETDEV_KIND_TAP, NETDEV_KIND_VRF, + NETDEV_KIND_VCAN, _NETDEV_KIND_MAX, _NETDEV_KIND_INVALID = -1 } NetDevKind; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 58e19e542a..313abca762 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -482,9 +482,10 @@ int config_parse_netdev(const char *unit, case NETDEV_KIND_MACVTAP: case NETDEV_KIND_IPVLAN: case NETDEV_KIND_VXLAN: + case NETDEV_KIND_VCAN: r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, r, "Can not add VLAN '%s' to network: %m", rvalue); + log_syntax(unit, LOG_ERR, filename, line, r, "Can not add NetDev '%s' to network: %m", rvalue); return 0; } diff --git a/src/network/networkd.h b/src/network/networkd.h index c4bd712147..cb1b73145e 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -43,6 +43,7 @@ #include "networkd-netdev-vlan.h" #include "networkd-netdev-vrf.h" #include "networkd-netdev-vxlan.h" +#include "networkd-netdev-vcan.h" #include "networkd-network.h" #include "networkd-util.h" diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 6d0420965a..6f4a33cd96 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1219,7 +1219,13 @@ static int setup_timezone(const char *dest) { /* Fix the timezone, if possible */ r = readlink_malloc("/etc/localtime", &p); if (r < 0) { - log_warning("/etc/localtime is not a symlink, not updating container timezone."); + log_warning("host's /etc/localtime is not a symlink, not updating container timezone."); + /* to handle warning, delete /etc/localtime and replace it + * it /w a symbolic link to a time zone data file. + * + * Example: + * ln -s /etc/localtime /usr/share/zoneinfo/UTC + */ return 0; } diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 65151b19a6..2597cfc648 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -484,7 +484,7 @@ int ask_password_agent( (void) mkdir_p_label("/run/systemd/ask-password", 0755); - fd = mkostemp_safe(temp, O_WRONLY|O_CLOEXEC); + fd = mkostemp_safe(temp); if (fd < 0) { r = fd; goto finish; diff --git a/src/shared/condition.c b/src/shared/condition.c index 6bb42c0692..f13fa6a9fd 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -37,6 +37,7 @@ #include "condition.h" #include "extract-word.h" #include "fd-util.h" +#include "fileio.h" #include "glob-util.h" #include "hostname-util.h" #include "ima-util.h" @@ -309,8 +310,45 @@ static int condition_test_needs_update(Condition *c) { if (lstat("/usr/", &usr) < 0) return true; - return usr.st_mtim.tv_sec > other.st_mtim.tv_sec || - (usr.st_mtim.tv_sec == other.st_mtim.tv_sec && usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec); + /* + * First, compare seconds as they are always accurate... + */ + if (usr.st_mtim.tv_sec != other.st_mtim.tv_sec) + return usr.st_mtim.tv_sec > other.st_mtim.tv_sec; + + /* + * ...then compare nanoseconds. + * + * A false positive is only possible when /usr's nanoseconds > 0 + * (otherwise /usr cannot be strictly newer than the target file) + * AND the target file's nanoseconds == 0 + * (otherwise the filesystem supports nsec timestamps, see stat(2)). + */ + if (usr.st_mtim.tv_nsec > 0 && other.st_mtim.tv_nsec == 0) { + _cleanup_free_ char *timestamp_str = NULL; + uint64_t timestamp; + int r; + + r = parse_env_file(p, NULL, "TimestampNSec", ×tamp_str, NULL); + if (r < 0) { + log_error_errno(-r, "Failed to parse timestamp file '%s', using mtime: %m", p); + return true; + } else if (r == 0) { + log_debug("No data in timestamp file '%s', using mtime", p); + return true; + } + + r = safe_atou64(timestamp_str, ×tamp); + if (r < 0) { + log_error_errno(-r, "Failed to parse timestamp value '%s' in file '%s', using mtime: %m", + timestamp_str, p); + return true; + } + + other.st_mtim.tv_nsec = timestamp % NSEC_PER_SEC; + } + + return usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec; } static int condition_test_first_boot(Condition *c) { diff --git a/src/shared/install.c b/src/shared/install.c index 11770d887f..5f12fb447f 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -403,6 +403,9 @@ static bool chroot_symlinks_same(const char *root, const char *wd, const char *a /* This will give incorrect results if the paths are relative and go outside * of the chroot. False negatives are possible. */ + if (!root) + root = "/"; + a = strjoina(path_is_absolute(a) ? root : wd, "/", a); b = strjoina(path_is_absolute(b) ? root : wd, "/", b); return path_equal_or_files_same(a, b); diff --git a/src/test/test-acl-util.c b/src/test/test-acl-util.c index 430dda8e78..5b572bb0bf 100644 --- a/src/test/test-acl-util.c +++ b/src/test/test-acl-util.c @@ -35,7 +35,7 @@ static void test_add_acls_for_user(void) { uid_t uid; int r; - fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(fn); assert_se(fd >= 0); /* Use the mode that user journal files use */ diff --git a/src/test/test-async.c b/src/test/test-async.c index ada6d67c42..4ebc27f0bd 100644 --- a/src/test/test-async.c +++ b/src/test/test-async.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) { int fd; char name[] = "/tmp/test-asynchronous_close.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); asynchronous_close(fd); diff --git a/src/test/test-clock.c b/src/test/test-clock.c index 84f775e5bc..7d97328416 100644 --- a/src/test/test-clock.c +++ b/src/test/test-clock.c @@ -55,7 +55,7 @@ static void test_clock_is_localtime(void) { /* without an adjtime file we default to UTC */ assert_se(clock_is_localtime("/nonexisting/adjtime") == 0); - fd = mkostemp_safe(adjtime, O_WRONLY|O_CLOEXEC); + fd = mkostemp_safe(adjtime); assert_se(fd >= 0); log_info("adjtime test file: %s", adjtime); f = fdopen(fd, "w"); diff --git a/src/test/test-copy.c b/src/test/test-copy.c index 68154fc4e8..ed1ea51dbd 100644 --- a/src/test/test-copy.c +++ b/src/test/test-copy.c @@ -42,11 +42,11 @@ static void test_copy_file(void) { log_info("%s", __func__); - fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(fn); assert_se(fd >= 0); close(fd); - fd = mkostemp_safe(fn_copy, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(fn_copy); assert_se(fd >= 0); close(fd); @@ -71,9 +71,9 @@ static void test_copy_file_fd(void) { log_info("%s", __func__); - in_fd = mkostemp_safe(in_fn, O_RDWR); + in_fd = mkostemp_safe(in_fn); assert_se(in_fd >= 0); - out_fd = mkostemp_safe(out_fn, O_RDWR); + out_fd = mkostemp_safe(out_fn); assert_se(out_fd >= 0); assert_se(write_string_file(in_fn, text, WRITE_STRING_FILE_CREATE) == 0); @@ -207,10 +207,10 @@ static void test_copy_bytes_regular_file(const char *src, bool try_reflink, uint fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY); assert_se(fd >= 0); - fd2 = mkostemp_safe(fn2, O_RDWR); + fd2 = mkostemp_safe(fn2); assert_se(fd2 >= 0); - fd3 = mkostemp_safe(fn3, O_WRONLY); + fd3 = mkostemp_safe(fn3); assert_se(fd3 >= 0); r = copy_bytes(fd, fd2, max_bytes, try_reflink); diff --git a/src/test/test-engine.c b/src/test/test-engine.c index 23da10fa1a..a651f6b683 100644 --- a/src/test/test-engine.c +++ b/src/test/test-engine.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) { assert_se(set_unit_path(TEST_DIR) >= 0); r = manager_new(UNIT_FILE_USER, true, &m); if (MANAGER_SKIP_TEST(r)) { - printf("Skipping test: manager_new: %s\n", strerror(-r)); + log_notice_errno(r, "Skipping test: manager_new: %m"); return EXIT_TEST_SKIP; } assert_se(r >= 0); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 05ec1d2eb1..25489cefbc 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -324,7 +324,7 @@ static int run_tests(UnitFileScope scope, test_function_t *tests) { r = manager_new(scope, true, &m); if (MANAGER_SKIP_TEST(r)) { - printf("Skipping test: manager_new: %s\n", strerror(-r)); + log_notice_errno(r, "Skipping test: manager_new: %m"); return EXIT_TEST_SKIP; } assert_se(r >= 0); diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index 421d3bdeb3..f555bb976c 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -31,9 +31,9 @@ static void test_close_many(void) { char name1[] = "/tmp/test-close-many.XXXXXX"; char name2[] = "/tmp/test-close-many.XXXXXX"; - fds[0] = mkostemp_safe(name0, O_RDWR|O_CLOEXEC); - fds[1] = mkostemp_safe(name1, O_RDWR|O_CLOEXEC); - fds[2] = mkostemp_safe(name2, O_RDWR|O_CLOEXEC); + fds[0] = mkostemp_safe(name0); + fds[1] = mkostemp_safe(name1); + fds[2] = mkostemp_safe(name2); close_many(fds, 2); @@ -52,7 +52,7 @@ static void test_close_nointr(void) { char name[] = "/tmp/test-test-close_nointr.XXXXXX"; int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(close_nointr(fd) >= 0); assert_se(close_nointr(fd) < 0); diff --git a/src/test/test-fdset.c b/src/test/test-fdset.c index 282aab1246..adbf99a7ec 100644 --- a/src/test/test-fdset.c +++ b/src/test/test-fdset.c @@ -31,7 +31,7 @@ static void test_fdset_new_fill(void) { _cleanup_fdset_free_ FDSet *fdset = NULL; char name[] = "/tmp/test-fdset_new_fill.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(fdset_new_fill(&fdset) >= 0); assert_se(fdset_contains(fdset, fd)); @@ -45,7 +45,7 @@ static void test_fdset_put_dup(void) { _cleanup_fdset_free_ FDSet *fdset = NULL; char name[] = "/tmp/test-fdset_put_dup.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); @@ -64,7 +64,7 @@ static void test_fdset_cloexec(void) { int flags = -1; char name[] = "/tmp/test-fdset_cloexec.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); @@ -91,7 +91,7 @@ static void test_fdset_close_others(void) { int flags = -1; char name[] = "/tmp/test-fdset_close_others.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); @@ -113,7 +113,7 @@ static void test_fdset_remove(void) { FDSet *fdset = NULL; char name[] = "/tmp/test-fdset_remove.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); @@ -136,7 +136,7 @@ static void test_fdset_iterate(void) { int c = 0; int a; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); @@ -161,7 +161,7 @@ static void test_fdset_isempty(void) { _cleanup_fdset_free_ FDSet *fdset = NULL; char name[] = "/tmp/test-fdset_isempty.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); @@ -179,7 +179,7 @@ static void test_fdset_steal_first(void) { _cleanup_fdset_free_ FDSet *fdset = NULL; char name[] = "/tmp/test-fdset_steal_first.XXXXXX"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); fdset = fdset_new(); diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 79609765e0..92663ef66f 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -45,11 +45,11 @@ static void test_parse_env_file(void) { char **i; unsigned k; - fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(p); assert_se(fd >= 0); close(fd); - fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(t); assert_se(fd >= 0); f = fdopen(fd, "w"); @@ -158,11 +158,11 @@ static void test_parse_multiline_env_file(void) { _cleanup_strv_free_ char **a = NULL, **b = NULL; char **i; - fd = mkostemp_safe(p, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(p); assert_se(fd >= 0); close(fd); - fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(t); assert_se(fd >= 0); f = fdopen(fd, "w"); @@ -211,7 +211,7 @@ static void test_executable_is_script(void) { FILE *f; char *command; - fd = mkostemp_safe(t, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(t); assert_se(fd >= 0); f = fdopen(fd, "w"); @@ -300,7 +300,7 @@ static void test_write_string_stream(void) { int fd; char buf[64]; - fd = mkostemp_safe(fn, O_RDWR); + fd = mkostemp_safe(fn); assert_se(fd >= 0); f = fdopen(fd, "r"); @@ -334,7 +334,7 @@ static void test_write_string_file(void) { char buf[64] = {}; _cleanup_close_ int fd; - fd = mkostemp_safe(fn, O_RDWR); + fd = mkostemp_safe(fn); assert_se(fd >= 0); assert_se(write_string_file(fn, "boohoo", WRITE_STRING_FILE_CREATE) == 0); @@ -350,7 +350,7 @@ static void test_write_string_file_no_create(void) { _cleanup_close_ int fd; char buf[64] = {0}; - fd = mkostemp_safe(fn, O_RDWR); + fd = mkostemp_safe(fn); assert_se(fd >= 0); assert_se(write_string_file("/a/file/which/does/not/exists/i/guess", "boohoo", 0) < 0); @@ -390,7 +390,7 @@ static void test_load_env_file_pairs(void) { _cleanup_strv_free_ char **l = NULL; char **k, **v; - fd = mkostemp_safe(fn, O_RDWR); + fd = mkostemp_safe(fn); assert_se(fd >= 0); r = write_string_file(fn, @@ -433,7 +433,7 @@ static void test_search_and_fopen(void) { int r; FILE *f; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); close(fd); @@ -469,7 +469,7 @@ static void test_search_and_fopen_nulstr(void) { int r; FILE *f; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); close(fd); @@ -504,7 +504,7 @@ static void test_writing_tmpfile(void) { IOVEC_SET_STRING(iov[1], ALPHANUMERICAL "\n"); IOVEC_SET_STRING(iov[2], ""); - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); printf("tmpfile: %s", name); r = writev(fd, iov, 3); diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index b3c4a2a2eb..b35a2ea2c8 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -34,7 +34,7 @@ static void test_unlink_noerrno(void) { char name[] = "/tmp/test-close_nointr.XXXXXX"; int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(close_nointr(fd) >= 0); diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c index 227d4290f0..9eea3eb608 100644 --- a/src/test/test-glob-util.c +++ b/src/test/test-glob-util.c @@ -30,7 +30,7 @@ static void test_glob_exists(void) { int fd = -1; int r; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); close(fd); diff --git a/src/test/test-hostname-util.c b/src/test/test-hostname-util.c index 1c3d13ed1d..d2c3ea5e0d 100644 --- a/src/test/test-hostname-util.c +++ b/src/test/test-hostname-util.c @@ -104,7 +104,7 @@ static void test_read_hostname_config(void) { char *hostname; int fd; - fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(path); assert(fd > 0); close(fd); diff --git a/src/test/test-path.c b/src/test/test-path.c index 62181e22a0..4d3f0e9948 100644 --- a/src/test/test-path.c +++ b/src/test/test-path.c @@ -47,7 +47,7 @@ static int setup_test(Manager **m) { r = manager_new(UNIT_FILE_USER, true, &tmp); if (MANAGER_SKIP_TEST(r)) { - printf("Skipping test: manager_new: %s\n", strerror(-r)); + log_notice_errno(r, "Skipping test: manager_new: %m"); return -EXIT_TEST_SKIP; } assert_se(r >= 0); diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index c068f5c39e..7b37910c33 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) { assert_se(set_unit_path(TEST_DIR) >= 0); r = manager_new(UNIT_FILE_USER, true, &m); if (MANAGER_SKIP_TEST(r)) { - printf("Skipping test: manager_new: %s\n", strerror(-r)); + log_notice_errno(r, "Skipping test: manager_new: %m"); return EXIT_TEST_SKIP; } assert_se(r >= 0); diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c index a10227f823..6c34250a01 100644 --- a/src/test/test-stat-util.c +++ b/src/test/test-stat-util.c @@ -31,7 +31,7 @@ static void test_files_same(void) { char name[] = "/tmp/test-files_same.XXXXXX"; char name_alias[] = "/tmp/test-files_same.alias"; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(symlink(name, name_alias) >= 0); @@ -47,7 +47,7 @@ static void test_is_symlink(void) { char name_link[] = "/tmp/test-is_symlink.link"; _cleanup_close_ int fd = -1; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(symlink(name, name_link) >= 0); diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c index 84b448a095..373a1b70ba 100644 --- a/src/test/test-terminal-util.c +++ b/src/test/test-terminal-util.c @@ -50,7 +50,7 @@ static void test_read_one_char(void) { char name[] = "/tmp/test-read_one_char.XXXXXX"; int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); file = fdopen(fd, "r+"); assert_se(file); diff --git a/src/test/test-tmpfiles.c b/src/test/test-tmpfiles.c index b34ebeefb2..f35e6793b7 100644 --- a/src/test/test-tmpfiles.c +++ b/src/test/test-tmpfiles.c @@ -51,7 +51,7 @@ int main(int argc, char** argv) { log_debug("link1: %s", ans); assert_se(endswith(ans, " (deleted)")); - fd2 = mkostemp_safe(pattern, O_RDWR|O_CLOEXEC); + fd2 = mkostemp_safe(pattern); assert_se(fd >= 0); assert_se(unlink(pattern) == 0); diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index ade0ff2a63..7ef087a2e3 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -56,12 +56,12 @@ static int test_unit_file_get_set(void) { r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h, NULL, NULL); if (r == -EPERM || r == -EACCES) { - printf("Skipping test: unit_file_get_list: %s", strerror(-r)); + log_notice_errno(r, "Skipping test: unit_file_get_list: %m"); return EXIT_TEST_SKIP; } - log_full(r == 0 ? LOG_INFO : LOG_ERR, - "unit_file_get_list: %s", strerror(-r)); + log_full_errno(r == 0 ? LOG_INFO : LOG_ERR, r, + "unit_file_get_list: %m"); if (r < 0) return EXIT_FAILURE; @@ -117,7 +117,7 @@ static void test_config_parse_exec(void) { r = manager_new(UNIT_FILE_USER, true, &m); if (MANAGER_SKIP_TEST(r)) { - printf("Skipping test: manager_new: %s\n", strerror(-r)); + log_notice_errno(r, "Skipping test: manager_new: %m"); return; } @@ -485,7 +485,7 @@ static void test_load_env_file_1(void) { char name[] = "/tmp/test-load-env-file.XXXXXX"; _cleanup_close_ int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1)); @@ -508,7 +508,7 @@ static void test_load_env_file_2(void) { char name[] = "/tmp/test-load-env-file.XXXXXX"; _cleanup_close_ int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2)); @@ -526,7 +526,7 @@ static void test_load_env_file_3(void) { char name[] = "/tmp/test-load-env-file.XXXXXX"; _cleanup_close_ int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(write(fd, env_file_3, sizeof(env_file_3)) == sizeof(env_file_3)); @@ -542,7 +542,7 @@ static void test_load_env_file_4(void) { _cleanup_close_ int fd; int r; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(write(fd, env_file_4, sizeof(env_file_4)) == sizeof(env_file_4)); @@ -562,7 +562,7 @@ static void test_load_env_file_5(void) { char name[] = "/tmp/test-load-env-file.XXXXXX"; _cleanup_close_ int fd; - fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + fd = mkostemp_safe(name); assert_se(fd >= 0); assert_se(write(fd, env_file_5, sizeof(env_file_5)) == sizeof(env_file_5)); diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index eedd94e777..ece9248c2a 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -191,20 +191,12 @@ static int load_link(link_config_ctx *ctx, const char *filename) { } static bool enable_name_policy(void) { - _cleanup_free_ char *line = NULL; - const char *word, *state; + _cleanup_free_ char *value = NULL; int r; - size_t l; - r = proc_cmdline(&line); - if (r < 0) { - log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m"); - return true; - } - - FOREACH_WORD_QUOTED(word, l, line, state) - if (strneq(word, "net.ifnames=0", l)) - return false; + r = get_proc_cmdline_key("net.ifnames=", &value); + if (r > 0 && streq(value, "0")) + return false; return true; } diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c index da306a4444..5cc5abfddf 100644 --- a/src/update-done/update-done.c +++ b/src/update-done/update-done.c @@ -23,67 +23,57 @@ #include "util.h" #define MESSAGE \ - "This file was created by systemd-update-done. Its only \n" \ - "purpose is to hold a timestamp of the time this directory\n" \ - "was updated. See systemd-update-done.service(8).\n" + "# This file was created by systemd-update-done. Its only \n" \ + "# purpose is to hold a timestamp of the time this directory\n" \ + "# was updated. See systemd-update-done.service(8).\n" static int apply_timestamp(const char *path, struct timespec *ts) { struct timespec twice[2] = { *ts, *ts }; - struct stat st; + int fd = -1; + _cleanup_fclose_ FILE *f = NULL; + int r; assert(path); assert(ts); - if (stat(path, &st) >= 0) { - /* Is the timestamp file already newer than the OS? If - * so, there's nothing to do. We ignore the nanosecond - * component of the timestamp, since some file systems - * do not support any better accuracy than 1s and we - * have no way to identify the accuracy - * available. Most notably ext4 on small disks (where - * 128 byte inodes are used) does not support better - * accuracy than 1s. */ - if (st.st_mtim.tv_sec > ts->tv_sec) - return 0; - - /* It is older? Then let's update it */ - if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) { - - if (errno == EROFS) - return log_debug("Can't update timestamp file %s, file system is read-only.", path); + /* + * We store the timestamp both as mtime of the file and in the file itself, + * to support filesystems which cannot store nanosecond-precision timestamps. + * Hence, don't bother updating the file, let's just rewrite it. + */ - return log_error_errno(errno, "Failed to update timestamp on %s: %m", path); - } + r = mac_selinux_create_file_prepare(path, S_IFREG); + if (r < 0) + return log_error_errno(r, "Failed to set SELinux context for %s: %m", path); - } else if (errno == ENOENT) { - _cleanup_close_ int fd = -1; - int r; + fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); + mac_selinux_create_file_clear(); - /* The timestamp file doesn't exist yet? Then let's create it. */ + if (fd < 0) { + if (errno == EROFS) + return log_debug("Can't create timestamp file %s, file system is read-only.", path); - r = mac_selinux_create_file_prepare(path, S_IFREG); - if (r < 0) - return log_error_errno(r, "Failed to set SELinux context for %s: %m", path); - - fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644); - mac_selinux_create_file_clear(); + return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path); + } - if (fd < 0) { - if (errno == EROFS) - return log_debug("Can't create timestamp file %s, file system is read-only.", path); + f = fdopen(fd, "w"); + if (!f) { + safe_close(fd); + return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path); + } - return log_error_errno(errno, "Failed to create timestamp file %s: %m", path); - } + (void) fprintf(f, + "%s" + "TimestampNSec=" NSEC_FMT "\n", + MESSAGE, timespec_load_nsec(ts)); - (void) loop_write(fd, MESSAGE, strlen(MESSAGE), false); + fflush(f); - if (futimens(fd, twice) < 0) - return log_error_errno(errno, "Failed to update timestamp on %s: %m", path); - } else - log_error_errno(errno, "Failed to stat() timestamp file %s: %m", path); + if (futimens(fd, twice) < 0) + return log_error_errno(errno, "Failed to update timestamp on %s: %m", path); return 0; } |