diff options
485 files changed, 9507 insertions, 3678 deletions
@@ -1,5 +1,11 @@ systemd System and Service Manager +CHANGES WITH 246 in spe: + * The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows + systemd-coredump to save core files for suid processes. When saving + the core file, systemd-coredump will use the effective uid and gid of + the process that faulted. + CHANGES WITH 245: * A new tool "systemd-repart" has been added, that operates as an @@ -7,12 +7,13 @@ System and Service Manager [![Semaphore CI Build Status](https://semaphoreci.com/api/v1/projects/28a5a3ca-3c56-4078-8b5e-7ed6ef912e14/443470/shields_badge.svg)](https://semaphoreci.com/systemd/systemd)<br/> [![Coverity Scan Status](https://scan.coverity.com/projects/350/badge.svg)](https://scan.coverity.com/projects/350)<br/> [![Fuzzit Status](https://app.fuzzit.dev/badge?org_id=systemd&branch=master)](https://app.fuzzit.dev/orgs/systemd/dashboard)<br/> -[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/systemd.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)<br/> +[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/systemd.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html#systemd)<br/> [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1369/badge)](https://bestpractices.coreinfrastructure.org/projects/1369)<br/> [![Travis CI Build Status](https://travis-ci.org/systemd/systemd.svg?branch=master)](https://travis-ci.org/systemd/systemd)<br/> [![Language Grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/systemd/systemd.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/systemd/systemd/context:cpp)<br/> [![CentOS CI Build Status](https://ci.centos.org/buildStatus/icon?job=systemd-pr-build)](https://ci.centos.org/job/systemd-pr-build/)<br/> -[![Build Status](https://dev.azure.com/evvers/systemd-systemd/_apis/build/status/systemd.systemd?branchName=master)](https://dev.azure.com/evvers/systemd-systemd/_build/latest?definitionId=1&branchName=master) +[![Build Status](https://dev.azure.com/evvers/systemd-systemd/_apis/build/status/systemd.systemd?branchName=master)](https://dev.azure.com/evvers/systemd-systemd/_build/latest?definitionId=1&branchName=master)<br/> +[![Packaging status](https://repology.org/badge/tiny-repos/systemd.svg)](https://repology.org/project/systemd/versions) ## Details @@ -19,6 +19,10 @@ Janitorial Clean-ups: Features: +* drop sd_bus_message_set_priority() from sd-bus API and documentation as much + as we can, it's a kdbus left-over and unlikely to come back on AF_UNIX, since + it's not really implementable there. + * cryptsetup/homed: also support FIDO2 HMAC password logic for unlocking devices. (see: https://github.com/mjec/fido2-hmac-secret) @@ -113,7 +117,8 @@ Features: * systemd-repart: allow config of partition uuid -* userdb: allow username prefix searches in varlink API +* userdb: allow username prefix searches in varlink API, allow realname and + realname substr searches in varlink API * userdb: allow existence checks @@ -860,6 +865,7 @@ Features: make assumptions about their slice anymore. - follow PropertiesChanged state more closely, to deal with quick logouts and relogins + - (optionally?) spawn seat-manager@$SEAT.service whenever a seat shows up that as CanGraphical set * journal: - consider introducing implicit _TTY= + _PPID= + _EUID= + _EGID= + _FSUID= + _FSGID= fields diff --git a/docs/DESKTOP_ENVIRONMENTS.md b/docs/DESKTOP_ENVIRONMENTS.md new file mode 100644 index 0000000000..1c8c7aec6e --- /dev/null +++ b/docs/DESKTOP_ENVIRONMENTS.md @@ -0,0 +1,102 @@ +--- +title: Desktop Environment Integration +category: Concepts +layout: default +--- + +# Desktop Environments + +NOTE: This document is a work-in-progress. + +## Single Graphical Session + +systemd only supports running one graphical session per user at a time. +While this might not have always been the case historically, having multiple +sessions for one user running at the same time is problematic. +The DBus session bus is shared between all the logins, and services that are +started must be implicitly assigned to the user's current graphical session. + +In principle it is possible to run a single graphical session across multiple +logind seats, and this could be a way to use more than one display per user. +When a user logs in to a second seat, the seat resources could be assigned +to the existing session, allowing the graphical environment to present it +is a single seat. +Currently nothing like this is supported or even planned. + +## Pre-defined systemd units + +[`systemd.special(7)`](https://www.freedesktop.org/software/systemd/man/systemd.special.html) +defines the `graphical-session.target` and `graphical-session-pre.target` to +allow cross-desktop integration. Furthermore, systemd defines the three base +slices `background`, `apps` and `session`. +All units should be placed into one of these slices depending on their purposes: + + * `session.slice`: Contains only processes essential to run the user's graphical session + * `apps.slice`: Contains all normal applications that the user is running + * `background.slice`: Useful for low-priority background tasks + +The purpose of this grouping is to assign different priorities to the +applications. +This could e.g. mean reserving memory to session processes, +preferentially killing background tasks in out-of-memory situations +or assinging different memory/CPU/IO priorities to ensure that the session +runs smoothly under load. + +TODO: Will there be a default to place units into e.g. `apps.slice` by default +rather than the root slice? + +## XDG standardization for applications + +To ensure cross-desktop compatibility and encourage sharing of good practices, +desktop environments should adhere to the following conventions: + + * Application units should follow the scheme `apps-<launcher>-<ApplicationID>-<RANDOM>.service`, + e.g. `apps-gnome-org.gnome.Evince-12345.service`, + `apps-flatpak-org.telegram.desktop-12345.service` or `apps-KDE-org.kde.okular-12345.service`. + * Using `.service` units instead of `.scope` units, i.e. allowing systemd to + start the process on behalf of the caller, + instead of the caller starting the process and letting systemd know about it, + is encouraged. + * If no application ID is available, the launcher should generate a reasonable + name when possible (e.g. using `basename(argv[0])`). This name must not + contain a `-` character. + +This has the following advantages: + * Using the `apps-<launcher>-` prefix means that the unit defaults can be + adjusted using desktop environment specific drop-in files. + * The application ID can be retrieved by stripping the prefix and postfix. + This in turn should map to the corresponding `.desktop` file when available + +TODO: Define the name of slices that should be used. +This could be `apps-<launcher>-<ApplicationID>-<RANDOM>.slice`. + +TODO: Does it really make sense to insert the `<launcher>`? In GNOME I am +currently using a drop-in to configure `BindTo=graphical-session.target`, +`CollectMode=inactive-or-failed` and `TimeoutSec=5s`. I feel that such a +policy makes sense, but it may make much more sense to just define a +global default for all (graphical) applications. + + * Should application lifetime be bound to the session? + * May the user have applications that do not belong to the graphical session (e.g. launched from SSH)? + * Could we maybe add a default `apps-.service.d` drop-in configuration? + +## XDG autostart integration + +To allow XDG autostart integration, systemd will ship a cross-desktop generator +to create appropriate units for the autostart directory. +Desktop Environments will be able to make use of this simply by starting the +appropriate XDG related targets (representing e.g. content of the +`$XDG_CURRENT_DESKTOP` environment variable to handle `OnlyShowIn/NotShowIn`). +The names and ordering rules for these targets are to be defined. + +This generator will likely never support certain desktop specific extensions. +One such example is the GNOME specific feature to bind a service to a settings +variable. + +## Startup and shutdown best practices + +Question here are: + + * Are there strong opinions on how the session-leader process should watch the user's session units? + * Should systemd/logind/… provide an integrated way to define a session in terms of a running *user* unit? + * Is having `gnome-session-shutdown.target` that is run with `replace-irreversibly` considered a good practice? diff --git a/docs/TRANSIENT-SETTINGS.md b/docs/TRANSIENT-SETTINGS.md index 271d8ab1e3..d5a8046676 100644 --- a/docs/TRANSIENT-SETTINGS.md +++ b/docs/TRANSIENT-SETTINGS.md @@ -114,6 +114,7 @@ All execution-related settings are available for transient units. ✓ SupplementaryGroups= ✓ Nice= ✓ OOMScoreAdjust= +✓ CoredumpFilter= ✓ IOSchedulingClass= ✓ IOSchedulingPriority= ✓ CPUSchedulingPolicy= diff --git a/fuzzbuzz.yaml b/fuzzbuzz.yaml deleted file mode 100644 index 2cd1763a6d..0000000000 --- a/fuzzbuzz.yaml +++ /dev/null @@ -1,33 +0,0 @@ -base: ubuntu:16.04 -language: c -setup: -- sudo bash -c "echo 'deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse' >>/etc/apt/sources.list" -- sudo apt-get update -y -- sudo apt-get build-dep -y systemd -- sudo apt-get install -y python3-pip -- sudo apt-get install -y libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev -- pip3 install meson ninja -- export PATH="$HOME/.local/bin/:$PATH" -- CC=$FUZZ_CC CXX=$FUZZ_CXX meson -Dfuzzbuzz=true -Dfuzzbuzz-engine-dir=$(dirname "$FUZZ_ENGINE") -Dfuzzbuzz-engine=$(cut -d. -f1 <(basename "$FUZZ_ENGINE")) -Db_lundef=false ./build -- ninja -v -C ./build fuzzers -environment: -targets: -- name: fuzz-compress - harness: - binary: ./build/fuzz-compress -- name: fuzz-unit-file - harness: - binary: ./build/fuzz-unit-file - corpus: ./test/fuzz/fuzz-unit-file -- name: fuzz-journald-syslog - harness: - binary: ./build/fuzz-journald-syslog - corpus: ./test/fuzz/fuzz-journald-syslog -- name: fuzz-netdev-parser - harness: - binary: ./build/fuzz-netdev-parser - corpus: ./test/fuzz/fuzz-netdev-parser -- name: fuzz-network-parser - harness: - binary: ./build/fuzz-network-parser - corpus: ./test/fuzz/fuzz-network-parser diff --git a/hwdb.d/20-bluetooth-vendor-product.hwdb b/hwdb.d/20-bluetooth-vendor-product.hwdb index 9cba3bfc05..1d92f57ecc 100644 --- a/hwdb.d/20-bluetooth-vendor-product.hwdb +++ b/hwdb.d/20-bluetooth-vendor-product.hwdb @@ -46,7 +46,7 @@ bluetooth:v000D* ID_VENDOR_FROM_DATABASE=Texas Instruments Inc. bluetooth:v000E* - ID_VENDOR_FROM_DATABASE=Ceva, Inc. (formerly Parthus Technologies, Inc.) + ID_VENDOR_FROM_DATABASE=Parthus Technologies Inc. bluetooth:v000F* ID_VENDOR_FROM_DATABASE=Broadcom Corporation @@ -55,7 +55,7 @@ bluetooth:v0010* ID_VENDOR_FROM_DATABASE=Mitel Semiconductor bluetooth:v0011* - ID_VENDOR_FROM_DATABASE=Widcomm, Inc + ID_VENDOR_FROM_DATABASE=Widcomm, Inc. bluetooth:v0012* ID_VENDOR_FROM_DATABASE=Zeevo, Inc. @@ -73,7 +73,7 @@ bluetooth:v0016* ID_VENDOR_FROM_DATABASE=KC Technology Inc. bluetooth:v0017* - ID_VENDOR_FROM_DATABASE=NewLogic + ID_VENDOR_FROM_DATABASE=Newlogic bluetooth:v0018* ID_VENDOR_FROM_DATABASE=Transilica, Inc. @@ -172,13 +172,13 @@ bluetooth:v0037* ID_VENDOR_FROM_DATABASE=Mobilian Corporation bluetooth:v0038* - ID_VENDOR_FROM_DATABASE=Terax + ID_VENDOR_FROM_DATABASE=Syntronix Corporation bluetooth:v0039* ID_VENDOR_FROM_DATABASE=Integrated System Solution Corp. bluetooth:v003A* - ID_VENDOR_FROM_DATABASE=Matsushita Electric Industrial Co., Ltd. + ID_VENDOR_FROM_DATABASE=Panasonic Corporation (formerly Matsushita Electric Industrial Co., Ltd.) bluetooth:v003B* ID_VENDOR_FROM_DATABASE=Gennum Corporation @@ -190,10 +190,10 @@ bluetooth:v003D* ID_VENDOR_FROM_DATABASE=IPextreme, Inc. bluetooth:v003E* - ID_VENDOR_FROM_DATABASE=Systems and Chips, Inc. + ID_VENDOR_FROM_DATABASE=Systems and Chips, Inc bluetooth:v003F* - ID_VENDOR_FROM_DATABASE=Bluetooth SIG, Inc. + ID_VENDOR_FROM_DATABASE=Bluetooth SIG, Inc bluetooth:v0040* ID_VENDOR_FROM_DATABASE=Seiko Epson Corporation @@ -205,7 +205,7 @@ bluetooth:v0042* ID_VENDOR_FROM_DATABASE=CONWISE Technology Corporation Ltd bluetooth:v0043* - ID_VENDOR_FROM_DATABASE=PARROT SA + ID_VENDOR_FROM_DATABASE=PARROT AUTOMOTIVE SAS bluetooth:v0044* ID_VENDOR_FROM_DATABASE=Socket Mobile @@ -241,10 +241,10 @@ bluetooth:v004E* ID_VENDOR_FROM_DATABASE=Avago Technologies bluetooth:v004F* - ID_VENDOR_FROM_DATABASE=APT Licensing Ltd. + ID_VENDOR_FROM_DATABASE=APT Ltd. bluetooth:v0050* - ID_VENDOR_FROM_DATABASE=SiRF Technology + ID_VENDOR_FROM_DATABASE=SiRF Technology, Inc. bluetooth:v0051* ID_VENDOR_FROM_DATABASE=Tzero Technologies, Inc. @@ -331,7 +331,7 @@ bluetooth:v006C* ID_VENDOR_FROM_DATABASE=Beautiful Enterprise Co., Ltd. bluetooth:v006D* - ID_VENDOR_FROM_DATABASE=BriarTek, Inc. + ID_VENDOR_FROM_DATABASE=BriarTek, Inc bluetooth:v006E* ID_VENDOR_FROM_DATABASE=Summit Data Communications, Inc. @@ -382,7 +382,7 @@ bluetooth:v007C* ID_VENDOR_FROM_DATABASE=A & R Cambridge bluetooth:v007D* - ID_VENDOR_FROM_DATABASE=Seers Technology Co. Ltd + ID_VENDOR_FROM_DATABASE=Seers Technology Co., Ltd. bluetooth:v007E* ID_VENDOR_FROM_DATABASE=Sports Tracking Technologies Ltd. @@ -409,7 +409,7 @@ bluetooth:v0085* ID_VENDOR_FROM_DATABASE=BlueRadios, Inc. bluetooth:v0086* - ID_VENDOR_FROM_DATABASE=equinox AG + ID_VENDOR_FROM_DATABASE=Equinux AG bluetooth:v0087* ID_VENDOR_FROM_DATABASE=Garmin International, Inc. @@ -433,16 +433,16 @@ bluetooth:v008D* ID_VENDOR_FROM_DATABASE=Zscan Software bluetooth:v008E* - ID_VENDOR_FROM_DATABASE=Quintic Corp. + ID_VENDOR_FROM_DATABASE=Quintic Corp bluetooth:v008F* - ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions GmbH (Formerly Stollman E+V GmbH) + ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions GmbH (formerly Stollmann E+V GmbH) bluetooth:v0090* ID_VENDOR_FROM_DATABASE=Funai Electric Co., Ltd. bluetooth:v0091* - ID_VENDOR_FROM_DATABASE=Advanced PANMOBIL Systems GmbH & Co. KG + ID_VENDOR_FROM_DATABASE=Advanced PANMOBIL systems GmbH & Co. KG bluetooth:v0092* ID_VENDOR_FROM_DATABASE=ThinkOptics, Inc. @@ -462,8 +462,11 @@ bluetooth:v0096* bluetooth:v0097* ID_VENDOR_FROM_DATABASE=ConnecteDevice Ltd. +bluetooth:v0097p0002* + ID_PRODUCT_FROM_DATABASE=COOKOO watch + bluetooth:v0098* - ID_VENDOR_FROM_DATABASE=zer01.tv GmbH + ID_VENDOR_FROM_DATABASE=zero1.tv GmbH bluetooth:v0099* ID_VENDOR_FROM_DATABASE=i.Tech Dynamic Global Distribution Ltd. @@ -514,7 +517,7 @@ bluetooth:v00A8* ID_VENDOR_FROM_DATABASE=ARP Devices Limited bluetooth:v00A9* - ID_VENDOR_FROM_DATABASE=Magneti Marelli S.p.A + ID_VENDOR_FROM_DATABASE=MARELLI EUROPE S.P.A. (formerly Magneti Marelli S.p.A.) bluetooth:v00AA* ID_VENDOR_FROM_DATABASE=CAEN RFID srl @@ -712,7 +715,7 @@ bluetooth:v00EA* ID_VENDOR_FROM_DATABASE=Nielsen-Kellerman Company bluetooth:v00EB* - ID_VENDOR_FROM_DATABASE=Server Technology, Inc. + ID_VENDOR_FROM_DATABASE=Server Technology Inc. bluetooth:v00EC* ID_VENDOR_FROM_DATABASE=BioResearch Associates @@ -733,7 +736,7 @@ bluetooth:v00F1* ID_VENDOR_FROM_DATABASE=Witron Technology Limited bluetooth:v00F2* - ID_VENDOR_FROM_DATABASE=Aether Things Inc. (formerly Morse Project Inc.) + ID_VENDOR_FROM_DATABASE=Morse Project Inc. bluetooth:v00F3* ID_VENDOR_FROM_DATABASE=Kent Displays Inc. @@ -748,7 +751,7 @@ bluetooth:v00F6* ID_VENDOR_FROM_DATABASE=Elcometer Limited bluetooth:v00F7* - ID_VENDOR_FROM_DATABASE=VSN Technologies Inc. + ID_VENDOR_FROM_DATABASE=VSN Technologies, Inc. bluetooth:v00F8* ID_VENDOR_FROM_DATABASE=AceUni Corp., Ltd. @@ -769,7 +772,7 @@ bluetooth:v00FD* ID_VENDOR_FROM_DATABASE=ValenceTech Limited bluetooth:v00FE* - ID_VENDOR_FROM_DATABASE=Reserved + ID_VENDOR_FROM_DATABASE=Stanley Black and Decker bluetooth:v00FF* ID_VENDOR_FROM_DATABASE=Typo Products, LLC @@ -778,7 +781,7 @@ bluetooth:v0100* ID_VENDOR_FROM_DATABASE=TomTom International BV bluetooth:v0101* - ID_VENDOR_FROM_DATABASE=Fugoo, Inc + ID_VENDOR_FROM_DATABASE=Fugoo, Inc. bluetooth:v0102* ID_VENDOR_FROM_DATABASE=Keiser Corporation @@ -787,7 +790,7 @@ bluetooth:v0103* ID_VENDOR_FROM_DATABASE=Bang & Olufsen A/S bluetooth:v0104* - ID_VENDOR_FROM_DATABASE=PLUS Locations Systems Pty Ltd + ID_VENDOR_FROM_DATABASE=PLUS Location Systems Pty Ltd bluetooth:v0105* ID_VENDOR_FROM_DATABASE=Ubiquitous Computing Technology Corporation @@ -805,22 +808,22 @@ bluetooth:v0109* ID_VENDOR_FROM_DATABASE=Atus BV bluetooth:v010A* - ID_VENDOR_FROM_DATABASE=Codegate Ltd. + ID_VENDOR_FROM_DATABASE=Codegate Ltd bluetooth:v010B* - ID_VENDOR_FROM_DATABASE=ERi, Inc. + ID_VENDOR_FROM_DATABASE=ERi, Inc bluetooth:v010C* ID_VENDOR_FROM_DATABASE=Transducers Direct, LLC bluetooth:v010D* - ID_VENDOR_FROM_DATABASE=Fujitsu Ten Limited + ID_VENDOR_FROM_DATABASE=DENSO TEN LIMITED (formerly Fujitsu Ten LImited) bluetooth:v010E* ID_VENDOR_FROM_DATABASE=Audi AG bluetooth:v010F* - ID_VENDOR_FROM_DATABASE=HiSilicon Technologies Co., Ltd. + ID_VENDOR_FROM_DATABASE=HiSilicon Technologies CO., LIMITED bluetooth:v0110* ID_VENDOR_FROM_DATABASE=Nippon Seiki Co., Ltd. @@ -841,7 +844,7 @@ bluetooth:v0115* ID_VENDOR_FROM_DATABASE=e.solutions bluetooth:v0116* - ID_VENDOR_FROM_DATABASE=1OAK Technologies + ID_VENDOR_FROM_DATABASE=10AK Technologies bluetooth:v0117* ID_VENDOR_FROM_DATABASE=Wimoto Technologies Inc @@ -880,7 +883,7 @@ bluetooth:v0122* ID_VENDOR_FROM_DATABASE=AirTurn, Inc. bluetooth:v0123* - ID_VENDOR_FROM_DATABASE=Kinsa, Inc. + ID_VENDOR_FROM_DATABASE=Kinsa, Inc bluetooth:v0124* ID_VENDOR_FROM_DATABASE=HID Global @@ -901,7 +904,7 @@ bluetooth:v0129* ID_VENDOR_FROM_DATABASE=Nimble Devices Oy bluetooth:v012A* - ID_VENDOR_FROM_DATABASE=Changzhou Yongse Infotech Co., Ltd + ID_VENDOR_FROM_DATABASE=Changzhou Yongse Infotech Co., Ltd. bluetooth:v012B* ID_VENDOR_FROM_DATABASE=SportIQ @@ -916,13 +919,13 @@ bluetooth:v012E* ID_VENDOR_FROM_DATABASE=ASSA ABLOY bluetooth:v012F* - ID_VENDOR_FROM_DATABASE=Clarion Co., Ltd. + ID_VENDOR_FROM_DATABASE=Clarion Co. Inc. bluetooth:v0130* ID_VENDOR_FROM_DATABASE=Warehouse Innovations bluetooth:v0131* - ID_VENDOR_FROM_DATABASE=Cypress Semiconductor Corporation + ID_VENDOR_FROM_DATABASE=Cypress Semiconductor bluetooth:v0132* ID_VENDOR_FROM_DATABASE=MADS Inc @@ -931,13 +934,13 @@ bluetooth:v0133* ID_VENDOR_FROM_DATABASE=Blue Maestro Limited bluetooth:v0134* - ID_VENDOR_FROM_DATABASE=Resolution Products, Inc. + ID_VENDOR_FROM_DATABASE=Resolution Products, Ltd. bluetooth:v0135* - ID_VENDOR_FROM_DATABASE=Airewear LLC + ID_VENDOR_FROM_DATABASE=Aireware LLC bluetooth:v0136* - ID_VENDOR_FROM_DATABASE=Seed Labs, Inc. (formerly ETC sp. z.o.o.) + ID_VENDOR_FROM_DATABASE=Silvair, Inc. bluetooth:v0137* ID_VENDOR_FROM_DATABASE=Prestigio Plaza Ltd. @@ -949,13 +952,13 @@ bluetooth:v0139* ID_VENDOR_FROM_DATABASE=Focus Systems Corporation bluetooth:v013A* - ID_VENDOR_FROM_DATABASE=Tencent Holdings Limited + ID_VENDOR_FROM_DATABASE=Tencent Holdings Ltd. bluetooth:v013B* ID_VENDOR_FROM_DATABASE=Allegion bluetooth:v013C* - ID_VENDOR_FROM_DATABASE=Murata Manufacuring Co., Ltd. + ID_VENDOR_FROM_DATABASE=Murata Manufacturing Co., Ltd. bluetooth:v013D* ID_VENDOR_FROM_DATABASE=WirelessWERX @@ -1006,7 +1009,7 @@ bluetooth:v014C* ID_VENDOR_FROM_DATABASE=Mesh-Net Ltd bluetooth:v014D* - ID_VENDOR_FROM_DATABASE=Huizhou Desay SV Automotive CO., LTD. + ID_VENDOR_FROM_DATABASE=HUIZHOU DESAY SV AUTOMOTIVE CO., LTD. bluetooth:v014E* ID_VENDOR_FROM_DATABASE=Tangerine, Inc. @@ -1069,7 +1072,7 @@ bluetooth:v0161* ID_VENDOR_FROM_DATABASE=yikes bluetooth:v0162* - ID_VENDOR_FROM_DATABASE=MADSGlobal NZ Ltd. + ID_VENDOR_FROM_DATABASE=MADSGlobalNZ Ltd. bluetooth:v0163* ID_VENDOR_FROM_DATABASE=PCH International @@ -1078,13 +1081,13 @@ bluetooth:v0164* ID_VENDOR_FROM_DATABASE=Qingdao Yeelink Information Technology Co., Ltd. bluetooth:v0165* - ID_VENDOR_FROM_DATABASE=Milwaukee Tool (formerly Milwaukee Electric Tools) + ID_VENDOR_FROM_DATABASE=Milwaukee Tool (Formally Milwaukee Electric Tools) bluetooth:v0166* ID_VENDOR_FROM_DATABASE=MISHIK Pte Ltd bluetooth:v0167* - ID_VENDOR_FROM_DATABASE=Bayer HealthCare + ID_VENDOR_FROM_DATABASE=Ascensia Diabetes Care US Inc. bluetooth:v0168* ID_VENDOR_FROM_DATABASE=Spicebox LLC @@ -1111,7 +1114,7 @@ bluetooth:v016F* ID_VENDOR_FROM_DATABASE=Podo Labs, Inc bluetooth:v0170* - ID_VENDOR_FROM_DATABASE=F. Hoffmann-La Roche AG + ID_VENDOR_FROM_DATABASE=Roche Diabetes Care AG bluetooth:v0171* ID_VENDOR_FROM_DATABASE=Amazon Fulfillment Service @@ -1123,7 +1126,7 @@ bluetooth:v0173* ID_VENDOR_FROM_DATABASE=Kocomojo, LLC bluetooth:v0174* - ID_VENDOR_FROM_DATABASE=Everykey LLC + ID_VENDOR_FROM_DATABASE=Everykey Inc. bluetooth:v0175* ID_VENDOR_FROM_DATABASE=Dynamic Controls @@ -1156,7 +1159,7 @@ bluetooth:v017E* ID_VENDOR_FROM_DATABASE=BluDotz Ltd bluetooth:v017F* - ID_VENDOR_FROM_DATABASE=XTel ApS + ID_VENDOR_FROM_DATABASE=XTel Wireless ApS bluetooth:v0180* ID_VENDOR_FROM_DATABASE=Gigaset Communications GmbH @@ -1168,7 +1171,7 @@ bluetooth:v0182* ID_VENDOR_FROM_DATABASE=HOP Ubiquitous bluetooth:v0183* - ID_VENDOR_FROM_DATABASE=To Be Assigned + ID_VENDOR_FROM_DATABASE=Walt Disney bluetooth:v0184* ID_VENDOR_FROM_DATABASE=Nectar @@ -1228,10 +1231,10 @@ bluetooth:v0196* ID_VENDOR_FROM_DATABASE=Paxton Access Ltd bluetooth:v0197* - ID_VENDOR_FROM_DATABASE=WiSilica Inc + ID_VENDOR_FROM_DATABASE=WiSilica Inc. bluetooth:v0198* - ID_VENDOR_FROM_DATABASE=VENGIT Korlátolt Felelősségű Társaság + ID_VENDOR_FROM_DATABASE=VENGIT Korlatolt Felelossegu Tarsasag bluetooth:v0199* ID_VENDOR_FROM_DATABASE=SALTO SYSTEMS S.L. @@ -1273,7 +1276,7 @@ bluetooth:v01A5* ID_VENDOR_FROM_DATABASE=Icon Health and Fitness bluetooth:v01A6* - ID_VENDOR_FROM_DATABASE=Asandoo GmbH + ID_VENDOR_FROM_DATABASE=Wille Engineering (formely as Asandoo GmbH) bluetooth:v01A7* ID_VENDOR_FROM_DATABASE=ENERGOUS CORPORATION @@ -1291,7 +1294,7 @@ bluetooth:v01AB* ID_VENDOR_FROM_DATABASE=Facebook, Inc. bluetooth:v01AC* - ID_VENDOR_FROM_DATABASE=Nipro Diagnostics, Inc. + ID_VENDOR_FROM_DATABASE=Trividia Health, Inc. bluetooth:v01AD* ID_VENDOR_FROM_DATABASE=FlightSafety International @@ -1402,7 +1405,7 @@ bluetooth:v01D0* ID_VENDOR_FROM_DATABASE=Primus Inter Pares Ltd bluetooth:v01D1* - ID_VENDOR_FROM_DATABASE=August + ID_VENDOR_FROM_DATABASE=August Home, Inc bluetooth:v01D2* ID_VENDOR_FROM_DATABASE=Gill Electronics @@ -1474,7 +1477,7 @@ bluetooth:v01E8* ID_VENDOR_FROM_DATABASE=STIR bluetooth:v01E9* - ID_VENDOR_FROM_DATABASE=Sano, Inc + ID_VENDOR_FROM_DATABASE=Sano, Inc. bluetooth:v01EA* ID_VENDOR_FROM_DATABASE=Advanced Application Design, Inc. @@ -1522,10 +1525,10 @@ bluetooth:v01F8* ID_VENDOR_FROM_DATABASE=Anyka (Guangzhou) Microelectronics Technology Co, LTD bluetooth:v01F9* - ID_VENDOR_FROM_DATABASE=Medtronic, Inc. + ID_VENDOR_FROM_DATABASE=Medtronic Inc. bluetooth:v01FA* - ID_VENDOR_FROM_DATABASE=Gozio, Inc. + ID_VENDOR_FROM_DATABASE=Gozio Inc. bluetooth:v01FB* ID_VENDOR_FROM_DATABASE=Form Lifting, LLC @@ -1537,13 +1540,13 @@ bluetooth:v01FD* ID_VENDOR_FROM_DATABASE=Kontakt Micro-Location Sp. z o.o. bluetooth:v01FE* - ID_VENDOR_FROM_DATABASE=Radio System Corporation + ID_VENDOR_FROM_DATABASE=Radio Systems Corporation bluetooth:v01FF* ID_VENDOR_FROM_DATABASE=Freescale Semiconductor, Inc. bluetooth:v0200* - ID_VENDOR_FROM_DATABASE=Verifone Systems PTe Ltd. Taiwan Branch + ID_VENDOR_FROM_DATABASE=Verifone Systems Pte Ltd. Taiwan Branch bluetooth:v0201* ID_VENDOR_FROM_DATABASE=AR Timing @@ -1624,7 +1627,7 @@ bluetooth:v021A* ID_VENDOR_FROM_DATABASE=Blue Speck Labs, LLC bluetooth:v021B* - ID_VENDOR_FROM_DATABASE=Cisco Systems Inc + ID_VENDOR_FROM_DATABASE=Cisco Systems, Inc bluetooth:v021C* ID_VENDOR_FROM_DATABASE=Mobicomm Inc @@ -1633,10 +1636,10 @@ bluetooth:v021D* ID_VENDOR_FROM_DATABASE=Edamic bluetooth:v021E* - ID_VENDOR_FROM_DATABASE=Goodnet Ltd + ID_VENDOR_FROM_DATABASE=Goodnet, Ltd bluetooth:v021F* - ID_VENDOR_FROM_DATABASE=Luster Leaf Products Inc + ID_VENDOR_FROM_DATABASE=Luster Leaf Products Inc bluetooth:v0220* ID_VENDOR_FROM_DATABASE=Manus Machina BV @@ -1717,7 +1720,7 @@ bluetooth:v0239* ID_VENDOR_FROM_DATABASE=JIN CO, Ltd bluetooth:v023A* - ID_VENDOR_FROM_DATABASE=Alatech Technology + ID_VENDOR_FROM_DATABASE=Alatech Tehnology bluetooth:v023B* ID_VENDOR_FROM_DATABASE=Beijing CarePulse Electronic Technology Co, Ltd @@ -1732,7 +1735,7 @@ bluetooth:v023E* ID_VENDOR_FROM_DATABASE=Raven Industries bluetooth:v023F* - ID_VENDOR_FROM_DATABASE=WaveWare Technologies + ID_VENDOR_FROM_DATABASE=WaveWare Technologies Inc. bluetooth:v0240* ID_VENDOR_FROM_DATABASE=Argenox Technologies @@ -1747,10 +1750,10 @@ bluetooth:v0243* ID_VENDOR_FROM_DATABASE=Masimo Corp bluetooth:v0244* - ID_VENDOR_FROM_DATABASE=Iotera Inc. + ID_VENDOR_FROM_DATABASE=Iotera Inc bluetooth:v0245* - ID_VENDOR_FROM_DATABASE=Endress+Hauser + ID_VENDOR_FROM_DATABASE=Endress+Hauser bluetooth:v0246* ID_VENDOR_FROM_DATABASE=ACKme Networks, Inc. @@ -1819,7 +1822,7 @@ bluetooth:v025B* ID_VENDOR_FROM_DATABASE=Five Interactive, LLC dba Zendo bluetooth:v025C* - ID_VENDOR_FROM_DATABASE=NetEase (Hangzhou) Network co.Ltd. + ID_VENDOR_FROM_DATABASE=NetEase(Hangzhou)Network co.Ltd. bluetooth:v025D* ID_VENDOR_FROM_DATABASE=Lexmark International Inc. @@ -1897,7 +1900,7 @@ bluetooth:v0275* ID_VENDOR_FROM_DATABASE=Geotab bluetooth:v0276* - ID_VENDOR_FROM_DATABASE=E.G.O. Elektro-Gerätebau GmbH + ID_VENDOR_FROM_DATABASE=E.G.O. Elektro-Geraetebau GmbH bluetooth:v0277* ID_VENDOR_FROM_DATABASE=bewhere inc @@ -1918,7 +1921,7 @@ bluetooth:v027C* ID_VENDOR_FROM_DATABASE=Aseptika Ltd bluetooth:v027D* - ID_VENDOR_FROM_DATABASE=HUAWEI Technologies Co., Ltd. ( 华为技术有限公司 ) + ID_VENDOR_FROM_DATABASE=HUAWEI Technologies Co., Ltd. bluetooth:v027E* ID_VENDOR_FROM_DATABASE=HabitAware, LLC @@ -2323,7 +2326,7 @@ bluetooth:v0303* ID_VENDOR_FROM_DATABASE=IACA electronique bluetooth:v0304* - ID_VENDOR_FROM_DATABASE=Martians Inc + ID_VENDOR_FROM_DATABASE=Proxy Technologies, Inc. bluetooth:v0305* ID_VENDOR_FROM_DATABASE=Swipp ApS @@ -3082,7 +3085,7 @@ bluetooth:v0400* ID_VENDOR_FROM_DATABASE=i-developer IT Beratung UG bluetooth:v0401* - ID_VENDOR_FROM_DATABASE=リレーションズ株式会社 + ID_VENDOR_FROM_DATABASE=Relations Inc. bluetooth:v0402* ID_VENDOR_FROM_DATABASE=Sears Holdings Corporation @@ -3119,3 +3122,3555 @@ bluetooth:v040C* bluetooth:v040D* ID_VENDOR_FROM_DATABASE=NorthStar Battery Company, LLC + +bluetooth:v040E* + ID_VENDOR_FROM_DATABASE=SKF (U.K.) Limited + +bluetooth:v040F* + ID_VENDOR_FROM_DATABASE=CO-AX Technology, Inc. + +bluetooth:v0410* + ID_VENDOR_FROM_DATABASE=Fender Musical Instruments + +bluetooth:v0411* + ID_VENDOR_FROM_DATABASE=Luidia Inc + +bluetooth:v0412* + ID_VENDOR_FROM_DATABASE=SEFAM + +bluetooth:v0413* + ID_VENDOR_FROM_DATABASE=Wireless Cables Inc + +bluetooth:v0414* + ID_VENDOR_FROM_DATABASE=Lightning Protection International Pty Ltd + +bluetooth:v0415* + ID_VENDOR_FROM_DATABASE=Uber Technologies Inc + +bluetooth:v0416* + ID_VENDOR_FROM_DATABASE=SODA GmbH + +bluetooth:v0417* + ID_VENDOR_FROM_DATABASE=Fatigue Science + +bluetooth:v0418* + ID_VENDOR_FROM_DATABASE=Alpine Electronics Inc. + +bluetooth:v0419* + ID_VENDOR_FROM_DATABASE=Novalogy LTD + +bluetooth:v041A* + ID_VENDOR_FROM_DATABASE=Friday Labs Limited + +bluetooth:v041B* + ID_VENDOR_FROM_DATABASE=OrthoAccel Technologies + +bluetooth:v041C* + ID_VENDOR_FROM_DATABASE=WaterGuru, Inc. + +bluetooth:v041D* + ID_VENDOR_FROM_DATABASE=Benning Elektrotechnik und Elektronik GmbH & Co. KG + +bluetooth:v041E* + ID_VENDOR_FROM_DATABASE=Dell Computer Corporation + +bluetooth:v041F* + ID_VENDOR_FROM_DATABASE=Kopin Corporation + +bluetooth:v0420* + ID_VENDOR_FROM_DATABASE=TecBakery GmbH + +bluetooth:v0421* + ID_VENDOR_FROM_DATABASE=Backbone Labs, Inc. + +bluetooth:v0422* + ID_VENDOR_FROM_DATABASE=DELSEY SA + +bluetooth:v0423* + ID_VENDOR_FROM_DATABASE=Chargifi Limited + +bluetooth:v0424* + ID_VENDOR_FROM_DATABASE=Trainesense Ltd. + +bluetooth:v0425* + ID_VENDOR_FROM_DATABASE=Unify Software and Solutions GmbH & Co. KG + +bluetooth:v0426* + ID_VENDOR_FROM_DATABASE=Husqvarna AB + +bluetooth:v0427* + ID_VENDOR_FROM_DATABASE=Focus fleet and fuel management inc + +bluetooth:v0428* + ID_VENDOR_FROM_DATABASE=SmallLoop, LLC + +bluetooth:v0429* + ID_VENDOR_FROM_DATABASE=Prolon Inc. + +bluetooth:v042A* + ID_VENDOR_FROM_DATABASE=BD Medical + +bluetooth:v042B* + ID_VENDOR_FROM_DATABASE=iMicroMed Incorporated + +bluetooth:v042C* + ID_VENDOR_FROM_DATABASE=Ticto N.V. + +bluetooth:v042D* + ID_VENDOR_FROM_DATABASE=Meshtech AS + +bluetooth:v042E* + ID_VENDOR_FROM_DATABASE=MemCachier Inc. + +bluetooth:v042F* + ID_VENDOR_FROM_DATABASE=Danfoss A/S + +bluetooth:v0430* + ID_VENDOR_FROM_DATABASE=SnapStyk Inc. + +bluetooth:v0431* + ID_VENDOR_FROM_DATABASE=Amway Corporation + +bluetooth:v0432* + ID_VENDOR_FROM_DATABASE=Silk Labs, Inc. + +bluetooth:v0433* + ID_VENDOR_FROM_DATABASE=Pillsy Inc. + +bluetooth:v0434* + ID_VENDOR_FROM_DATABASE=Hatch Baby, Inc. + +bluetooth:v0435* + ID_VENDOR_FROM_DATABASE=Blocks Wearables Ltd. + +bluetooth:v0436* + ID_VENDOR_FROM_DATABASE=Drayson Technologies (Europe) Limited + +bluetooth:v0437* + ID_VENDOR_FROM_DATABASE=eBest IOT Inc. + +bluetooth:v0438* + ID_VENDOR_FROM_DATABASE=Helvar Ltd + +bluetooth:v0439* + ID_VENDOR_FROM_DATABASE=Radiance Technologies + +bluetooth:v043A* + ID_VENDOR_FROM_DATABASE=Nuheara Limited + +bluetooth:v043B* + ID_VENDOR_FROM_DATABASE=Appside co., ltd. + +bluetooth:v043C* + ID_VENDOR_FROM_DATABASE=DeLaval + +bluetooth:v043D* + ID_VENDOR_FROM_DATABASE=Coiler Corporation + +bluetooth:v043E* + ID_VENDOR_FROM_DATABASE=Thermomedics, Inc. + +bluetooth:v043F* + ID_VENDOR_FROM_DATABASE=Tentacle Sync GmbH + +bluetooth:v0440* + ID_VENDOR_FROM_DATABASE=Valencell, Inc. + +bluetooth:v0441* + ID_VENDOR_FROM_DATABASE=iProtoXi Oy + +bluetooth:v0442* + ID_VENDOR_FROM_DATABASE=SECOM CO., LTD. + +bluetooth:v0443* + ID_VENDOR_FROM_DATABASE=Tucker International LLC + +bluetooth:v0444* + ID_VENDOR_FROM_DATABASE=Metanate Limited + +bluetooth:v0445* + ID_VENDOR_FROM_DATABASE=Kobian Canada Inc. + +bluetooth:v0446* + ID_VENDOR_FROM_DATABASE=NETGEAR, Inc. + +bluetooth:v0447* + ID_VENDOR_FROM_DATABASE=Fabtronics Australia Pty Ltd + +bluetooth:v0448* + ID_VENDOR_FROM_DATABASE=Grand Centrix GmbH + +bluetooth:v0449* + ID_VENDOR_FROM_DATABASE=1UP USA.com llc + +bluetooth:v044A* + ID_VENDOR_FROM_DATABASE=SHIMANO INC. + +bluetooth:v044B* + ID_VENDOR_FROM_DATABASE=Nain Inc. + +bluetooth:v044C* + ID_VENDOR_FROM_DATABASE=LifeStyle Lock, LLC + +bluetooth:v044D* + ID_VENDOR_FROM_DATABASE=VEGA Grieshaber KG + +bluetooth:v044E* + ID_VENDOR_FROM_DATABASE=Xtrava Inc. + +bluetooth:v044F* + ID_VENDOR_FROM_DATABASE=TTS Tooltechnic Systems AG & Co. KG + +bluetooth:v0450* + ID_VENDOR_FROM_DATABASE=Teenage Engineering AB + +bluetooth:v0451* + ID_VENDOR_FROM_DATABASE=Tunstall Nordic AB + +bluetooth:v0452* + ID_VENDOR_FROM_DATABASE=Svep Design Center AB + +bluetooth:v0453* + ID_VENDOR_FROM_DATABASE=GreenPeak Technologies BV + +bluetooth:v0454* + ID_VENDOR_FROM_DATABASE=Sphinx Electronics GmbH & Co KG + +bluetooth:v0455* + ID_VENDOR_FROM_DATABASE=Atomation + +bluetooth:v0456* + ID_VENDOR_FROM_DATABASE=Nemik Consulting Inc + +bluetooth:v0457* + ID_VENDOR_FROM_DATABASE=RF INNOVATION + +bluetooth:v0458* + ID_VENDOR_FROM_DATABASE=Mini Solution Co., Ltd. + +bluetooth:v0459* + ID_VENDOR_FROM_DATABASE=Lumenetix, Inc + +bluetooth:v045A* + ID_VENDOR_FROM_DATABASE=2048450 Ontario Inc + +bluetooth:v045B* + ID_VENDOR_FROM_DATABASE=SPACEEK LTD + +bluetooth:v045C* + ID_VENDOR_FROM_DATABASE=Delta T Corporation + +bluetooth:v045D* + ID_VENDOR_FROM_DATABASE=Boston Scientific Corporation + +bluetooth:v045E* + ID_VENDOR_FROM_DATABASE=Nuviz, Inc. + +bluetooth:v045F* + ID_VENDOR_FROM_DATABASE=Real Time Automation, Inc. + +bluetooth:v0460* + ID_VENDOR_FROM_DATABASE=Kolibree + +bluetooth:v0461* + ID_VENDOR_FROM_DATABASE=vhf elektronik GmbH + +bluetooth:v0462* + ID_VENDOR_FROM_DATABASE=Bonsai Systems GmbH + +bluetooth:v0463* + ID_VENDOR_FROM_DATABASE=Fathom Systems Inc. + +bluetooth:v0464* + ID_VENDOR_FROM_DATABASE=Bellman & Symfon + +bluetooth:v0465* + ID_VENDOR_FROM_DATABASE=International Forte Group LLC + +bluetooth:v0466* + ID_VENDOR_FROM_DATABASE=CycleLabs Solutions inc. + +bluetooth:v0467* + ID_VENDOR_FROM_DATABASE=Codenex Oy + +bluetooth:v0468* + ID_VENDOR_FROM_DATABASE=Kynesim Ltd + +bluetooth:v0469* + ID_VENDOR_FROM_DATABASE=Palago AB + +bluetooth:v046A* + ID_VENDOR_FROM_DATABASE=INSIGMA INC. + +bluetooth:v046B* + ID_VENDOR_FROM_DATABASE=PMD Solutions + +bluetooth:v046C* + ID_VENDOR_FROM_DATABASE=Qingdao Realtime Technology Co., Ltd. + +bluetooth:v046D* + ID_VENDOR_FROM_DATABASE=BEGA Gantenbrink-Leuchten KG + +bluetooth:v046E* + ID_VENDOR_FROM_DATABASE=Pambor Ltd. + +bluetooth:v046F* + ID_VENDOR_FROM_DATABASE=Develco Products A/S + +bluetooth:v0470* + ID_VENDOR_FROM_DATABASE=iDesign s.r.l. + +bluetooth:v0471* + ID_VENDOR_FROM_DATABASE=TiVo Corp + +bluetooth:v0472* + ID_VENDOR_FROM_DATABASE=Control-J Pty Ltd + +bluetooth:v0473* + ID_VENDOR_FROM_DATABASE=Steelcase, Inc. + +bluetooth:v0474* + ID_VENDOR_FROM_DATABASE=iApartment co., ltd. + +bluetooth:v0475* + ID_VENDOR_FROM_DATABASE=Icom inc. + +bluetooth:v0476* + ID_VENDOR_FROM_DATABASE=Oxstren Wearable Technologies Private Limited + +bluetooth:v0477* + ID_VENDOR_FROM_DATABASE=Blue Spark Technologies + +bluetooth:v0478* + ID_VENDOR_FROM_DATABASE=FarSite Communications Limited + +bluetooth:v0479* + ID_VENDOR_FROM_DATABASE=mywerk system GmbH + +bluetooth:v047A* + ID_VENDOR_FROM_DATABASE=Sinosun Technology Co., Ltd. + +bluetooth:v047B* + ID_VENDOR_FROM_DATABASE=MIYOSHI ELECTRONICS CORPORATION + +bluetooth:v047C* + ID_VENDOR_FROM_DATABASE=POWERMAT LTD + +bluetooth:v047D* + ID_VENDOR_FROM_DATABASE=Occly LLC + +bluetooth:v047E* + ID_VENDOR_FROM_DATABASE=OurHub Dev IvS + +bluetooth:v047F* + ID_VENDOR_FROM_DATABASE=Pro-Mark, Inc. + +bluetooth:v0480* + ID_VENDOR_FROM_DATABASE=Dynometrics Inc. + +bluetooth:v0481* + ID_VENDOR_FROM_DATABASE=Quintrax Limited + +bluetooth:v0482* + ID_VENDOR_FROM_DATABASE=POS Tuning Udo Vosshenrich GmbH & Co. KG + +bluetooth:v0483* + ID_VENDOR_FROM_DATABASE=Multi Care Systems B.V. + +bluetooth:v0484* + ID_VENDOR_FROM_DATABASE=Revol Technologies Inc + +bluetooth:v0485* + ID_VENDOR_FROM_DATABASE=SKIDATA AG + +bluetooth:v0486* + ID_VENDOR_FROM_DATABASE=DEV TECNOLOGIA INDUSTRIA, COMERCIO E MANUTENCAO DE EQUIPAMENTOS LTDA. - ME + +bluetooth:v0487* + ID_VENDOR_FROM_DATABASE=Centrica Connected Home + +bluetooth:v0488* + ID_VENDOR_FROM_DATABASE=Automotive Data Solutions Inc + +bluetooth:v0489* + ID_VENDOR_FROM_DATABASE=Igarashi Engineering + +bluetooth:v048A* + ID_VENDOR_FROM_DATABASE=Taelek Oy + +bluetooth:v048B* + ID_VENDOR_FROM_DATABASE=CP Electronics Limited + +bluetooth:v048C* + ID_VENDOR_FROM_DATABASE=Vectronix AG + +bluetooth:v048D* + ID_VENDOR_FROM_DATABASE=S-Labs Sp. z o.o. + +bluetooth:v048E* + ID_VENDOR_FROM_DATABASE=Companion Medical, Inc. + +bluetooth:v048F* + ID_VENDOR_FROM_DATABASE=BlueKitchen GmbH + +bluetooth:v0490* + ID_VENDOR_FROM_DATABASE=Matting AB + +bluetooth:v0491* + ID_VENDOR_FROM_DATABASE=SOREX - Wireless Solutions GmbH + +bluetooth:v0492* + ID_VENDOR_FROM_DATABASE=ADC Technology, Inc. + +bluetooth:v0493* + ID_VENDOR_FROM_DATABASE=Lynxemi Pte Ltd + +bluetooth:v0494* + ID_VENDOR_FROM_DATABASE=SENNHEISER electronic GmbH & Co. KG + +bluetooth:v0495* + ID_VENDOR_FROM_DATABASE=LMT Mercer Group, Inc + +bluetooth:v0496* + ID_VENDOR_FROM_DATABASE=Polymorphic Labs LLC + +bluetooth:v0497* + ID_VENDOR_FROM_DATABASE=Cochlear Limited + +bluetooth:v0498* + ID_VENDOR_FROM_DATABASE=METER Group, Inc. USA + +bluetooth:v0499* + ID_VENDOR_FROM_DATABASE=Ruuvi Innovations Ltd. + +bluetooth:v049A* + ID_VENDOR_FROM_DATABASE=Situne AS + +bluetooth:v049B* + ID_VENDOR_FROM_DATABASE=nVisti, LLC + +bluetooth:v049C* + ID_VENDOR_FROM_DATABASE=DyOcean + +bluetooth:v049D* + ID_VENDOR_FROM_DATABASE=Uhlmann & Zacher GmbH + +bluetooth:v049E* + ID_VENDOR_FROM_DATABASE=AND!XOR LLC + +bluetooth:v049F* + ID_VENDOR_FROM_DATABASE=tictote AB + +bluetooth:v04A0* + ID_VENDOR_FROM_DATABASE=Vypin, LLC + +bluetooth:v04A1* + ID_VENDOR_FROM_DATABASE=PNI Sensor Corporation + +bluetooth:v04A2* + ID_VENDOR_FROM_DATABASE=ovrEngineered, LLC + +bluetooth:v04A3* + ID_VENDOR_FROM_DATABASE=GT-tronics HK Ltd + +bluetooth:v04A4* + ID_VENDOR_FROM_DATABASE=Herbert Waldmann GmbH & Co. KG + +bluetooth:v04A5* + ID_VENDOR_FROM_DATABASE=Guangzhou FiiO Electronics Technology Co.,Ltd + +bluetooth:v04A6* + ID_VENDOR_FROM_DATABASE=Vinetech Co., Ltd + +bluetooth:v04A7* + ID_VENDOR_FROM_DATABASE=Dallas Logic Corporation + +bluetooth:v04A8* + ID_VENDOR_FROM_DATABASE=BioTex, Inc. + +bluetooth:v04A9* + ID_VENDOR_FROM_DATABASE=DISCOVERY SOUND TECHNOLOGY, LLC + +bluetooth:v04AA* + ID_VENDOR_FROM_DATABASE=LINKIO SAS + +bluetooth:v04AB* + ID_VENDOR_FROM_DATABASE=Harbortronics, Inc. + +bluetooth:v04AC* + ID_VENDOR_FROM_DATABASE=Undagrid B.V. + +bluetooth:v04AD* + ID_VENDOR_FROM_DATABASE=Shure Inc + +bluetooth:v04AE* + ID_VENDOR_FROM_DATABASE=ERM Electronic Systems LTD + +bluetooth:v04AF* + ID_VENDOR_FROM_DATABASE=BIOROWER Handelsagentur GmbH + +bluetooth:v04B0* + ID_VENDOR_FROM_DATABASE=Weba Sport und Med. Artikel GmbH + +bluetooth:v04B1* + ID_VENDOR_FROM_DATABASE=Kartographers Technologies Pvt. Ltd. + +bluetooth:v04B2* + ID_VENDOR_FROM_DATABASE=The Shadow on the Moon + +bluetooth:v04B3* + ID_VENDOR_FROM_DATABASE=mobike (Hong Kong) Limited + +bluetooth:v04B4* + ID_VENDOR_FROM_DATABASE=Inuheat Group AB + +bluetooth:v04B5* + ID_VENDOR_FROM_DATABASE=Swiftronix AB + +bluetooth:v04B6* + ID_VENDOR_FROM_DATABASE=Diagnoptics Technologies + +bluetooth:v04B7* + ID_VENDOR_FROM_DATABASE=Analog Devices, Inc. + +bluetooth:v04B8* + ID_VENDOR_FROM_DATABASE=Soraa Inc. + +bluetooth:v04B9* + ID_VENDOR_FROM_DATABASE=CSR Building Products Limited + +bluetooth:v04BA* + ID_VENDOR_FROM_DATABASE=Crestron Electronics, Inc. + +bluetooth:v04BB* + ID_VENDOR_FROM_DATABASE=Neatebox Ltd + +bluetooth:v04BC* + ID_VENDOR_FROM_DATABASE=Draegerwerk AG & Co. KGaA + +bluetooth:v04BD* + ID_VENDOR_FROM_DATABASE=AlbynMedical + +bluetooth:v04BE* + ID_VENDOR_FROM_DATABASE=Averos FZCO + +bluetooth:v04BF* + ID_VENDOR_FROM_DATABASE=VIT Initiative, LLC + +bluetooth:v04C0* + ID_VENDOR_FROM_DATABASE=Statsports International + +bluetooth:v04C1* + ID_VENDOR_FROM_DATABASE=Sospitas, s.r.o. + +bluetooth:v04C2* + ID_VENDOR_FROM_DATABASE=Dmet Products Corp. + +bluetooth:v04C3* + ID_VENDOR_FROM_DATABASE=Mantracourt Electronics Limited + +bluetooth:v04C4* + ID_VENDOR_FROM_DATABASE=TeAM Hutchins AB + +bluetooth:v04C5* + ID_VENDOR_FROM_DATABASE=Seibert Williams Glass, LLC + +bluetooth:v04C6* + ID_VENDOR_FROM_DATABASE=Insta GmbH + +bluetooth:v04C7* + ID_VENDOR_FROM_DATABASE=Svantek Sp. z o.o. + +bluetooth:v04C8* + ID_VENDOR_FROM_DATABASE=Shanghai Flyco Electrical Appliance Co., Ltd. + +bluetooth:v04C9* + ID_VENDOR_FROM_DATABASE=Thornwave Labs Inc + +bluetooth:v04CA* + ID_VENDOR_FROM_DATABASE=Steiner-Optik GmbH + +bluetooth:v04CB* + ID_VENDOR_FROM_DATABASE=Novo Nordisk A/S + +bluetooth:v04CC* + ID_VENDOR_FROM_DATABASE=Enflux Inc. + +bluetooth:v04CD* + ID_VENDOR_FROM_DATABASE=Safetech Products LLC + +bluetooth:v04CE* + ID_VENDOR_FROM_DATABASE=GOOOLED S.R.L. + +bluetooth:v04CF* + ID_VENDOR_FROM_DATABASE=DOM Sicherheitstechnik GmbH & Co. KG + +bluetooth:v04D0* + ID_VENDOR_FROM_DATABASE=Olympus Corporation + +bluetooth:v04D1* + ID_VENDOR_FROM_DATABASE=KTS GmbH + +bluetooth:v04D2* + ID_VENDOR_FROM_DATABASE=Anloq Technologies Inc. + +bluetooth:v04D3* + ID_VENDOR_FROM_DATABASE=Queercon, Inc + +bluetooth:v04D4* + ID_VENDOR_FROM_DATABASE=5th Element Ltd + +bluetooth:v04D5* + ID_VENDOR_FROM_DATABASE=Gooee Limited + +bluetooth:v04D6* + ID_VENDOR_FROM_DATABASE=LUGLOC LLC + +bluetooth:v04D7* + ID_VENDOR_FROM_DATABASE=Blincam, Inc. + +bluetooth:v04D8* + ID_VENDOR_FROM_DATABASE=FUJIFILM Corporation + +bluetooth:v04D9* + ID_VENDOR_FROM_DATABASE=RandMcNally + +bluetooth:v04DA* + ID_VENDOR_FROM_DATABASE=Franceschi Marina snc + +bluetooth:v04DB* + ID_VENDOR_FROM_DATABASE=Engineered Audio, LLC. + +bluetooth:v04DC* + ID_VENDOR_FROM_DATABASE=IOTTIVE (OPC) PRIVATE LIMITED + +bluetooth:v04DD* + ID_VENDOR_FROM_DATABASE=4MOD Technology + +bluetooth:v04DE* + ID_VENDOR_FROM_DATABASE=Lutron Electronics Co., Inc. + +bluetooth:v04DF* + ID_VENDOR_FROM_DATABASE=Emerson + +bluetooth:v04E0* + ID_VENDOR_FROM_DATABASE=Guardtec, Inc. + +bluetooth:v04E1* + ID_VENDOR_FROM_DATABASE=REACTEC LIMITED + +bluetooth:v04E2* + ID_VENDOR_FROM_DATABASE=EllieGrid + +bluetooth:v04E3* + ID_VENDOR_FROM_DATABASE=Under Armour + +bluetooth:v04E4* + ID_VENDOR_FROM_DATABASE=Woodenshark + +bluetooth:v04E5* + ID_VENDOR_FROM_DATABASE=Avack Oy + +bluetooth:v04E6* + ID_VENDOR_FROM_DATABASE=Smart Solution Technology, Inc. + +bluetooth:v04E7* + ID_VENDOR_FROM_DATABASE=REHABTRONICS INC. + +bluetooth:v04E8* + ID_VENDOR_FROM_DATABASE=STABILO International + +bluetooth:v04E9* + ID_VENDOR_FROM_DATABASE=Busch Jaeger Elektro GmbH + +bluetooth:v04EA* + ID_VENDOR_FROM_DATABASE=Pacific Bioscience Laboratories, Inc + +bluetooth:v04EB* + ID_VENDOR_FROM_DATABASE=Bird Home Automation GmbH + +bluetooth:v04EC* + ID_VENDOR_FROM_DATABASE=Motorola Solutions + +bluetooth:v04ED* + ID_VENDOR_FROM_DATABASE=R9 Technology, Inc. + +bluetooth:v04EE* + ID_VENDOR_FROM_DATABASE=Auxivia + +bluetooth:v04EF* + ID_VENDOR_FROM_DATABASE=DaisyWorks, Inc + +bluetooth:v04F0* + ID_VENDOR_FROM_DATABASE=Kosi Limited + +bluetooth:v04F1* + ID_VENDOR_FROM_DATABASE=Theben AG + +bluetooth:v04F2* + ID_VENDOR_FROM_DATABASE=InDreamer Techsol Private Limited + +bluetooth:v04F3* + ID_VENDOR_FROM_DATABASE=Cerevast Medical + +bluetooth:v04F4* + ID_VENDOR_FROM_DATABASE=ZanCompute Inc. + +bluetooth:v04F5* + ID_VENDOR_FROM_DATABASE=Pirelli Tyre S.P.A. + +bluetooth:v04F6* + ID_VENDOR_FROM_DATABASE=McLear Limited + +bluetooth:v04F7* + ID_VENDOR_FROM_DATABASE=Shenzhen Huiding Technology Co.,Ltd. + +bluetooth:v04F8* + ID_VENDOR_FROM_DATABASE=Convergence Systems Limited + +bluetooth:v04F9* + ID_VENDOR_FROM_DATABASE=Interactio + +bluetooth:v04FA* + ID_VENDOR_FROM_DATABASE=Androtec GmbH + +bluetooth:v04FB* + ID_VENDOR_FROM_DATABASE=Benchmark Drives GmbH & Co. KG + +bluetooth:v04FC* + ID_VENDOR_FROM_DATABASE=SwingLync L. L. C. + +bluetooth:v04FD* + ID_VENDOR_FROM_DATABASE=Tapkey GmbH + +bluetooth:v04FE* + ID_VENDOR_FROM_DATABASE=Woosim Systems Inc. + +bluetooth:v04FF* + ID_VENDOR_FROM_DATABASE=Microsemi Corporation + +bluetooth:v0500* + ID_VENDOR_FROM_DATABASE=Wiliot LTD. + +bluetooth:v0501* + ID_VENDOR_FROM_DATABASE=Polaris IND + +bluetooth:v0502* + ID_VENDOR_FROM_DATABASE=Specifi-Kali LLC + +bluetooth:v0503* + ID_VENDOR_FROM_DATABASE=Locoroll, Inc + +bluetooth:v0504* + ID_VENDOR_FROM_DATABASE=PHYPLUS Inc + +bluetooth:v0505* + ID_VENDOR_FROM_DATABASE=Inplay Technologies LLC + +bluetooth:v0506* + ID_VENDOR_FROM_DATABASE=Hager + +bluetooth:v0507* + ID_VENDOR_FROM_DATABASE=Yellowcog + +bluetooth:v0508* + ID_VENDOR_FROM_DATABASE=Axes System sp. z o. o. + +bluetooth:v0509* + ID_VENDOR_FROM_DATABASE=myLIFTER Inc. + +bluetooth:v050A* + ID_VENDOR_FROM_DATABASE=Shake-on B.V. + +bluetooth:v050B* + ID_VENDOR_FROM_DATABASE=Vibrissa Inc. + +bluetooth:v050C* + ID_VENDOR_FROM_DATABASE=OSRAM GmbH + +bluetooth:v050D* + ID_VENDOR_FROM_DATABASE=TRSystems GmbH + +bluetooth:v050E* + ID_VENDOR_FROM_DATABASE=Yichip Microelectronics (Hangzhou) Co.,Ltd. + +bluetooth:v050F* + ID_VENDOR_FROM_DATABASE=Foundation Engineering LLC + +bluetooth:v0510* + ID_VENDOR_FROM_DATABASE=UNI-ELECTRONICS, INC. + +bluetooth:v0511* + ID_VENDOR_FROM_DATABASE=Brookfield Equinox LLC + +bluetooth:v0512* + ID_VENDOR_FROM_DATABASE=Soprod SA + +bluetooth:v0513* + ID_VENDOR_FROM_DATABASE=9974091 Canada Inc. + +bluetooth:v0514* + ID_VENDOR_FROM_DATABASE=FIBRO GmbH + +bluetooth:v0515* + ID_VENDOR_FROM_DATABASE=RB Controls Co., Ltd. + +bluetooth:v0516* + ID_VENDOR_FROM_DATABASE=Footmarks + +bluetooth:v0517* + ID_VENDOR_FROM_DATABASE=Amtronic Sverige AB (formerly Amcore AB) + +bluetooth:v0518* + ID_VENDOR_FROM_DATABASE=MAMORIO.inc + +bluetooth:v0519* + ID_VENDOR_FROM_DATABASE=Tyto Life LLC + +bluetooth:v051A* + ID_VENDOR_FROM_DATABASE=Leica Camera AG + +bluetooth:v051B* + ID_VENDOR_FROM_DATABASE=Angee Technologies Ltd. + +bluetooth:v051C* + ID_VENDOR_FROM_DATABASE=EDPS + +bluetooth:v051D* + ID_VENDOR_FROM_DATABASE=OFF Line Co., Ltd. + +bluetooth:v051E* + ID_VENDOR_FROM_DATABASE=Detect Blue Limited + +bluetooth:v051F* + ID_VENDOR_FROM_DATABASE=Setec Pty Ltd + +bluetooth:v0520* + ID_VENDOR_FROM_DATABASE=Target Corporation + +bluetooth:v0521* + ID_VENDOR_FROM_DATABASE=IAI Corporation + +bluetooth:v0522* + ID_VENDOR_FROM_DATABASE=NS Tech, Inc. + +bluetooth:v0523* + ID_VENDOR_FROM_DATABASE=MTG Co., Ltd. + +bluetooth:v0524* + ID_VENDOR_FROM_DATABASE=Hangzhou iMagic Technology Co., Ltd + +bluetooth:v0525* + ID_VENDOR_FROM_DATABASE=HONGKONG NANO IC TECHNOLOGIES CO., LIMITED + +bluetooth:v0526* + ID_VENDOR_FROM_DATABASE=Honeywell International Inc. + +bluetooth:v0527* + ID_VENDOR_FROM_DATABASE=Albrecht JUNG + +bluetooth:v0528* + ID_VENDOR_FROM_DATABASE=Lunera Lighting Inc. + +bluetooth:v0529* + ID_VENDOR_FROM_DATABASE=Lumen UAB + +bluetooth:v052A* + ID_VENDOR_FROM_DATABASE=Keynes Controls Ltd + +bluetooth:v052B* + ID_VENDOR_FROM_DATABASE=Novartis AG + +bluetooth:v052C* + ID_VENDOR_FROM_DATABASE=Geosatis SA + +bluetooth:v052D* + ID_VENDOR_FROM_DATABASE=EXFO, Inc. + +bluetooth:v052E* + ID_VENDOR_FROM_DATABASE=LEDVANCE GmbH + +bluetooth:v052F* + ID_VENDOR_FROM_DATABASE=Center ID Corp. + +bluetooth:v0530* + ID_VENDOR_FROM_DATABASE=Adolene, Inc. + +bluetooth:v0531* + ID_VENDOR_FROM_DATABASE=D&M Holdings Inc. + +bluetooth:v0532* + ID_VENDOR_FROM_DATABASE=CRESCO Wireless, Inc. + +bluetooth:v0533* + ID_VENDOR_FROM_DATABASE=Nura Operations Pty Ltd + +bluetooth:v0534* + ID_VENDOR_FROM_DATABASE=Frontiergadget, Inc. + +bluetooth:v0535* + ID_VENDOR_FROM_DATABASE=Smart Component Technologies Limited + +bluetooth:v0536* + ID_VENDOR_FROM_DATABASE=ZTR Control Systems LLC + +bluetooth:v0537* + ID_VENDOR_FROM_DATABASE=MetaLogics Corporation + +bluetooth:v0538* + ID_VENDOR_FROM_DATABASE=Medela AG + +bluetooth:v0539* + ID_VENDOR_FROM_DATABASE=OPPLE Lighting Co., Ltd + +bluetooth:v053A* + ID_VENDOR_FROM_DATABASE=Savitech Corp., + +bluetooth:v053B* + ID_VENDOR_FROM_DATABASE=prodigy + +bluetooth:v053C* + ID_VENDOR_FROM_DATABASE=Screenovate Technologies Ltd + +bluetooth:v053D* + ID_VENDOR_FROM_DATABASE=TESA SA + +bluetooth:v053E* + ID_VENDOR_FROM_DATABASE=CLIM8 LIMITED + +bluetooth:v053F* + ID_VENDOR_FROM_DATABASE=Silergy Corp + +bluetooth:v0540* + ID_VENDOR_FROM_DATABASE=SilverPlus, Inc + +bluetooth:v0541* + ID_VENDOR_FROM_DATABASE=Sharknet srl + +bluetooth:v0542* + ID_VENDOR_FROM_DATABASE=Mist Systems, Inc. + +bluetooth:v0543* + ID_VENDOR_FROM_DATABASE=MIWA LOCK CO.,Ltd + +bluetooth:v0544* + ID_VENDOR_FROM_DATABASE=OrthoSensor, Inc. + +bluetooth:v0545* + ID_VENDOR_FROM_DATABASE=Candy Hoover Group s.r.l + +bluetooth:v0546* + ID_VENDOR_FROM_DATABASE=Apexar Technologies S.A. + +bluetooth:v0547* + ID_VENDOR_FROM_DATABASE=LOGICDATA d.o.o. + +bluetooth:v0548* + ID_VENDOR_FROM_DATABASE=Knick Elektronische Messgeraete GmbH & Co. KG + +bluetooth:v0549* + ID_VENDOR_FROM_DATABASE=Smart Technologies and Investment Limited + +bluetooth:v054A* + ID_VENDOR_FROM_DATABASE=Linough Inc. + +bluetooth:v054B* + ID_VENDOR_FROM_DATABASE=Advanced Electronic Designs, Inc. + +bluetooth:v054C* + ID_VENDOR_FROM_DATABASE=Carefree Scott Fetzer Co Inc + +bluetooth:v054D* + ID_VENDOR_FROM_DATABASE=Sensome + +bluetooth:v054E* + ID_VENDOR_FROM_DATABASE=FORTRONIK storitve d.o.o. + +bluetooth:v054F* + ID_VENDOR_FROM_DATABASE=Sinnoz + +bluetooth:v0550* + ID_VENDOR_FROM_DATABASE=Versa Networks, Inc. + +bluetooth:v0551* + ID_VENDOR_FROM_DATABASE=Sylero + +bluetooth:v0552* + ID_VENDOR_FROM_DATABASE=Avempace SARL + +bluetooth:v0553* + ID_VENDOR_FROM_DATABASE=Nintendo Co., Ltd. + +bluetooth:v0554* + ID_VENDOR_FROM_DATABASE=National Instruments + +bluetooth:v0555* + ID_VENDOR_FROM_DATABASE=KROHNE Messtechnik GmbH + +bluetooth:v0556* + ID_VENDOR_FROM_DATABASE=Otodynamics Ltd + +bluetooth:v0557* + ID_VENDOR_FROM_DATABASE=Arwin Technology Limited + +bluetooth:v0558* + ID_VENDOR_FROM_DATABASE=benegear, inc. + +bluetooth:v0559* + ID_VENDOR_FROM_DATABASE=Newcon Optik + +bluetooth:v055A* + ID_VENDOR_FROM_DATABASE=CANDY HOUSE, Inc. + +bluetooth:v055B* + ID_VENDOR_FROM_DATABASE=FRANKLIN TECHNOLOGY INC + +bluetooth:v055C* + ID_VENDOR_FROM_DATABASE=Lely + +bluetooth:v055D* + ID_VENDOR_FROM_DATABASE=Valve Corporation + +bluetooth:v055E* + ID_VENDOR_FROM_DATABASE=Hekatron Vertriebs GmbH + +bluetooth:v055F* + ID_VENDOR_FROM_DATABASE=PROTECH S.A.S. DI GIRARDI ANDREA & C. + +bluetooth:v0560* + ID_VENDOR_FROM_DATABASE=Sarita CareTech APS (formerly Sarita CareTech IVS) + +bluetooth:v0561* + ID_VENDOR_FROM_DATABASE=Finder S.p.A. + +bluetooth:v0562* + ID_VENDOR_FROM_DATABASE=Thalmic Labs Inc. + +bluetooth:v0563* + ID_VENDOR_FROM_DATABASE=Steinel Vertrieb GmbH + +bluetooth:v0564* + ID_VENDOR_FROM_DATABASE=Beghelli Spa + +bluetooth:v0565* + ID_VENDOR_FROM_DATABASE=Beijing Smartspace Technologies Inc. + +bluetooth:v0566* + ID_VENDOR_FROM_DATABASE=CORE TRANSPORT TECHNOLOGIES NZ LIMITED + +bluetooth:v0567* + ID_VENDOR_FROM_DATABASE=Xiamen Everesports Goods Co., Ltd + +bluetooth:v0568* + ID_VENDOR_FROM_DATABASE=Bodyport Inc. + +bluetooth:v0569* + ID_VENDOR_FROM_DATABASE=Audionics System, INC. + +bluetooth:v056A* + ID_VENDOR_FROM_DATABASE=Flipnavi Co.,Ltd. + +bluetooth:v056B* + ID_VENDOR_FROM_DATABASE=Rion Co., Ltd. + +bluetooth:v056C* + ID_VENDOR_FROM_DATABASE=Long Range Systems, LLC + +bluetooth:v056D* + ID_VENDOR_FROM_DATABASE=Redmond Industrial Group LLC + +bluetooth:v056E* + ID_VENDOR_FROM_DATABASE=VIZPIN INC. + +bluetooth:v056F* + ID_VENDOR_FROM_DATABASE=BikeFinder AS + +bluetooth:v0570* + ID_VENDOR_FROM_DATABASE=Consumer Sleep Solutions LLC + +bluetooth:v0571* + ID_VENDOR_FROM_DATABASE=PSIKICK, INC. + +bluetooth:v0572* + ID_VENDOR_FROM_DATABASE=AntTail.com + +bluetooth:v0573* + ID_VENDOR_FROM_DATABASE=Lighting Science Group Corp. + +bluetooth:v0574* + ID_VENDOR_FROM_DATABASE=AFFORDABLE ELECTRONICS INC + +bluetooth:v0575* + ID_VENDOR_FROM_DATABASE=Integral Memroy Plc + +bluetooth:v0576* + ID_VENDOR_FROM_DATABASE=Globalstar, Inc. + +bluetooth:v0577* + ID_VENDOR_FROM_DATABASE=True Wearables, Inc. + +bluetooth:v0578* + ID_VENDOR_FROM_DATABASE=Wellington Drive Technologies Ltd + +bluetooth:v0579* + ID_VENDOR_FROM_DATABASE=Ensemble Tech Private Limited + +bluetooth:v057A* + ID_VENDOR_FROM_DATABASE=OMNI Remotes + +bluetooth:v057B* + ID_VENDOR_FROM_DATABASE=Duracell U.S. Operations Inc. + +bluetooth:v057C* + ID_VENDOR_FROM_DATABASE=Toor Technologies LLC + +bluetooth:v057D* + ID_VENDOR_FROM_DATABASE=Instinct Performance + +bluetooth:v057E* + ID_VENDOR_FROM_DATABASE=Beco, Inc + +bluetooth:v057F* + ID_VENDOR_FROM_DATABASE=Scuf Gaming International, LLC + +bluetooth:v0580* + ID_VENDOR_FROM_DATABASE=ARANZ Medical Limited + +bluetooth:v0581* + ID_VENDOR_FROM_DATABASE=LYS TECHNOLOGIES LTD + +bluetooth:v0582* + ID_VENDOR_FROM_DATABASE=Breakwall Analytics, LLC + +bluetooth:v0583* + ID_VENDOR_FROM_DATABASE=Code Blue Communications + +bluetooth:v0584* + ID_VENDOR_FROM_DATABASE=Gira Giersiepen GmbH & Co. KG + +bluetooth:v0585* + ID_VENDOR_FROM_DATABASE=Hearing Lab Technology + +bluetooth:v0586* + ID_VENDOR_FROM_DATABASE=LEGRAND + +bluetooth:v0587* + ID_VENDOR_FROM_DATABASE=Derichs GmbH + +bluetooth:v0588* + ID_VENDOR_FROM_DATABASE=ALT-TEKNIK LLC + +bluetooth:v0589* + ID_VENDOR_FROM_DATABASE=Star Technologies + +bluetooth:v058A* + ID_VENDOR_FROM_DATABASE=START TODAY CO.,LTD. + +bluetooth:v058B* + ID_VENDOR_FROM_DATABASE=Maxim Integrated Products + +bluetooth:v058C* + ID_VENDOR_FROM_DATABASE=MERCK Kommanditgesellschaft auf Aktien + +bluetooth:v058D* + ID_VENDOR_FROM_DATABASE=Jungheinrich Aktiengesellschaft + +bluetooth:v058E* + ID_VENDOR_FROM_DATABASE=Oculus VR, LLC + +bluetooth:v058F* + ID_VENDOR_FROM_DATABASE=HENDON SEMICONDUCTORS PTY LTD + +bluetooth:v0590* + ID_VENDOR_FROM_DATABASE=Pur3 Ltd + +bluetooth:v0591* + ID_VENDOR_FROM_DATABASE=Viasat Group S.p.A. + +bluetooth:v0592* + ID_VENDOR_FROM_DATABASE=IZITHERM + +bluetooth:v0593* + ID_VENDOR_FROM_DATABASE=Spaulding Clinical Research + +bluetooth:v0594* + ID_VENDOR_FROM_DATABASE=Kohler Company + +bluetooth:v0595* + ID_VENDOR_FROM_DATABASE=Inor Process AB + +bluetooth:v0596* + ID_VENDOR_FROM_DATABASE=My Smart Blinds + +bluetooth:v0597* + ID_VENDOR_FROM_DATABASE=RadioPulse Inc + +bluetooth:v0598* + ID_VENDOR_FROM_DATABASE=rapitag GmbH + +bluetooth:v0599* + ID_VENDOR_FROM_DATABASE=Lazlo326, LLC. + +bluetooth:v059A* + ID_VENDOR_FROM_DATABASE=Teledyne Lecroy, Inc. + +bluetooth:v059B* + ID_VENDOR_FROM_DATABASE=Dataflow Systems Limited + +bluetooth:v059C* + ID_VENDOR_FROM_DATABASE=Macrogiga Electronics + +bluetooth:v059D* + ID_VENDOR_FROM_DATABASE=Tandem Diabetes Care + +bluetooth:v059E* + ID_VENDOR_FROM_DATABASE=Polycom, Inc. + +bluetooth:v059F* + ID_VENDOR_FROM_DATABASE=Fisher & Paykel Healthcare + +bluetooth:v05A0* + ID_VENDOR_FROM_DATABASE=RCP Software Oy + +bluetooth:v05A1* + ID_VENDOR_FROM_DATABASE=Shanghai Xiaoyi Technology Co.,Ltd. + +bluetooth:v05A2* + ID_VENDOR_FROM_DATABASE=ADHERIUM(NZ) LIMITED + +bluetooth:v05A3* + ID_VENDOR_FROM_DATABASE=Axiomware Systems Incorporated + +bluetooth:v05A4* + ID_VENDOR_FROM_DATABASE=O. E. M. Controls, Inc. + +bluetooth:v05A5* + ID_VENDOR_FROM_DATABASE=Kiiroo BV + +bluetooth:v05A6* + ID_VENDOR_FROM_DATABASE=Telecon Mobile Limited + +bluetooth:v05A7* + ID_VENDOR_FROM_DATABASE=Sonos Inc + +bluetooth:v05A8* + ID_VENDOR_FROM_DATABASE=Tom Allebrandi Consulting + +bluetooth:v05A9* + ID_VENDOR_FROM_DATABASE=Monidor + +bluetooth:v05AA* + ID_VENDOR_FROM_DATABASE=Tramex Limited + +bluetooth:v05AB* + ID_VENDOR_FROM_DATABASE=Nofence AS + +bluetooth:v05AC* + ID_VENDOR_FROM_DATABASE=GoerTek Dynaudio Co., Ltd. + +bluetooth:v05AD* + ID_VENDOR_FROM_DATABASE=INIA + +bluetooth:v05AE* + ID_VENDOR_FROM_DATABASE=CARMATE MFG.CO.,LTD + +bluetooth:v05AF* + ID_VENDOR_FROM_DATABASE=ONvocal + +bluetooth:v05B0* + ID_VENDOR_FROM_DATABASE=NewTec GmbH + +bluetooth:v05B1* + ID_VENDOR_FROM_DATABASE=Medallion Instrumentation Systems + +bluetooth:v05B2* + ID_VENDOR_FROM_DATABASE=CAREL INDUSTRIES S.P.A. + +bluetooth:v05B3* + ID_VENDOR_FROM_DATABASE=Parabit Systems, Inc. + +bluetooth:v05B4* + ID_VENDOR_FROM_DATABASE=White Horse Scientific ltd + +bluetooth:v05B5* + ID_VENDOR_FROM_DATABASE=verisilicon + +bluetooth:v05B6* + ID_VENDOR_FROM_DATABASE=Elecs Industry Co.,Ltd. + +bluetooth:v05B7* + ID_VENDOR_FROM_DATABASE=Beijing Pinecone Electronics Co.,Ltd. + +bluetooth:v05B8* + ID_VENDOR_FROM_DATABASE=Ambystoma Labs Inc. + +bluetooth:v05B9* + ID_VENDOR_FROM_DATABASE=Suzhou Pairlink Network Technology + +bluetooth:v05BA* + ID_VENDOR_FROM_DATABASE=igloohome + +bluetooth:v05BB* + ID_VENDOR_FROM_DATABASE=Oxford Metrics plc + +bluetooth:v05BC* + ID_VENDOR_FROM_DATABASE=Leviton Mfg. Co., Inc. + +bluetooth:v05BD* + ID_VENDOR_FROM_DATABASE=ULC Robotics Inc. + +bluetooth:v05BE* + ID_VENDOR_FROM_DATABASE=RFID Global by Softwork SrL + +bluetooth:v05BF* + ID_VENDOR_FROM_DATABASE=Real-World-Systems Corporation + +bluetooth:v05C0* + ID_VENDOR_FROM_DATABASE=Nalu Medical, Inc. + +bluetooth:v05C1* + ID_VENDOR_FROM_DATABASE=P.I.Engineering + +bluetooth:v05C2* + ID_VENDOR_FROM_DATABASE=Grote Industries + +bluetooth:v05C3* + ID_VENDOR_FROM_DATABASE=Runtime, Inc. + +bluetooth:v05C4* + ID_VENDOR_FROM_DATABASE=Codecoup sp. z o.o. sp. k. + +bluetooth:v05C5* + ID_VENDOR_FROM_DATABASE=SELVE GmbH & Co. KG + +bluetooth:v05C6* + ID_VENDOR_FROM_DATABASE=Smart Animal Training Systems, LLC + +bluetooth:v05C7* + ID_VENDOR_FROM_DATABASE=Lippert Components, INC + +bluetooth:v05C8* + ID_VENDOR_FROM_DATABASE=SOMFY SAS + +bluetooth:v05C9* + ID_VENDOR_FROM_DATABASE=TBS Electronics B.V. + +bluetooth:v05CA* + ID_VENDOR_FROM_DATABASE=MHL Custom Inc + +bluetooth:v05CB* + ID_VENDOR_FROM_DATABASE=LucentWear LLC + +bluetooth:v05CC* + ID_VENDOR_FROM_DATABASE=WATTS ELECTRONICS + +bluetooth:v05CD* + ID_VENDOR_FROM_DATABASE=RJ Brands LLC + +bluetooth:v05CE* + ID_VENDOR_FROM_DATABASE=V-ZUG Ltd + +bluetooth:v05CF* + ID_VENDOR_FROM_DATABASE=Biowatch SA + +bluetooth:v05D0* + ID_VENDOR_FROM_DATABASE=Anova Applied Electronics + +bluetooth:v05D1* + ID_VENDOR_FROM_DATABASE=Lindab AB + +bluetooth:v05D2* + ID_VENDOR_FROM_DATABASE=frogblue TECHNOLOGY GmbH + +bluetooth:v05D3* + ID_VENDOR_FROM_DATABASE=Acurable Limited + +bluetooth:v05D4* + ID_VENDOR_FROM_DATABASE=LAMPLIGHT Co., Ltd. + +bluetooth:v05D5* + ID_VENDOR_FROM_DATABASE=TEGAM, Inc. + +bluetooth:v05D6* + ID_VENDOR_FROM_DATABASE=Zhuhai Jieli technology Co.,Ltd + +bluetooth:v05D7* + ID_VENDOR_FROM_DATABASE=modum.io AG + +bluetooth:v05D8* + ID_VENDOR_FROM_DATABASE=Farm Jenny LLC + +bluetooth:v05D9* + ID_VENDOR_FROM_DATABASE=Toyo Electronics Corporation + +bluetooth:v05DA* + ID_VENDOR_FROM_DATABASE=Applied Neural Research Corp + +bluetooth:v05DB* + ID_VENDOR_FROM_DATABASE=Avid Identification Systems, Inc. + +bluetooth:v05DC* + ID_VENDOR_FROM_DATABASE=Petronics Inc. + +bluetooth:v05DD* + ID_VENDOR_FROM_DATABASE=essentim GmbH + +bluetooth:v05DE* + ID_VENDOR_FROM_DATABASE=QT Medical INC. + +bluetooth:v05DF* + ID_VENDOR_FROM_DATABASE=VIRTUALCLINIC.DIRECT LIMITED + +bluetooth:v05E0* + ID_VENDOR_FROM_DATABASE=Viper Design LLC + +bluetooth:v05E1* + ID_VENDOR_FROM_DATABASE=Human, Incorporated + +bluetooth:v05E2* + ID_VENDOR_FROM_DATABASE=stAPPtronics GmbH + +bluetooth:v05E3* + ID_VENDOR_FROM_DATABASE=Elemental Machines, Inc. + +bluetooth:v05E4* + ID_VENDOR_FROM_DATABASE=Taiyo Yuden Co., Ltd + +bluetooth:v05E5* + ID_VENDOR_FROM_DATABASE=INEO ENERGY& SYSTEMS + +bluetooth:v05E6* + ID_VENDOR_FROM_DATABASE=Motion Instruments Inc. + +bluetooth:v05E7* + ID_VENDOR_FROM_DATABASE=PressurePro + +bluetooth:v05E8* + ID_VENDOR_FROM_DATABASE=COWBOY + +bluetooth:v05E9* + ID_VENDOR_FROM_DATABASE=iconmobile GmbH + +bluetooth:v05EA* + ID_VENDOR_FROM_DATABASE=ACS-Control-System GmbH + +bluetooth:v05EB* + ID_VENDOR_FROM_DATABASE=Bayerische Motoren Werke AG + +bluetooth:v05EC* + ID_VENDOR_FROM_DATABASE=Gycom Svenska AB + +bluetooth:v05ED* + ID_VENDOR_FROM_DATABASE=Fuji Xerox Co., Ltd + +bluetooth:v05EE* + ID_VENDOR_FROM_DATABASE=Glide Inc. + +bluetooth:v05EF* + ID_VENDOR_FROM_DATABASE=SIKOM AS + +bluetooth:v05F0* + ID_VENDOR_FROM_DATABASE=beken + +bluetooth:v05F1* + ID_VENDOR_FROM_DATABASE=The Linux Foundation + +bluetooth:v05F2* + ID_VENDOR_FROM_DATABASE=Try and E CO.,LTD. + +bluetooth:v05F3* + ID_VENDOR_FROM_DATABASE=SeeScan + +bluetooth:v05F4* + ID_VENDOR_FROM_DATABASE=Clearity, LLC + +bluetooth:v05F5* + ID_VENDOR_FROM_DATABASE=GS TAG + +bluetooth:v05F6* + ID_VENDOR_FROM_DATABASE=DPTechnics + +bluetooth:v05F7* + ID_VENDOR_FROM_DATABASE=TRACMO, INC. + +bluetooth:v05F8* + ID_VENDOR_FROM_DATABASE=Anki Inc. + +bluetooth:v05F9* + ID_VENDOR_FROM_DATABASE=Hagleitner Hygiene International GmbH + +bluetooth:v05FA* + ID_VENDOR_FROM_DATABASE=Konami Sports Life Co., Ltd. + +bluetooth:v05FB* + ID_VENDOR_FROM_DATABASE=Arblet Inc. + +bluetooth:v05FC* + ID_VENDOR_FROM_DATABASE=Masbando GmbH + +bluetooth:v05FD* + ID_VENDOR_FROM_DATABASE=Innoseis + +bluetooth:v05FE* + ID_VENDOR_FROM_DATABASE=Niko nv + +bluetooth:v05FF* + ID_VENDOR_FROM_DATABASE=Wellnomics Ltd + +bluetooth:v0600* + ID_VENDOR_FROM_DATABASE=iRobot Corporation + +bluetooth:v0601* + ID_VENDOR_FROM_DATABASE=Schrader Electronics + +bluetooth:v0602* + ID_VENDOR_FROM_DATABASE=Geberit International AG + +bluetooth:v0603* + ID_VENDOR_FROM_DATABASE=Fourth Evolution Inc + +bluetooth:v0604* + ID_VENDOR_FROM_DATABASE=Cell2Jack LLC + +bluetooth:v0605* + ID_VENDOR_FROM_DATABASE=FMW electronic Futterer u. Maier-Wolf OHG + +bluetooth:v0606* + ID_VENDOR_FROM_DATABASE=John Deere + +bluetooth:v0607* + ID_VENDOR_FROM_DATABASE=Rookery Technology Ltd + +bluetooth:v0608* + ID_VENDOR_FROM_DATABASE=KeySafe-Cloud + +bluetooth:v0609* + ID_VENDOR_FROM_DATABASE=BUCHI Labortechnik AG + +bluetooth:v060A* + ID_VENDOR_FROM_DATABASE=IQAir AG + +bluetooth:v060B* + ID_VENDOR_FROM_DATABASE=Triax Technologies Inc + +bluetooth:v060C* + ID_VENDOR_FROM_DATABASE=Vuzix Corporation + +bluetooth:v060D* + ID_VENDOR_FROM_DATABASE=TDK Corporation + +bluetooth:v060E* + ID_VENDOR_FROM_DATABASE=Blueair AB + +bluetooth:v060F* + ID_VENDOR_FROM_DATABASE=Signify Netherlands + +bluetooth:v0610* + ID_VENDOR_FROM_DATABASE=ADH GUARDIAN USA LLC + +bluetooth:v0611* + ID_VENDOR_FROM_DATABASE=Beurer GmbH + +bluetooth:v0612* + ID_VENDOR_FROM_DATABASE=Playfinity AS + +bluetooth:v0613* + ID_VENDOR_FROM_DATABASE=Hans Dinslage GmbH + +bluetooth:v0614* + ID_VENDOR_FROM_DATABASE=OnAsset Intelligence, Inc. + +bluetooth:v0615* + ID_VENDOR_FROM_DATABASE=INTER ACTION Corporation + +bluetooth:v0616* + ID_VENDOR_FROM_DATABASE=OS42 UG (haftungsbeschraenkt) + +bluetooth:v0617* + ID_VENDOR_FROM_DATABASE=WIZCONNECTED COMPANY LIMITED + +bluetooth:v0618* + ID_VENDOR_FROM_DATABASE=Audio-Technica Corporation + +bluetooth:v0619* + ID_VENDOR_FROM_DATABASE=Six Guys Labs, s.r.o. + +bluetooth:v061A* + ID_VENDOR_FROM_DATABASE=R.W. Beckett Corporation + +bluetooth:v061B* + ID_VENDOR_FROM_DATABASE=silex technology, inc. + +bluetooth:v061C* + ID_VENDOR_FROM_DATABASE=Univations Limited + +bluetooth:v061D* + ID_VENDOR_FROM_DATABASE=SENS Innovation ApS + +bluetooth:v061E* + ID_VENDOR_FROM_DATABASE=Diamond Kinetics, Inc. + +bluetooth:v061F* + ID_VENDOR_FROM_DATABASE=Phrame Inc. + +bluetooth:v0620* + ID_VENDOR_FROM_DATABASE=Forciot Oy + +bluetooth:v0621* + ID_VENDOR_FROM_DATABASE=Noordung d.o.o. + +bluetooth:v0622* + ID_VENDOR_FROM_DATABASE=Beam Labs, LLC + +bluetooth:v0623* + ID_VENDOR_FROM_DATABASE=Philadelphia Scientific (U.K.) Limited + +bluetooth:v0624* + ID_VENDOR_FROM_DATABASE=Biovotion AG + +bluetooth:v0625* + ID_VENDOR_FROM_DATABASE=Square Panda, Inc. + +bluetooth:v0626* + ID_VENDOR_FROM_DATABASE=Amplifico + +bluetooth:v0627* + ID_VENDOR_FROM_DATABASE=WEG S.A. + +bluetooth:v0628* + ID_VENDOR_FROM_DATABASE=Ensto Oy + +bluetooth:v0629* + ID_VENDOR_FROM_DATABASE=PHONEPE PVT LTD + +bluetooth:v062A* + ID_VENDOR_FROM_DATABASE=Lunatico Astronomia SL + +bluetooth:v062B* + ID_VENDOR_FROM_DATABASE=MinebeaMitsumi Inc. + +bluetooth:v062C* + ID_VENDOR_FROM_DATABASE=ASPion GmbH + +bluetooth:v062D* + ID_VENDOR_FROM_DATABASE=Vossloh-Schwabe Deutschland GmbH + +bluetooth:v062E* + ID_VENDOR_FROM_DATABASE=Procept + +bluetooth:v062F* + ID_VENDOR_FROM_DATABASE=ONKYO Corporation + +bluetooth:v0630* + ID_VENDOR_FROM_DATABASE=Asthrea D.O.O. + +bluetooth:v0631* + ID_VENDOR_FROM_DATABASE=Fortiori Design LLC + +bluetooth:v0632* + ID_VENDOR_FROM_DATABASE=Hugo Muller GmbH & Co KG + +bluetooth:v0633* + ID_VENDOR_FROM_DATABASE=Wangi Lai PLT + +bluetooth:v0634* + ID_VENDOR_FROM_DATABASE=Fanstel Corp + +bluetooth:v0635* + ID_VENDOR_FROM_DATABASE=Crookwood + +bluetooth:v0636* + ID_VENDOR_FROM_DATABASE=ELECTRONICA INTEGRAL DE SONIDO S.A. + +bluetooth:v0637* + ID_VENDOR_FROM_DATABASE=GiP Innovation Tools GmbH + +bluetooth:v0638* + ID_VENDOR_FROM_DATABASE=LX SOLUTIONS PTY LIMITED + +bluetooth:v0639* + ID_VENDOR_FROM_DATABASE=Shenzhen Minew Technologies Co., Ltd. + +bluetooth:v063A* + ID_VENDOR_FROM_DATABASE=Prolojik Limited + +bluetooth:v063B* + ID_VENDOR_FROM_DATABASE=Kromek Group Plc + +bluetooth:v063C* + ID_VENDOR_FROM_DATABASE=Contec Medical Systems Co., Ltd. + +bluetooth:v063D* + ID_VENDOR_FROM_DATABASE=Xradio Technology Co.,Ltd. + +bluetooth:v063E* + ID_VENDOR_FROM_DATABASE=The Indoor Lab, LLC + +bluetooth:v063F* + ID_VENDOR_FROM_DATABASE=LDL TECHNOLOGY + +bluetooth:v0640* + ID_VENDOR_FROM_DATABASE=Parkifi + +bluetooth:v0641* + ID_VENDOR_FROM_DATABASE=Revenue Collection Systems FRANCE SAS + +bluetooth:v0642* + ID_VENDOR_FROM_DATABASE=Bluetrum Technology Co.,Ltd + +bluetooth:v0643* + ID_VENDOR_FROM_DATABASE=makita corporation + +bluetooth:v0644* + ID_VENDOR_FROM_DATABASE=Apogee Instruments + +bluetooth:v0645* + ID_VENDOR_FROM_DATABASE=BM3 + +bluetooth:v0646* + ID_VENDOR_FROM_DATABASE=SGV Group Holding GmbH & Co. KG + +bluetooth:v0647* + ID_VENDOR_FROM_DATABASE=MED-EL + +bluetooth:v0648* + ID_VENDOR_FROM_DATABASE=Ultune Technologies + +bluetooth:v0649* + ID_VENDOR_FROM_DATABASE=Ryeex Technology Co.,Ltd. + +bluetooth:v064A* + ID_VENDOR_FROM_DATABASE=Open Research Institute, Inc. + +bluetooth:v064B* + ID_VENDOR_FROM_DATABASE=Scale-Tec, Ltd + +bluetooth:v064C* + ID_VENDOR_FROM_DATABASE=Zumtobel Group AG + +bluetooth:v064D* + ID_VENDOR_FROM_DATABASE=iLOQ Oy + +bluetooth:v064E* + ID_VENDOR_FROM_DATABASE=KRUXWorks Technologies Private Limited + +bluetooth:v064F* + ID_VENDOR_FROM_DATABASE=Digital Matter Pty Ltd + +bluetooth:v0650* + ID_VENDOR_FROM_DATABASE=Coravin, Inc. + +bluetooth:v0651* + ID_VENDOR_FROM_DATABASE=Stasis Labs, Inc. + +bluetooth:v0652* + ID_VENDOR_FROM_DATABASE=ITZ Innovations- und Technologiezentrum GmbH + +bluetooth:v0653* + ID_VENDOR_FROM_DATABASE=Meggitt SA + +bluetooth:v0654* + ID_VENDOR_FROM_DATABASE=Ledlenser GmbH & Co. KG + +bluetooth:v0655* + ID_VENDOR_FROM_DATABASE=Renishaw PLC + +bluetooth:v0656* + ID_VENDOR_FROM_DATABASE=ZhuHai AdvanPro Technology Company Limited + +bluetooth:v0657* + ID_VENDOR_FROM_DATABASE=Meshtronix Limited + +bluetooth:v0658* + ID_VENDOR_FROM_DATABASE=Payex Norge AS + +bluetooth:v0659* + ID_VENDOR_FROM_DATABASE=UnSeen Technologies Oy + +bluetooth:v065A* + ID_VENDOR_FROM_DATABASE=Zound Industries International AB + +bluetooth:v065B* + ID_VENDOR_FROM_DATABASE=Sesam Solutions BV + +bluetooth:v065C* + ID_VENDOR_FROM_DATABASE=PixArt Imaging Inc. + +bluetooth:v065D* + ID_VENDOR_FROM_DATABASE=Panduit Corp. + +bluetooth:v065E* + ID_VENDOR_FROM_DATABASE=Alo AB + +bluetooth:v065F* + ID_VENDOR_FROM_DATABASE=Ricoh Company Ltd + +bluetooth:v0660* + ID_VENDOR_FROM_DATABASE=RTC Industries, Inc. + +bluetooth:v0661* + ID_VENDOR_FROM_DATABASE=Mode Lighting Limited + +bluetooth:v0662* + ID_VENDOR_FROM_DATABASE=Particle Industries, Inc. + +bluetooth:v0663* + ID_VENDOR_FROM_DATABASE=Advanced Telemetry Systems, Inc. + +bluetooth:v0664* + ID_VENDOR_FROM_DATABASE=RHA TECHNOLOGIES LTD + +bluetooth:v0665* + ID_VENDOR_FROM_DATABASE=Pure International Limited + +bluetooth:v0666* + ID_VENDOR_FROM_DATABASE=WTO Werkzeug-Einrichtungen GmbH + +bluetooth:v0667* + ID_VENDOR_FROM_DATABASE=Spark Technology Labs Inc. + +bluetooth:v0668* + ID_VENDOR_FROM_DATABASE=Bleb Technology srl + +bluetooth:v0669* + ID_VENDOR_FROM_DATABASE=Livanova USA, Inc. + +bluetooth:v066A* + ID_VENDOR_FROM_DATABASE=Brady Worldwide Inc. + +bluetooth:v066B* + ID_VENDOR_FROM_DATABASE=DewertOkin GmbH + +bluetooth:v066C* + ID_VENDOR_FROM_DATABASE=Ztove ApS + +bluetooth:v066D* + ID_VENDOR_FROM_DATABASE=Venso EcoSolutions AB + +bluetooth:v066E* + ID_VENDOR_FROM_DATABASE=Eurotronik Kranj d.o.o. + +bluetooth:v066F* + ID_VENDOR_FROM_DATABASE=Hug Technology Ltd + +bluetooth:v0670* + ID_VENDOR_FROM_DATABASE=Gema Switzerland GmbH + +bluetooth:v0671* + ID_VENDOR_FROM_DATABASE=Buzz Products Ltd. + +bluetooth:v0672* + ID_VENDOR_FROM_DATABASE=Kopi + +bluetooth:v0673* + ID_VENDOR_FROM_DATABASE=Innova Ideas Limited + +bluetooth:v0674* + ID_VENDOR_FROM_DATABASE=BeSpoon + +bluetooth:v0675* + ID_VENDOR_FROM_DATABASE=Deco Enterprises, Inc. + +bluetooth:v0676* + ID_VENDOR_FROM_DATABASE=Expai Solutions Private Limited + +bluetooth:v0677* + ID_VENDOR_FROM_DATABASE=Innovation First, Inc. + +bluetooth:v0678* + ID_VENDOR_FROM_DATABASE=SABIK Offshore GmbH + +bluetooth:v0679* + ID_VENDOR_FROM_DATABASE=4iiii Innovations Inc. + +bluetooth:v067A* + ID_VENDOR_FROM_DATABASE=The Energy Conservatory, Inc. + +bluetooth:v067B* + ID_VENDOR_FROM_DATABASE=I.FARM, INC. + +bluetooth:v067C* + ID_VENDOR_FROM_DATABASE=Tile, Inc. + +bluetooth:v067D* + ID_VENDOR_FROM_DATABASE=Form Athletica Inc. + +bluetooth:v067E* + ID_VENDOR_FROM_DATABASE=MbientLab Inc + +bluetooth:v067F* + ID_VENDOR_FROM_DATABASE=NETGRID S.N.C. DI BISSOLI MATTEO, CAMPOREALE SIMONE, TOGNETTI FEDERICO + +bluetooth:v0680* + ID_VENDOR_FROM_DATABASE=Mannkind Corporation + +bluetooth:v0681* + ID_VENDOR_FROM_DATABASE=Trade FIDES a.s. + +bluetooth:v0682* + ID_VENDOR_FROM_DATABASE=Photron Limited + +bluetooth:v0683* + ID_VENDOR_FROM_DATABASE=Eltako GmbH + +bluetooth:v0684* + ID_VENDOR_FROM_DATABASE=Dermalapps, LLC + +bluetooth:v0685* + ID_VENDOR_FROM_DATABASE=Greenwald Industries + +bluetooth:v0686* + ID_VENDOR_FROM_DATABASE=inQs Co., Ltd. + +bluetooth:v0687* + ID_VENDOR_FROM_DATABASE=Cherry GmbH + +bluetooth:v0688* + ID_VENDOR_FROM_DATABASE=Amsted Digital Solutions Inc. + +bluetooth:v0689* + ID_VENDOR_FROM_DATABASE=Tacx b.v. + +bluetooth:v068A* + ID_VENDOR_FROM_DATABASE=Raytac Corporation + +bluetooth:v068B* + ID_VENDOR_FROM_DATABASE=Jiangsu Teranovo Tech Co., Ltd. + +bluetooth:v068C* + ID_VENDOR_FROM_DATABASE=Changzhou Sound Dragon Electronics and Acoustics Co., Ltd + +bluetooth:v068D* + ID_VENDOR_FROM_DATABASE=JetBeep Inc. + +bluetooth:v068E* + ID_VENDOR_FROM_DATABASE=Razer Inc. + +bluetooth:v068F* + ID_VENDOR_FROM_DATABASE=JRM Group Limited + +bluetooth:v0690* + ID_VENDOR_FROM_DATABASE=Eccrine Systems, Inc. + +bluetooth:v0691* + ID_VENDOR_FROM_DATABASE=Curie Point AB + +bluetooth:v0692* + ID_VENDOR_FROM_DATABASE=Georg Fischer AG + +bluetooth:v0693* + ID_VENDOR_FROM_DATABASE=Hach - Danaher + +bluetooth:v0694* + ID_VENDOR_FROM_DATABASE=T&A Laboratories LLC + +bluetooth:v0695* + ID_VENDOR_FROM_DATABASE=Koki Holdings Co., Ltd. + +bluetooth:v0696* + ID_VENDOR_FROM_DATABASE=Gunakar Private Limited + +bluetooth:v0697* + ID_VENDOR_FROM_DATABASE=Stemco Products Inc + +bluetooth:v0698* + ID_VENDOR_FROM_DATABASE=Wood IT Security, LLC + +bluetooth:v0699* + ID_VENDOR_FROM_DATABASE=RandomLab SAS + +bluetooth:v069A* + ID_VENDOR_FROM_DATABASE=Adero, Inc. (formerly as TrackR, Inc.) + +bluetooth:v069B* + ID_VENDOR_FROM_DATABASE=Dragonchip Limited + +bluetooth:v069C* + ID_VENDOR_FROM_DATABASE=Noomi AB + +bluetooth:v069D* + ID_VENDOR_FROM_DATABASE=Vakaros LLC + +bluetooth:v069E* + ID_VENDOR_FROM_DATABASE=Delta Electronics, Inc. + +bluetooth:v069F* + ID_VENDOR_FROM_DATABASE=FlowMotion Technologies AS + +bluetooth:v06A0* + ID_VENDOR_FROM_DATABASE=OBIQ Location Technology Inc. + +bluetooth:v06A1* + ID_VENDOR_FROM_DATABASE=Cardo Systems, Ltd + +bluetooth:v06A2* + ID_VENDOR_FROM_DATABASE=Globalworx GmbH + +bluetooth:v06A3* + ID_VENDOR_FROM_DATABASE=Nymbus, LLC + +bluetooth:v06A4* + ID_VENDOR_FROM_DATABASE=Sanyo Techno Solutions Tottori Co., Ltd. + +bluetooth:v06A5* + ID_VENDOR_FROM_DATABASE=TEKZITEL PTY LTD + +bluetooth:v06A6* + ID_VENDOR_FROM_DATABASE=Roambee Corporation + +bluetooth:v06A7* + ID_VENDOR_FROM_DATABASE=Chipsea Technologies (ShenZhen) Corp. + +bluetooth:v06A8* + ID_VENDOR_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co., Ltd. + +bluetooth:v06A9* + ID_VENDOR_FROM_DATABASE=Soundmax Electronics Limited + +bluetooth:v06AA* + ID_VENDOR_FROM_DATABASE=Produal Oy + +bluetooth:v06AB* + ID_VENDOR_FROM_DATABASE=HMS Industrial Networks AB + +bluetooth:v06AC* + ID_VENDOR_FROM_DATABASE=Ingchips Technology Co., Ltd. + +bluetooth:v06AD* + ID_VENDOR_FROM_DATABASE=InnovaSea Systems Inc. + +bluetooth:v06AE* + ID_VENDOR_FROM_DATABASE=SenseQ Inc. + +bluetooth:v06AF* + ID_VENDOR_FROM_DATABASE=Shoof Technologies + +bluetooth:v06B0* + ID_VENDOR_FROM_DATABASE=BRK Brands, Inc. + +bluetooth:v06B1* + ID_VENDOR_FROM_DATABASE=SimpliSafe, Inc. + +bluetooth:v06B2* + ID_VENDOR_FROM_DATABASE=Tussock Innovation 2013 Limited + +bluetooth:v06B3* + ID_VENDOR_FROM_DATABASE=The Hablab ApS + +bluetooth:v06B4* + ID_VENDOR_FROM_DATABASE=Sencilion Oy + +bluetooth:v06B5* + ID_VENDOR_FROM_DATABASE=Wabilogic Ltd. + +bluetooth:v06B6* + ID_VENDOR_FROM_DATABASE=Sociometric Solutions, Inc. + +bluetooth:v06B7* + ID_VENDOR_FROM_DATABASE=iCOGNIZE GmbH + +bluetooth:v06B8* + ID_VENDOR_FROM_DATABASE=ShadeCraft, Inc + +bluetooth:v06B9* + ID_VENDOR_FROM_DATABASE=Beflex Inc. + +bluetooth:v06BA* + ID_VENDOR_FROM_DATABASE=Beaconzone Ltd + +bluetooth:v06BB* + ID_VENDOR_FROM_DATABASE=Leaftronix Analogic Solutions Private Limited + +bluetooth:v06BC* + ID_VENDOR_FROM_DATABASE=TWS Srl + +bluetooth:v06BD* + ID_VENDOR_FROM_DATABASE=ABB Oy + +bluetooth:v06BE* + ID_VENDOR_FROM_DATABASE=HitSeed Oy + +bluetooth:v06BF* + ID_VENDOR_FROM_DATABASE=Delcom Products Inc. + +bluetooth:v06C0* + ID_VENDOR_FROM_DATABASE=CAME S.p.A. + +bluetooth:v06C1* + ID_VENDOR_FROM_DATABASE=Alarm.com Holdings, Inc + +bluetooth:v06C2* + ID_VENDOR_FROM_DATABASE=Measurlogic Inc. + +bluetooth:v06C3* + ID_VENDOR_FROM_DATABASE=King I Electronics.Co.,Ltd + +bluetooth:v06C4* + ID_VENDOR_FROM_DATABASE=Dream Labs GmbH + +bluetooth:v06C5* + ID_VENDOR_FROM_DATABASE=Urban Compass, Inc + +bluetooth:v06C6* + ID_VENDOR_FROM_DATABASE=Simm Tronic Limited + +bluetooth:v06C7* + ID_VENDOR_FROM_DATABASE=Somatix Inc + +bluetooth:v06C8* + ID_VENDOR_FROM_DATABASE=Storz & Bickel GmbH & Co. KG + +bluetooth:v06C9* + ID_VENDOR_FROM_DATABASE=MYLAPS B.V. + +bluetooth:v06CA* + ID_VENDOR_FROM_DATABASE=Shenzhen Zhongguang Infotech Technology Development Co., Ltd + +bluetooth:v06CB* + ID_VENDOR_FROM_DATABASE=Dyeware, LLC + +bluetooth:v06CC* + ID_VENDOR_FROM_DATABASE=Dongguan SmartAction Technology Co.,Ltd. + +bluetooth:v06CD* + ID_VENDOR_FROM_DATABASE=DIG Corporation + +bluetooth:v06CE* + ID_VENDOR_FROM_DATABASE=FIOR & GENTZ + +bluetooth:v06CF* + ID_VENDOR_FROM_DATABASE=Belparts N.V. + +bluetooth:v06D0* + ID_VENDOR_FROM_DATABASE=Etekcity Corporation + +bluetooth:v06D1* + ID_VENDOR_FROM_DATABASE=Meyer Sound Laboratories, Incorporated + +bluetooth:v06D2* + ID_VENDOR_FROM_DATABASE=CeoTronics AG + +bluetooth:v06D3* + ID_VENDOR_FROM_DATABASE=TriTeq Lock and Security, LLC + +bluetooth:v06D4* + ID_VENDOR_FROM_DATABASE=DYNAKODE TECHNOLOGY PRIVATE LIMITED + +bluetooth:v06D5* + ID_VENDOR_FROM_DATABASE=Sensirion AG + +bluetooth:v06D6* + ID_VENDOR_FROM_DATABASE=JCT Healthcare Pty Ltd + +bluetooth:v06D7* + ID_VENDOR_FROM_DATABASE=FUBA Automotive Electronics GmbH + +bluetooth:v06D8* + ID_VENDOR_FROM_DATABASE=AW Company + +bluetooth:v06D9* + ID_VENDOR_FROM_DATABASE=Shanghai Mountain View Silicon Co.,Ltd. + +bluetooth:v06DA* + ID_VENDOR_FROM_DATABASE=Zliide Technologies ApS + +bluetooth:v06DB* + ID_VENDOR_FROM_DATABASE=Automatic Labs, Inc. + +bluetooth:v06DC* + ID_VENDOR_FROM_DATABASE=Industrial Network Controls, LLC + +bluetooth:v06DD* + ID_VENDOR_FROM_DATABASE=Intellithings Ltd. + +bluetooth:v06DE* + ID_VENDOR_FROM_DATABASE=Navcast, Inc. + +bluetooth:v06DF* + ID_VENDOR_FROM_DATABASE=Hubbell Lighting, Inc. + +bluetooth:v06E0* + ID_VENDOR_FROM_DATABASE=Avaya + +bluetooth:v06E1* + ID_VENDOR_FROM_DATABASE=Milestone AV Technologies LLC + +bluetooth:v06E2* + ID_VENDOR_FROM_DATABASE=Alango Technologies Ltd + +bluetooth:v06E3* + ID_VENDOR_FROM_DATABASE=Spinlock Ltd + +bluetooth:v06E4* + ID_VENDOR_FROM_DATABASE=Aluna + +bluetooth:v06E5* + ID_VENDOR_FROM_DATABASE=OPTEX CO.,LTD. + +bluetooth:v06E6* + ID_VENDOR_FROM_DATABASE=NIHON DENGYO KOUSAKU + +bluetooth:v06E7* + ID_VENDOR_FROM_DATABASE=VELUX A/S + +bluetooth:v06E8* + ID_VENDOR_FROM_DATABASE=Almendo Technologies GmbH + +bluetooth:v06E9* + ID_VENDOR_FROM_DATABASE=Zmartfun Electronics, Inc. + +bluetooth:v06EA* + ID_VENDOR_FROM_DATABASE=SafeLine Sweden AB + +bluetooth:v06EB* + ID_VENDOR_FROM_DATABASE=Houston Radar LLC + +bluetooth:v06EC* + ID_VENDOR_FROM_DATABASE=Sigur + +bluetooth:v06ED* + ID_VENDOR_FROM_DATABASE=J Neades Ltd + +bluetooth:v06EE* + ID_VENDOR_FROM_DATABASE=Avantis Systems Limited + +bluetooth:v06EF* + ID_VENDOR_FROM_DATABASE=ALCARE Co., Ltd. + +bluetooth:v06F0* + ID_VENDOR_FROM_DATABASE=Chargy Technologies, SL + +bluetooth:v06F1* + ID_VENDOR_FROM_DATABASE=Shibutani Co., Ltd. + +bluetooth:v06F2* + ID_VENDOR_FROM_DATABASE=Trapper Data AB + +bluetooth:v06F3* + ID_VENDOR_FROM_DATABASE=Alfred International Inc. + +bluetooth:v06F4* + ID_VENDOR_FROM_DATABASE=Near Field Solutions Ltd + +bluetooth:v06F5* + ID_VENDOR_FROM_DATABASE=Vigil Technologies Inc. + +bluetooth:v06F6* + ID_VENDOR_FROM_DATABASE=Vitulo Plus BV + +bluetooth:v06F7* + ID_VENDOR_FROM_DATABASE=WILKA Schliesstechnik GmbH + +bluetooth:v06F8* + ID_VENDOR_FROM_DATABASE=BodyPlus Technology Co.,Ltd + +bluetooth:v06F9* + ID_VENDOR_FROM_DATABASE=happybrush GmbH + +bluetooth:v06FA* + ID_VENDOR_FROM_DATABASE=Enequi AB + +bluetooth:v06FB* + ID_VENDOR_FROM_DATABASE=Sartorius AG + +bluetooth:v06FC* + ID_VENDOR_FROM_DATABASE=Tom Communication Industrial Co.,Ltd. + +bluetooth:v06FD* + ID_VENDOR_FROM_DATABASE=ESS Embedded System Solutions Inc. + +bluetooth:v06FE* + ID_VENDOR_FROM_DATABASE=Mahr GmbH + +bluetooth:v06FF* + ID_VENDOR_FROM_DATABASE=Redpine Signals Inc + +bluetooth:v0700* + ID_VENDOR_FROM_DATABASE=TraqFreq LLC + +bluetooth:v0701* + ID_VENDOR_FROM_DATABASE=PAFERS TECH + +bluetooth:v0702* + ID_VENDOR_FROM_DATABASE=Akciju sabiedriba "SAF TEHNIKA" + +bluetooth:v0703* + ID_VENDOR_FROM_DATABASE=Beijing Jingdong Century Trading Co., Ltd. + +bluetooth:v0704* + ID_VENDOR_FROM_DATABASE=JBX Designs Inc. + +bluetooth:v0705* + ID_VENDOR_FROM_DATABASE=AB Electrolux + +bluetooth:v0706* + ID_VENDOR_FROM_DATABASE=Wernher von Braun Center for ASdvanced Research + +bluetooth:v0707* + ID_VENDOR_FROM_DATABASE=Essity Hygiene and Health Aktiebolag + +bluetooth:v0708* + ID_VENDOR_FROM_DATABASE=Be Interactive Co., Ltd + +bluetooth:v0709* + ID_VENDOR_FROM_DATABASE=Carewear Corp. + +bluetooth:v070A* + ID_VENDOR_FROM_DATABASE=Huf Hülsbeck & Fürst GmbH & Co. KG + +bluetooth:v070B* + ID_VENDOR_FROM_DATABASE=Element Products, Inc. + +bluetooth:v070C* + ID_VENDOR_FROM_DATABASE=Beijing Winner Microelectronics Co.,Ltd + +bluetooth:v070D* + ID_VENDOR_FROM_DATABASE=SmartSnugg Pty Ltd + +bluetooth:v070E* + ID_VENDOR_FROM_DATABASE=FiveCo Sarl + +bluetooth:v070F* + ID_VENDOR_FROM_DATABASE=California Things Inc. + +bluetooth:v0710* + ID_VENDOR_FROM_DATABASE=Audiodo AB + +bluetooth:v0711* + ID_VENDOR_FROM_DATABASE=ABAX AS + +bluetooth:v0712* + ID_VENDOR_FROM_DATABASE=Bull Group Company Limited + +bluetooth:v0713* + ID_VENDOR_FROM_DATABASE=Respiri Limited + +bluetooth:v0714* + ID_VENDOR_FROM_DATABASE=MindPeace Safety LLC + +bluetooth:v0715* + ID_VENDOR_FROM_DATABASE=Vgyan Solutions + +bluetooth:v0716* + ID_VENDOR_FROM_DATABASE=Altonics + +bluetooth:v0717* + ID_VENDOR_FROM_DATABASE=iQsquare BV + +bluetooth:v0718* + ID_VENDOR_FROM_DATABASE=IDIBAIX enginneering + +bluetooth:v0719* + ID_VENDOR_FROM_DATABASE=ECSG + +bluetooth:v071A* + ID_VENDOR_FROM_DATABASE=REVSMART WEARABLE HK CO LTD + +bluetooth:v071B* + ID_VENDOR_FROM_DATABASE=Precor + +bluetooth:v071C* + ID_VENDOR_FROM_DATABASE=F5 Sports, Inc + +bluetooth:v071D* + ID_VENDOR_FROM_DATABASE=exoTIC Systems + +bluetooth:v071E* + ID_VENDOR_FROM_DATABASE=DONGGUAN HELE ELECTRONICS CO., LTD + +bluetooth:v071F* + ID_VENDOR_FROM_DATABASE=Dongguan Liesheng Electronic Co.Ltd + +bluetooth:v0720* + ID_VENDOR_FROM_DATABASE=Oculeve, Inc. + +bluetooth:v0721* + ID_VENDOR_FROM_DATABASE=Clover Network, Inc. + +bluetooth:v0722* + ID_VENDOR_FROM_DATABASE=Xiamen Eholder Electronics Co.Ltd + +bluetooth:v0723* + ID_VENDOR_FROM_DATABASE=Ford Motor Company + +bluetooth:v0724* + ID_VENDOR_FROM_DATABASE=Guangzhou SuperSound Information Technology Co.,Ltd + +bluetooth:v0725* + ID_VENDOR_FROM_DATABASE=Tedee Sp. z o.o. + +bluetooth:v0726* + ID_VENDOR_FROM_DATABASE=PHC Corporation + +bluetooth:v0727* + ID_VENDOR_FROM_DATABASE=STALKIT AS + +bluetooth:v0728* + ID_VENDOR_FROM_DATABASE=Eli Lilly and Company + +bluetooth:v0729* + ID_VENDOR_FROM_DATABASE=SwaraLink Technologies + +bluetooth:v072A* + ID_VENDOR_FROM_DATABASE=JMR embedded systems GmbH + +bluetooth:v072B* + ID_VENDOR_FROM_DATABASE=Bitkey Inc. + +bluetooth:v072C* + ID_VENDOR_FROM_DATABASE=GWA Hygiene GmbH + +bluetooth:v072D* + ID_VENDOR_FROM_DATABASE=Safera Oy + +bluetooth:v072E* + ID_VENDOR_FROM_DATABASE=Open Platform Systems LLC + +bluetooth:v072F* + ID_VENDOR_FROM_DATABASE=OnePlus Electronics (Shenzhen) Co., Ltd. + +bluetooth:v0730* + ID_VENDOR_FROM_DATABASE=Wildlife Acoustics, Inc. + +bluetooth:v0731* + ID_VENDOR_FROM_DATABASE=ABLIC Inc. + +bluetooth:v0732* + ID_VENDOR_FROM_DATABASE=Dairy Tech, Inc. + +bluetooth:v0733* + ID_VENDOR_FROM_DATABASE=Iguanavation, Inc. + +bluetooth:v0734* + ID_VENDOR_FROM_DATABASE=DiUS Computing Pty Ltd + +bluetooth:v0735* + ID_VENDOR_FROM_DATABASE=UpRight Technologies LTD + +bluetooth:v0736* + ID_VENDOR_FROM_DATABASE=FrancisFund, LLC + +bluetooth:v0737* + ID_VENDOR_FROM_DATABASE=LLC Navitek + +bluetooth:v0738* + ID_VENDOR_FROM_DATABASE=Glass Security Pte Ltd + +bluetooth:v0739* + ID_VENDOR_FROM_DATABASE=Jiangsu Qinheng Co., Ltd. + +bluetooth:v073A* + ID_VENDOR_FROM_DATABASE=Chandler Systems Inc. + +bluetooth:v073B* + ID_VENDOR_FROM_DATABASE=Fantini Cosmi s.p.a. + +bluetooth:v073C* + ID_VENDOR_FROM_DATABASE=Acubit ApS + +bluetooth:v073D* + ID_VENDOR_FROM_DATABASE=Beijing Hao Heng Tian Tech Co., Ltd. + +bluetooth:v073E* + ID_VENDOR_FROM_DATABASE=Bluepack S.R.L. + +bluetooth:v073F* + ID_VENDOR_FROM_DATABASE=Beijing Unisoc Technologies Co., Ltd. + +bluetooth:v0740* + ID_VENDOR_FROM_DATABASE=HITIQ LIMITED + +bluetooth:v0741* + ID_VENDOR_FROM_DATABASE=MAC SRL + +bluetooth:v0742* + ID_VENDOR_FROM_DATABASE=DML LLC + +bluetooth:v0743* + ID_VENDOR_FROM_DATABASE=Sanofi + +bluetooth:v0744* + ID_VENDOR_FROM_DATABASE=SOCOMEC + +bluetooth:v0745* + ID_VENDOR_FROM_DATABASE=WIZNOVA, Inc. + +bluetooth:v0746* + ID_VENDOR_FROM_DATABASE=Seitec Elektronik GmbH + +bluetooth:v0747* + ID_VENDOR_FROM_DATABASE=OR Technologies Pty Ltd + +bluetooth:v0748* + ID_VENDOR_FROM_DATABASE=GuangZhou KuGou Computer Technology Co.Ltd + +bluetooth:v0749* + ID_VENDOR_FROM_DATABASE=DIAODIAO (Beijing) Technology Co., Ltd. + +bluetooth:v074A* + ID_VENDOR_FROM_DATABASE=Illusory Studios LLC + +bluetooth:v074B* + ID_VENDOR_FROM_DATABASE=Sarvavid Software Solutions LLP + +bluetooth:v074C* + ID_VENDOR_FROM_DATABASE=iopool s.a. + +bluetooth:v074D* + ID_VENDOR_FROM_DATABASE=Amtech Systems, LLC + +bluetooth:v074E* + ID_VENDOR_FROM_DATABASE=EAGLE DETECTION SA + +bluetooth:v074F* + ID_VENDOR_FROM_DATABASE=MEDIATECH S.R.L. + +bluetooth:v0750* + ID_VENDOR_FROM_DATABASE=Hamilton Professional Services of Canada Incorporated + +bluetooth:v0751* + ID_VENDOR_FROM_DATABASE=Changsha JEMO IC Design Co.,Ltd + +bluetooth:v0752* + ID_VENDOR_FROM_DATABASE=Elatec GmbH + +bluetooth:v0753* + ID_VENDOR_FROM_DATABASE=JLG Industries, Inc. + +bluetooth:v0754* + ID_VENDOR_FROM_DATABASE=Michael Parkin + +bluetooth:v0755* + ID_VENDOR_FROM_DATABASE=Brother Industries, Ltd + +bluetooth:v0756* + ID_VENDOR_FROM_DATABASE=Lumens For Less, Inc + +bluetooth:v0757* + ID_VENDOR_FROM_DATABASE=ELA Innovation + +bluetooth:v0758* + ID_VENDOR_FROM_DATABASE=umanSense AB + +bluetooth:v0759* + ID_VENDOR_FROM_DATABASE=Shanghai InGeek Cyber Security Co., Ltd. + +bluetooth:v075A* + ID_VENDOR_FROM_DATABASE=HARMAN CO.,LTD. + +bluetooth:v075B* + ID_VENDOR_FROM_DATABASE=Smart Sensor Devices AB + +bluetooth:v075C* + ID_VENDOR_FROM_DATABASE=Antitronics Inc. + +bluetooth:v075D* + ID_VENDOR_FROM_DATABASE=RHOMBUS SYSTEMS, INC. + +bluetooth:v075E* + ID_VENDOR_FROM_DATABASE=Katerra Inc. + +bluetooth:v075F* + ID_VENDOR_FROM_DATABASE=Remote Solution Co., LTD. + +bluetooth:v0760* + ID_VENDOR_FROM_DATABASE=Vimar SpA + +bluetooth:v0761* + ID_VENDOR_FROM_DATABASE=Mantis Tech LLC + +bluetooth:v0762* + ID_VENDOR_FROM_DATABASE=TerOpta Ltd + +bluetooth:v0763* + ID_VENDOR_FROM_DATABASE=PIKOLIN S.L. + +bluetooth:v0764* + ID_VENDOR_FROM_DATABASE=WWZN Information Technology Company Limited + +bluetooth:v0765* + ID_VENDOR_FROM_DATABASE=Voxx International + +bluetooth:v0766* + ID_VENDOR_FROM_DATABASE=ART AND PROGRAM, INC. + +bluetooth:v0767* + ID_VENDOR_FROM_DATABASE=NITTO DENKO ASIA TECHNICAL CENTRE PTE. LTD. + +bluetooth:v0768* + ID_VENDOR_FROM_DATABASE=Peloton Interactive Inc. + +bluetooth:v0769* + ID_VENDOR_FROM_DATABASE=Force Impact Technologies + +bluetooth:v076A* + ID_VENDOR_FROM_DATABASE=Dmac Mobile Developments, LLC + +bluetooth:v076B* + ID_VENDOR_FROM_DATABASE=Engineered Medical Technologies + +bluetooth:v076C* + ID_VENDOR_FROM_DATABASE=Noodle Technology inc + +bluetooth:v076D* + ID_VENDOR_FROM_DATABASE=Graesslin GmbH + +bluetooth:v076E* + ID_VENDOR_FROM_DATABASE=WuQi technologies, Inc. + +bluetooth:v076F* + ID_VENDOR_FROM_DATABASE=Successful Endeavours Pty Ltd + +bluetooth:v0770* + ID_VENDOR_FROM_DATABASE=InnoCon Medical ApS + +bluetooth:v0771* + ID_VENDOR_FROM_DATABASE=Corvex Connected Safety + +bluetooth:v0772* + ID_VENDOR_FROM_DATABASE=Thirdwayv Inc. + +bluetooth:v0773* + ID_VENDOR_FROM_DATABASE=Echoflex Solutions Inc. + +bluetooth:v0774* + ID_VENDOR_FROM_DATABASE=C-MAX Asia Limited + +bluetooth:v0775* + ID_VENDOR_FROM_DATABASE=4eBusiness GmbH + +bluetooth:v0776* + ID_VENDOR_FROM_DATABASE=Cyber Transport Control GmbH + +bluetooth:v0777* + ID_VENDOR_FROM_DATABASE=Cue + +bluetooth:v0778* + ID_VENDOR_FROM_DATABASE=KOAMTAC INC. + +bluetooth:v0779* + ID_VENDOR_FROM_DATABASE=Loopshore Oy + +bluetooth:v077A* + ID_VENDOR_FROM_DATABASE=Niruha Systems Private Limited + +bluetooth:v077B* + ID_VENDOR_FROM_DATABASE=AmaterZ, Inc. + +bluetooth:v077C* + ID_VENDOR_FROM_DATABASE=radius co., ltd. + +bluetooth:v077D* + ID_VENDOR_FROM_DATABASE=Sensority, s.r.o. + +bluetooth:v077E* + ID_VENDOR_FROM_DATABASE=Sparkage Inc. + +bluetooth:v077F* + ID_VENDOR_FROM_DATABASE=Glenview Software Corporation + +bluetooth:v0780* + ID_VENDOR_FROM_DATABASE=Finch Technologies Ltd. + +bluetooth:v0781* + ID_VENDOR_FROM_DATABASE=Qingping Technology (Beijing) Co., Ltd. + +bluetooth:v0782* + ID_VENDOR_FROM_DATABASE=DeviceDrive AS + +bluetooth:v0783* + ID_VENDOR_FROM_DATABASE=ESEMBER LIMITED LIABILITY COMPANY + +bluetooth:v0784* + ID_VENDOR_FROM_DATABASE=audifon GmbH & Co. KG + +bluetooth:v0785* + ID_VENDOR_FROM_DATABASE=O2 Micro, Inc. + +bluetooth:v0786* + ID_VENDOR_FROM_DATABASE=HLP Controls Pty Limited + +bluetooth:v0787* + ID_VENDOR_FROM_DATABASE=Pangaea Solution + +bluetooth:v0788* + ID_VENDOR_FROM_DATABASE=BubblyNet, LLC + +bluetooth:v078A* + ID_VENDOR_FROM_DATABASE=The Wildflower Foundation + +bluetooth:v078B* + ID_VENDOR_FROM_DATABASE=Optikam Tech Inc. + +bluetooth:v078C* + ID_VENDOR_FROM_DATABASE=MINIBREW HOLDING B.V + +bluetooth:v078D* + ID_VENDOR_FROM_DATABASE=Cybex GmbH + +bluetooth:v078E* + ID_VENDOR_FROM_DATABASE=FUJIMIC NIIGATA, INC. + +bluetooth:v078F* + ID_VENDOR_FROM_DATABASE=Hanna Instruments, Inc. + +bluetooth:v0790* + ID_VENDOR_FROM_DATABASE=KOMPAN A/S + +bluetooth:v0791* + ID_VENDOR_FROM_DATABASE=Scosche Industries, Inc. + +bluetooth:v0792* + ID_VENDOR_FROM_DATABASE=Provo Craft + +bluetooth:v0793* + ID_VENDOR_FROM_DATABASE=AEV spol. s r.o. + +bluetooth:v0794* + ID_VENDOR_FROM_DATABASE=The Coca-Cola Company + +bluetooth:v0795* + ID_VENDOR_FROM_DATABASE=GASTEC CORPORATION + +bluetooth:v0796* + ID_VENDOR_FROM_DATABASE=StarLeaf Ltd + +bluetooth:v0797* + ID_VENDOR_FROM_DATABASE=Water-i.d. GmbH + +bluetooth:v0798* + ID_VENDOR_FROM_DATABASE=HoloKit, Inc. + +bluetooth:v0799* + ID_VENDOR_FROM_DATABASE=PlantChoir Inc. + +bluetooth:v079A* + ID_VENDOR_FROM_DATABASE=GuangDong Oppo Mobile Telecommunications Corp., Ltd. + +bluetooth:v079B* + ID_VENDOR_FROM_DATABASE=CST ELECTRONICS (PROPRIETARY) LIMITED + +bluetooth:v079C* + ID_VENDOR_FROM_DATABASE=Sky UK Limited + +bluetooth:v079D* + ID_VENDOR_FROM_DATABASE=Digibale Pty Ltd + +bluetooth:v079E* + ID_VENDOR_FROM_DATABASE=Smartloxx GmbH + +bluetooth:v079F* + ID_VENDOR_FROM_DATABASE=Pune Scientific LLP + +bluetooth:v07A0* + ID_VENDOR_FROM_DATABASE=Regent Beleuchtungskorper AG + +bluetooth:v07A1* + ID_VENDOR_FROM_DATABASE=Apollo Neuroscience, Inc. + +bluetooth:v07A2* + ID_VENDOR_FROM_DATABASE=Roku, Inc. + +bluetooth:v07A3* + ID_VENDOR_FROM_DATABASE=Comcast Cable + +bluetooth:v07A4* + ID_VENDOR_FROM_DATABASE=Xiamen Mage Information Technology Co., Ltd. + +bluetooth:v07A5* + ID_VENDOR_FROM_DATABASE=RAB Lighting, Inc. + +bluetooth:v07A6* + ID_VENDOR_FROM_DATABASE=Musen Connect, Inc. + +bluetooth:v07A7* + ID_VENDOR_FROM_DATABASE=Zume, Inc. + +bluetooth:v07A8* + ID_VENDOR_FROM_DATABASE=conbee GmbH + +bluetooth:v07A9* + ID_VENDOR_FROM_DATABASE=Bruel & Kjaer Sound & Vibration + +bluetooth:v07AA* + ID_VENDOR_FROM_DATABASE=The Kroger Co. + +bluetooth:v07AB* + ID_VENDOR_FROM_DATABASE=Granite River Solutions, Inc. + +bluetooth:v07AC* + ID_VENDOR_FROM_DATABASE=LoupeDeck Oy + +bluetooth:v07AD* + ID_VENDOR_FROM_DATABASE=New H3C Technologies Co.,Ltd + +bluetooth:v07AE* + ID_VENDOR_FROM_DATABASE=Aurea Solucoes Tecnologicas Ltda. + +bluetooth:v07AF* + ID_VENDOR_FROM_DATABASE=Hong Kong Bouffalo Lab Limited + +bluetooth:v07B0* + ID_VENDOR_FROM_DATABASE=GV Concepts Inc. + +bluetooth:v07B1* + ID_VENDOR_FROM_DATABASE=Thomas Dynamics, LLC + +bluetooth:v07B2* + ID_VENDOR_FROM_DATABASE=Moeco IOT Inc. + +bluetooth:v07B3* + ID_VENDOR_FROM_DATABASE=2N TELEKOMUNIKACE a.s. + +bluetooth:v07B4* + ID_VENDOR_FROM_DATABASE=Hormann KG Antriebstechnik + +bluetooth:v07B5* + ID_VENDOR_FROM_DATABASE=CRONO CHIP, S.L. + +bluetooth:v07B6* + ID_VENDOR_FROM_DATABASE=Soundbrenner Limited + +bluetooth:v07B7* + ID_VENDOR_FROM_DATABASE=ETABLISSEMENTS GEORGES RENAULT + +bluetooth:v07B8* + ID_VENDOR_FROM_DATABASE=iSwip + +bluetooth:v07B9* + ID_VENDOR_FROM_DATABASE=Epona Biotec Limited + +bluetooth:v07BA* + ID_VENDOR_FROM_DATABASE=Battery-Biz Inc. + +bluetooth:v07BB* + ID_VENDOR_FROM_DATABASE=EPIC S.R.L. + +bluetooth:v07BC* + ID_VENDOR_FROM_DATABASE=KD CIRCUITS LLC + +bluetooth:v07BD* + ID_VENDOR_FROM_DATABASE=Genedrive Diagnostics Ltd + +bluetooth:v07BE* + ID_VENDOR_FROM_DATABASE=Axentia Technologies AB + +bluetooth:v07BF* + ID_VENDOR_FROM_DATABASE=REGULA Ltd. + +bluetooth:v07C0* + ID_VENDOR_FROM_DATABASE=Biral AG + +bluetooth:v07C1* + ID_VENDOR_FROM_DATABASE=A.W. Chesterton Company + +bluetooth:v07C2* + ID_VENDOR_FROM_DATABASE=Radinn AB + +bluetooth:v07C3* + ID_VENDOR_FROM_DATABASE=CIMTechniques, Inc. + +bluetooth:v07C4* + ID_VENDOR_FROM_DATABASE=Johnson Health Tech NA + +bluetooth:v07C5* + ID_VENDOR_FROM_DATABASE=June Life, Inc. + +bluetooth:v07C6* + ID_VENDOR_FROM_DATABASE=Bluenetics GmbH + +bluetooth:v07C7* + ID_VENDOR_FROM_DATABASE=iaconicDesign Inc. + +bluetooth:v07C8* + ID_VENDOR_FROM_DATABASE=WRLDS Creations AB + +bluetooth:v07C9* + ID_VENDOR_FROM_DATABASE=Skullcandy, Inc. + +bluetooth:v07CA* + ID_VENDOR_FROM_DATABASE=Modul-System HH AB + +bluetooth:v07CB* + ID_VENDOR_FROM_DATABASE=West Pharmaceutical Services, Inc. + +bluetooth:v07CC* + ID_VENDOR_FROM_DATABASE=Barnacle Systems Inc. + +bluetooth:v07CD* + ID_VENDOR_FROM_DATABASE=Smart Wave Technologies Canada Inc + +bluetooth:v07CE* + ID_VENDOR_FROM_DATABASE=Shanghai Top-Chip Microelectronics Tech. Co., LTD + +bluetooth:v07CF* + ID_VENDOR_FROM_DATABASE=NeoSensory, Inc. + +bluetooth:v07D0* + ID_VENDOR_FROM_DATABASE=Hangzhou Tuya Information Technology Co., Ltd + +bluetooth:v07D1* + ID_VENDOR_FROM_DATABASE=Shanghai Panchip Microelectronics Co., Ltd + +bluetooth:v07D2* + ID_VENDOR_FROM_DATABASE=React Accessibility Limited + +bluetooth:v07D3* + ID_VENDOR_FROM_DATABASE=LIVNEX Co.,Ltd. + +bluetooth:v07D4* + ID_VENDOR_FROM_DATABASE=Kano Computing Limited + +bluetooth:v07D5* + ID_VENDOR_FROM_DATABASE=hoots classic GmbH + +bluetooth:v07D6* + ID_VENDOR_FROM_DATABASE=ecobee Inc. + +bluetooth:v07D7* + ID_VENDOR_FROM_DATABASE=Nanjing Qinheng Microelectronics Co., Ltd + +bluetooth:v07D8* + ID_VENDOR_FROM_DATABASE=SOLUTIONS AMBRA INC. + +bluetooth:v07D9* + ID_VENDOR_FROM_DATABASE=Micro-Design, Inc. + +bluetooth:v07DA* + ID_VENDOR_FROM_DATABASE=STARLITE Co., Ltd. + +bluetooth:v07DB* + ID_VENDOR_FROM_DATABASE=Remedee Labs + +bluetooth:v07DC* + ID_VENDOR_FROM_DATABASE=ThingOS GmbH + +bluetooth:v07DD* + ID_VENDOR_FROM_DATABASE=Linear Circuits + +bluetooth:v07DE* + ID_VENDOR_FROM_DATABASE=Unlimited Engineering SL + +bluetooth:v07DF* + ID_VENDOR_FROM_DATABASE=Snap-on Incorporated + +bluetooth:v07E0* + ID_VENDOR_FROM_DATABASE=Edifier International Limited + +bluetooth:v07E1* + ID_VENDOR_FROM_DATABASE=Lucie Labs + +bluetooth:v07E2* + ID_VENDOR_FROM_DATABASE=Alfred Kaercher SE & Co. KG + +bluetooth:v07E3* + ID_VENDOR_FROM_DATABASE=Audiowise Technology Inc. + +bluetooth:v07E4* + ID_VENDOR_FROM_DATABASE=Geeksme S.L. + +bluetooth:v07E5* + ID_VENDOR_FROM_DATABASE=Minut, Inc. + +bluetooth:v07E6* + ID_VENDOR_FROM_DATABASE=Autogrow Systems Limited + +bluetooth:v07E7* + ID_VENDOR_FROM_DATABASE=Komfort IQ, Inc. + +bluetooth:v07E8* + ID_VENDOR_FROM_DATABASE=Packetcraft, Inc. + +bluetooth:v07E9* + ID_VENDOR_FROM_DATABASE=Häfele GmbH & Co KG + +bluetooth:v07EA* + ID_VENDOR_FROM_DATABASE=ShapeLog, Inc. + +bluetooth:v07EB* + ID_VENDOR_FROM_DATABASE=NOVABASE S.R.L. + +bluetooth:v07EC* + ID_VENDOR_FROM_DATABASE=Frecce LLC + +bluetooth:v07ED* + ID_VENDOR_FROM_DATABASE=Joule IQ, INC. + +bluetooth:v07EE* + ID_VENDOR_FROM_DATABASE=KidzTek LLC + +bluetooth:v07EF* + ID_VENDOR_FROM_DATABASE=Aktiebolaget Sandvik Coromant + +bluetooth:v07F0* + ID_VENDOR_FROM_DATABASE=e-moola.com Pty Ltd + +bluetooth:v07F1* + ID_VENDOR_FROM_DATABASE=GSM Innovations Pty Ltd + +bluetooth:v07F2* + ID_VENDOR_FROM_DATABASE=SERENE GROUP, INC + +bluetooth:v07F3* + ID_VENDOR_FROM_DATABASE=DIGISINE ENERGYTECH CO. LTD. + +bluetooth:v07F4* + ID_VENDOR_FROM_DATABASE=MEDIRLAB Orvosbiologiai Fejleszto Korlatolt Felelossegu Tarsasag + +bluetooth:v07F5* + ID_VENDOR_FROM_DATABASE=Byton North America Corporation + +bluetooth:v07F6* + ID_VENDOR_FROM_DATABASE=Shenzhen TonliScience and Technology Development Co.,Ltd + +bluetooth:v07F7* + ID_VENDOR_FROM_DATABASE=Cesar Systems Ltd. + +bluetooth:v07F8* + ID_VENDOR_FROM_DATABASE=quip NYC Inc. + +bluetooth:v07F9* + ID_VENDOR_FROM_DATABASE=Direct Communication Solutions, Inc. + +bluetooth:v07FA* + ID_VENDOR_FROM_DATABASE=Klipsch Group, Inc. + +bluetooth:v07FB* + ID_VENDOR_FROM_DATABASE=Access Co., Ltd + +bluetooth:v07FC* + ID_VENDOR_FROM_DATABASE=Renault SA + +bluetooth:v07FD* + ID_VENDOR_FROM_DATABASE=JSK CO., LTD. + +bluetooth:v07FE* + ID_VENDOR_FROM_DATABASE=BIROTA + +bluetooth:v07FF* + ID_VENDOR_FROM_DATABASE=maxon motor ltd. + +bluetooth:v0800* + ID_VENDOR_FROM_DATABASE=Optek + +bluetooth:v0801* + ID_VENDOR_FROM_DATABASE=CRONUS ELECTRONICS LTD + +bluetooth:v0802* + ID_VENDOR_FROM_DATABASE=NantSound, Inc. + +bluetooth:v0803* + ID_VENDOR_FROM_DATABASE=Domintell s.a. + +bluetooth:v0804* + ID_VENDOR_FROM_DATABASE=Andon Health Co.,Ltd + +bluetooth:v0805* + ID_VENDOR_FROM_DATABASE=Urbanminded Ltd + +bluetooth:v0806* + ID_VENDOR_FROM_DATABASE=TYRI Sweden AB + +bluetooth:v0807* + ID_VENDOR_FROM_DATABASE=ECD Electronic Components GmbH Dresden + +bluetooth:v0808* + ID_VENDOR_FROM_DATABASE=SISTEMAS KERN, SOCIEDAD ANÓMINA + +bluetooth:v0809* + ID_VENDOR_FROM_DATABASE=Trulli Audio + +bluetooth:v080A* + ID_VENDOR_FROM_DATABASE=Altaneos + +bluetooth:v080B* + ID_VENDOR_FROM_DATABASE=Nanoleaf Canada Limited + +bluetooth:v080C* + ID_VENDOR_FROM_DATABASE=Ingy B.V. + +bluetooth:v080D* + ID_VENDOR_FROM_DATABASE=Azbil Co. + +bluetooth:v080E* + ID_VENDOR_FROM_DATABASE=TATTCOM LLC + +bluetooth:v080F* + ID_VENDOR_FROM_DATABASE=Paradox Engineering SA + +bluetooth:v0810* + ID_VENDOR_FROM_DATABASE=LECO Corporation + +bluetooth:v0811* + ID_VENDOR_FROM_DATABASE=Becker Antriebe GmbH + +bluetooth:v0812* + ID_VENDOR_FROM_DATABASE=Mstream Technologies., Inc. + +bluetooth:v0813* + ID_VENDOR_FROM_DATABASE=Flextronics International USA Inc. + +bluetooth:v0814* + ID_VENDOR_FROM_DATABASE=Ossur hf. + +bluetooth:v0815* + ID_VENDOR_FROM_DATABASE=SKC Inc + +bluetooth:v0816* + ID_VENDOR_FROM_DATABASE=SPICA SYSTEMS LLC + +bluetooth:v0817* + ID_VENDOR_FROM_DATABASE=Wangs Alliance Corporation + +bluetooth:v0818* + ID_VENDOR_FROM_DATABASE=tatwah SA + +bluetooth:v0819* + ID_VENDOR_FROM_DATABASE=Hunter Douglas Inc + +bluetooth:v081A* + ID_VENDOR_FROM_DATABASE=Shenzhen Conex + +bluetooth:v081B* + ID_VENDOR_FROM_DATABASE=DIM3 + +bluetooth:v081C* + ID_VENDOR_FROM_DATABASE=Bobrick Washroom Equipment, Inc. + +bluetooth:v081D* + ID_VENDOR_FROM_DATABASE=Potrykus Holdings and Development LLC + +bluetooth:v081E* + ID_VENDOR_FROM_DATABASE=iNFORM Technology GmbH + +bluetooth:v081F* + ID_VENDOR_FROM_DATABASE=eSenseLab LTD + +bluetooth:v0820* + ID_VENDOR_FROM_DATABASE=Brilliant Home Technology, Inc. + +bluetooth:v0821* + ID_VENDOR_FROM_DATABASE=INOVA Geophysical, Inc. + +bluetooth:v0822* + ID_VENDOR_FROM_DATABASE=adafruit industries + +bluetooth:v0823* + ID_VENDOR_FROM_DATABASE=Nexite Ltd + +bluetooth:v0824* + ID_VENDOR_FROM_DATABASE=8Power Limited + +bluetooth:v0825* + ID_VENDOR_FROM_DATABASE=CME PTE. LTD. + +bluetooth:v0826* + ID_VENDOR_FROM_DATABASE=Hyundai Motor Company + +bluetooth:v0827* + ID_VENDOR_FROM_DATABASE=Kickmaker + +bluetooth:v0828* + ID_VENDOR_FROM_DATABASE=Shanghai Suisheng Information Technology Co., Ltd. + +bluetooth:v0829* + ID_VENDOR_FROM_DATABASE=HEXAGON + +bluetooth:v082A* + ID_VENDOR_FROM_DATABASE=Mitutoyo Corporation + +bluetooth:v082B* + ID_VENDOR_FROM_DATABASE=shenzhen fitcare electronics Co.,Ltd + +bluetooth:v082C* + ID_VENDOR_FROM_DATABASE=INGICS TECHNOLOGY CO., LTD. + +bluetooth:v082D* + ID_VENDOR_FROM_DATABASE=INCUS PERFORMANCE LTD. + +bluetooth:v082E* + ID_VENDOR_FROM_DATABASE=ABB S.p.A. + +bluetooth:v082F* + ID_VENDOR_FROM_DATABASE=Blippit AB + +bluetooth:v0830* + ID_VENDOR_FROM_DATABASE=Core Health and Fitness LLC + +bluetooth:v0831* + ID_VENDOR_FROM_DATABASE=Foxble, LLC + +bluetooth:v0832* + ID_VENDOR_FROM_DATABASE=Intermotive,Inc. + +bluetooth:v0833* + ID_VENDOR_FROM_DATABASE=Conneqtech B.V. + +bluetooth:v0834* + ID_VENDOR_FROM_DATABASE=RIKEN KEIKI CO., LTD., + +bluetooth:v0835* + ID_VENDOR_FROM_DATABASE=Canopy Growth Corporation + +bluetooth:v0836* + ID_VENDOR_FROM_DATABASE=Bitwards Oy + +bluetooth:v0837* + ID_VENDOR_FROM_DATABASE=vivo Mobile Communication Co., Ltd. + +bluetooth:v0838* + ID_VENDOR_FROM_DATABASE=Etymotic Research, Inc. + +bluetooth:v0839* + ID_VENDOR_FROM_DATABASE=A puissance 3 + +bluetooth:v083A* + ID_VENDOR_FROM_DATABASE=BPW Bergische Achsen Kommanditgesellschaft + +bluetooth:v083B* + ID_VENDOR_FROM_DATABASE=Piaggio Fast Forward + +bluetooth:v083C* + ID_VENDOR_FROM_DATABASE=BeerTech LTD + +bluetooth:v083D* + ID_VENDOR_FROM_DATABASE=Tokenize, Inc. + +bluetooth:v083E* + ID_VENDOR_FROM_DATABASE=Zorachka LTD + +bluetooth:v083F* + ID_VENDOR_FROM_DATABASE=D-Link Corp. + +bluetooth:v0840* + ID_VENDOR_FROM_DATABASE=Down Range Systems LLC + +bluetooth:v0841* + ID_VENDOR_FROM_DATABASE=General Luminaire (Shanghai) Co., Ltd. + +bluetooth:v0842* + ID_VENDOR_FROM_DATABASE=Tangshan HongJia electronic technology co., LTD. + +bluetooth:v0843* + ID_VENDOR_FROM_DATABASE=FRAGRANCE DELIVERY TECHNOLOGIES LTD + +bluetooth:v0844* + ID_VENDOR_FROM_DATABASE=Pepperl + Fuchs GmbH + +bluetooth:v0845* + ID_VENDOR_FROM_DATABASE=Dometic Corporation + +bluetooth:v0846* + ID_VENDOR_FROM_DATABASE=USound GmbH + +bluetooth:v0847* + ID_VENDOR_FROM_DATABASE=DNANUDGE LIMITED + +bluetooth:v0848* + ID_VENDOR_FROM_DATABASE=JUJU JOINTS CANADA CORP. + +bluetooth:v0849* + ID_VENDOR_FROM_DATABASE=Dopple Technologies B.V. + +bluetooth:v084A* + ID_VENDOR_FROM_DATABASE=ARCOM + +bluetooth:v084B* + ID_VENDOR_FROM_DATABASE=Biotechware SRL + +bluetooth:v084C* + ID_VENDOR_FROM_DATABASE=ORSO Inc. + +bluetooth:v084D* + ID_VENDOR_FROM_DATABASE=SafePort + +bluetooth:v084E* + ID_VENDOR_FROM_DATABASE=Carol Cole Company + +bluetooth:v084F* + ID_VENDOR_FROM_DATABASE=Embedded Fitness B.V. + +bluetooth:v0850* + ID_VENDOR_FROM_DATABASE=Yealink (Xiamen) Network Technology Co.,LTD + +bluetooth:v0851* + ID_VENDOR_FROM_DATABASE=Subeca, Inc. + +bluetooth:v0852* + ID_VENDOR_FROM_DATABASE=Cognosos, Inc. + +bluetooth:v0853* + ID_VENDOR_FROM_DATABASE=Pektron Group Limited + +bluetooth:v0854* + ID_VENDOR_FROM_DATABASE=Tap Sound System + +bluetooth:v0855* + ID_VENDOR_FROM_DATABASE=Helios Hockey, Inc. + +bluetooth:v0856* + ID_VENDOR_FROM_DATABASE=Canopy Growth Corporation + +bluetooth:v0857* + ID_VENDOR_FROM_DATABASE=Parsyl Inc + +bluetooth:v0858* + ID_VENDOR_FROM_DATABASE=SOUNDBOKS + +bluetooth:v0859* + ID_VENDOR_FROM_DATABASE=BlueUp + +bluetooth:v085A* + ID_VENDOR_FROM_DATABASE=DAKATECH + +bluetooth:v085B* + ID_VENDOR_FROM_DATABASE=RICOH ELECTRONIC DEVICES CO., LTD. + +bluetooth:v085C* + ID_VENDOR_FROM_DATABASE=ACOS CO.,LTD. + +bluetooth:v085D* + ID_VENDOR_FROM_DATABASE=Guilin Zhishen Information Technology Co.,Ltd. + +bluetooth:v085E* + ID_VENDOR_FROM_DATABASE=Krog Systems LLC + +bluetooth:v085F* + ID_VENDOR_FROM_DATABASE=COMPEGPS TEAM,SOCIEDAD LIMITADA + +bluetooth:v0860* + ID_VENDOR_FROM_DATABASE=Alflex Products B.V. + +bluetooth:v0861* + ID_VENDOR_FROM_DATABASE=SmartSensor Labs Ltd + +bluetooth:v0862* + ID_VENDOR_FROM_DATABASE=SmartDrive Inc. + +bluetooth:v0863* + ID_VENDOR_FROM_DATABASE=Yo-tronics Technology Co., Ltd. + +bluetooth:v0864* + ID_VENDOR_FROM_DATABASE=Rafaelmicro + +bluetooth:v0865* + ID_VENDOR_FROM_DATABASE=Emergency Lighting Products Limited + +bluetooth:v0866* + ID_VENDOR_FROM_DATABASE=LAONZ Co.,Ltd + +bluetooth:v0867* + ID_VENDOR_FROM_DATABASE=Western Digital Techologies, Inc. + +bluetooth:v0868* + ID_VENDOR_FROM_DATABASE=WIOsense GmbH & Co. KG + +bluetooth:v0869* + ID_VENDOR_FROM_DATABASE=EVVA Sicherheitstechnologie GmbH + +bluetooth:v086A* + ID_VENDOR_FROM_DATABASE=Odic Incorporated + +bluetooth:v086B* + ID_VENDOR_FROM_DATABASE=Pacific Track, LLC + +bluetooth:v086C* + ID_VENDOR_FROM_DATABASE=Revvo Technologies, Inc. + +bluetooth:v086D* + ID_VENDOR_FROM_DATABASE=Biometrika d.o.o. + +bluetooth:v086E* + ID_VENDOR_FROM_DATABASE=Vorwerk Elektrowerke GmbH & Co. KG + +bluetooth:v086F* + ID_VENDOR_FROM_DATABASE=Trackunit A/S + +bluetooth:v0870* + ID_VENDOR_FROM_DATABASE=Wyze Labs, Inc + +bluetooth:v0871* + ID_VENDOR_FROM_DATABASE=Dension Elektronikai Kft. (formerly: Dension Audio Systems Ltd.) + +bluetooth:v0872* + ID_VENDOR_FROM_DATABASE=11 Health & Technologies Limited + +bluetooth:v0873* + ID_VENDOR_FROM_DATABASE=Innophase Incorporated + +bluetooth:v0874* + ID_VENDOR_FROM_DATABASE=Treegreen Limited + +bluetooth:v0875* + ID_VENDOR_FROM_DATABASE=Berner International LLC + +bluetooth:v0876* + ID_VENDOR_FROM_DATABASE=SmartResQ ApS + +bluetooth:v0877* + ID_VENDOR_FROM_DATABASE=Tome, Inc. + +bluetooth:v0878* + ID_VENDOR_FROM_DATABASE=The Chamberlain Group, Inc. + +bluetooth:v0879* + ID_VENDOR_FROM_DATABASE=MIZUNO Corporation + +bluetooth:v087A* + ID_VENDOR_FROM_DATABASE=ZRF, LLC + +bluetooth:v087B* + ID_VENDOR_FROM_DATABASE=BYSTAMP + +bluetooth:v087C* + ID_VENDOR_FROM_DATABASE=Crosscan GmbH + +bluetooth:v087D* + ID_VENDOR_FROM_DATABASE=Konftel AB + +bluetooth:v087E* + ID_VENDOR_FROM_DATABASE=1bar.net Limited + +bluetooth:v087F* + ID_VENDOR_FROM_DATABASE=Phillips Connect Technologies LLC + +bluetooth:v0880* + ID_VENDOR_FROM_DATABASE=imagiLabs AB + +bluetooth:v0881* + ID_VENDOR_FROM_DATABASE=Optalert + +bluetooth:v0882* + ID_VENDOR_FROM_DATABASE=PSYONIC, Inc. + +bluetooth:v0883* + ID_VENDOR_FROM_DATABASE=Wintersteiger AG + +bluetooth:v0884* + ID_VENDOR_FROM_DATABASE=Controlid Industria, Comercio de Hardware e Servicos de Tecnologia Ltda + +bluetooth:v0885* + ID_VENDOR_FROM_DATABASE=LEVOLOR, INC. + +bluetooth:v0886* + ID_VENDOR_FROM_DATABASE=Xsens Technologies B.V. + +bluetooth:v0887* + ID_VENDOR_FROM_DATABASE=Hydro-Gear Limited Partnership + +bluetooth:v0888* + ID_VENDOR_FROM_DATABASE=EnPointe Fencing Pty Ltd + +bluetooth:v0889* + ID_VENDOR_FROM_DATABASE=XANTHIO + +bluetooth:v088A* + ID_VENDOR_FROM_DATABASE=sclak s.r.l. + +bluetooth:v088B* + ID_VENDOR_FROM_DATABASE=Tricorder Arraay Technologies LLC + +bluetooth:v088C* + ID_VENDOR_FROM_DATABASE=GB Solution co.,Ltd + +bluetooth:v088D* + ID_VENDOR_FROM_DATABASE=Soliton Systems K.K. + +bluetooth:v088E* + ID_VENDOR_FROM_DATABASE=GIGA-TMS INC + +bluetooth:v088F* + ID_VENDOR_FROM_DATABASE=Tait International Limited + +bluetooth:v0890* + ID_VENDOR_FROM_DATABASE=NICHIEI INTEC CO., LTD. + +bluetooth:v0891* + ID_VENDOR_FROM_DATABASE=SmartWireless GmbH & Co. KG + +bluetooth:v0892* + ID_VENDOR_FROM_DATABASE=Ingenieurbuero Birnfeld UG (haftungsbeschraenkt) + +bluetooth:v0893* + ID_VENDOR_FROM_DATABASE=Maytronics Ltd + +bluetooth:v0894* + ID_VENDOR_FROM_DATABASE=EPIFIT + +bluetooth:v0895* + ID_VENDOR_FROM_DATABASE=Gimer medical + +bluetooth:v0896* + ID_VENDOR_FROM_DATABASE=Nokian Renkaat Oyj + +bluetooth:v0897* + ID_VENDOR_FROM_DATABASE=Current Lighting Solutions LLC + +bluetooth:v0898* + ID_VENDOR_FROM_DATABASE=Sensibo, Inc. + +bluetooth:v0899* + ID_VENDOR_FROM_DATABASE=SFS unimarket AG + +bluetooth:v089A* + ID_VENDOR_FROM_DATABASE=Private limited company "Teltonika" + +bluetooth:v089B* + ID_VENDOR_FROM_DATABASE=Saucon Technologies + +bluetooth:v089C* + ID_VENDOR_FROM_DATABASE=Embedded Devices Co. Company + +bluetooth:v089D* + ID_VENDOR_FROM_DATABASE=J-J.A.D.E. Enterprise LLC + +bluetooth:v089E* + ID_VENDOR_FROM_DATABASE=i-SENS, inc. + +bluetooth:v089F* + ID_VENDOR_FROM_DATABASE=Witschi Electronic Ltd + +bluetooth:v08A0* + ID_VENDOR_FROM_DATABASE=Aclara Technologies LLC + +bluetooth:v08A1* + ID_VENDOR_FROM_DATABASE=EXEO TECH CORPORATION + +bluetooth:v08A2* + ID_VENDOR_FROM_DATABASE=Epic Systems Co., Ltd. + +bluetooth:v08A3* + ID_VENDOR_FROM_DATABASE=Hoffmann SE + +bluetooth:v08A4* + ID_VENDOR_FROM_DATABASE=Realme Chongqing Mobile Telecommunications Corp., Ltd. + +bluetooth:v08A5* + ID_VENDOR_FROM_DATABASE=UMEHEAL Ltd + +bluetooth:v08A6* + ID_VENDOR_FROM_DATABASE=Intelligenceworks Inc. + +bluetooth:v08A7* + ID_VENDOR_FROM_DATABASE=TGR 1.618 Limited + +bluetooth:v08A8* + ID_VENDOR_FROM_DATABASE=Shanghai Kfcube Inc + +bluetooth:v08A9* + ID_VENDOR_FROM_DATABASE=Fraunhofer IIS + +bluetooth:v08AA* + ID_VENDOR_FROM_DATABASE=SZ DJI TECHNOLOGY CO.,LTD + +bluetooth:v08AB* + ID_VENDOR_FROM_DATABASE=Coburn Technology, LLC + +bluetooth:v08AC* + ID_VENDOR_FROM_DATABASE=Topre Corporation + +bluetooth:v08AD* + ID_VENDOR_FROM_DATABASE=Kayamatics Limited + +bluetooth:v08AE* + ID_VENDOR_FROM_DATABASE=Moticon ReGo AG diff --git a/hwdb.d/60-evdev.hwdb b/hwdb.d/60-evdev.hwdb index 5d4ff8bc93..1ab0f01584 100644 --- a/hwdb.d/60-evdev.hwdb +++ b/hwdb.d/60-evdev.hwdb @@ -572,6 +572,24 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn870Z5E/ EVDEV_ABS_36=::29 ######################################### +# Star Labs +######################################### + +# Star LabTop Mk III +evdev:name:ALPS0001:00 0911:5288 Touchpad:dmi:*svnStarLabs:pnLabTop* + EVDEV_ABS_00=0:2627:25 + EVDEV_ABS_01=0:1331:20 + EVDEV_ABS_35=0:2627:25 + EVDEV_ABS_36=0:1331:20 + +# Star Lite Mk II +evdev:name:ALPS0001:00 0911:5288 Touchpad:dmi:*svnStarLabs:pnLite:* + EVDEV_ABS_00=55:1750:16 + EVDEV_ABS_01=51:950:15 + EVDEV_ABS_35=55:1750:16 + EVDEV_ABS_36=51:950:15 + +######################################### # System76 ######################################### diff --git a/hwdb.d/60-keyboard.hwdb b/hwdb.d/60-keyboard.hwdb index 176ec3836a..ee335c8c11 100644 --- a/hwdb.d/60-keyboard.hwdb +++ b/hwdb.d/60-keyboard.hwdb @@ -160,6 +160,11 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*8930:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*7750G:pvr* KEYBOARD_KEY_e0=!pageup +# Predator PH 315-52 +evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredator*PH*315-52:pvr* + KEYBOARD_KEY_ef=kbdillumup # Fn+F10 + KEYBOARD_KEY_f0=kbdillumdown # Fn+F9 + # Travelmate C300 evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:pvr* KEYBOARD_KEY_67=f24 # FIXME: rotate screen diff --git a/hwdb.d/60-sensor.hwdb b/hwdb.d/60-sensor.hwdb index abedbaca81..3b6d98f0bf 100644 --- a/hwdb.d/60-sensor.hwdb +++ b/hwdb.d/60-sensor.hwdb @@ -249,6 +249,10 @@ sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t* sensor:modalias:platform:HID-SENSOR-200073:dmi:*svnDell*:pnVostro5581:* ACCEL_LOCATION=base +# Dell Venue 8 Pro 3845 +sensor:modalias:acpi:INVN6500*:dmi:*svnDellInc.*:pnVenue8Pro3845* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + # Dell Venue 10 Pro 5055 sensor:modalias:acpi:INVN6500*:dmi:*svnDell*:pnVenue10Pro5055* ACCEL_MOUNT_MATRIX=0, -1, 0; 1, 0, 0; 0, 0, 1 @@ -407,6 +411,10 @@ sensor:modalias:acpi:SMO8500*:dmi:bvnLENOVO:*:pvrLenovoMIIX3-830:* sensor:modalias:acpi:BOSC0200*:dmi:*:svnLENOVO:pn81H3:* ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 +# IdeaPad Miix 300 +sensor:modalias:acpi:SMO8500*:dmi:bvnLENOVO:*:pvrMIIX300-* + ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 + # IdeaPad Miix 310 note this only is for BIOS version (bvr) 1HCN4?WW and 1HCN2?WW, which has # a portrait LCD panel, versions with bvr 1HCN3?WW have a landscape panel sensor:modalias:acpi:KIOX000A*:dmi:bvnLENOVO:bvr1HCN4?WW:*:svnLENOVO:pn80SG:* @@ -462,6 +470,12 @@ sensor:modalias:acpi:KIOX010A*:dmi:*:svnMEDION:pnMEDION*:* ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ######################################### +# MPMAN +######################################### +sensor:modalias:acpi:BMA250E*:dmi:*:svnMPMAN:pnMPWIN8900CL:* + ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 + +######################################### # MSI ######################################### sensor:modalias:acpi:SMO8500*:dmi:*:svnMicro-StarInternationalCo.,Ltd.:pnS100:* diff --git a/man/custom-entities.ent.in b/man/custom-entities.ent.in index 85805777a0..84a29f5de4 100644 --- a/man/custom-entities.ent.in +++ b/man/custom-entities.ent.in @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" ?> <!ENTITY MOUNT_PATH @MOUNT_PATH@> <!ENTITY UMOUNT_PATH @UMOUNT_PATH@> -<!ENTITY systemgeneratordir @SYSTEM_GENERATOR_PATH@> -<!ENTITY usergeneratordir @USER_GENERATOR_PATH@> -<!ENTITY systemenvgeneratordir @SYSTEM_ENV_GENERATOR_PATH@> -<!ENTITY userenvgeneratordir @USER_ENV_GENERATOR_PATH@> +<!ENTITY systemgeneratordir @SYSTEM_GENERATOR_DIR@> +<!ENTITY usergeneratordir @USER_GENERATOR_DIR@> +<!ENTITY systemenvgeneratordir @SYSTEM_ENV_GENERATOR_DIR@> +<!ENTITY userenvgeneratordir @USER_ENV_GENERATOR_DIR@> <!ENTITY CERTIFICATE_ROOT @CERTIFICATE_ROOT@> <!ENTITY MEMORY_ACCOUNTING_DEFAULT @MEMORY_ACCOUNTING_DEFAULT_YES_NO@> <!ENTITY KILL_USER_PROCESSES @KILL_USER_PROCESSES_YES_NO@> diff --git a/man/html.in b/man/html.in index bc9a668c23..c09d300d6f 100755 --- a/man/html.in +++ b/man/html.in @@ -6,6 +6,9 @@ if [ -z "$1" ]; then exit 1 fi +# make sure the rules have been regenrated (in case man/update-man-rules was just run) +ninja -C "@BUILD_ROOT@" version.h + target="man/$1.html" ninja -C "@BUILD_ROOT@" "$target" set -x diff --git a/man/journalctl.xml b/man/journalctl.xml index 2a685d1ee6..1e5f95e19d 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -398,8 +398,8 @@ <varlistentry> <term><option>--output-fields=</option></term> - <listitem><para>A comma separated list of the fields which should be included in the output. This only has an - effect for the output modes which would normally show all fields (<option>verbose</option>, + <listitem><para>A comma separated list of the fields which should be included in the output. This has an + effect only for the output modes which would normally show all fields (<option>verbose</option>, <option>export</option>, <option>json</option>, <option>json-pretty</option>, <option>json-sse</option> and <option>json-seq</option>). The <literal>__CURSOR</literal>, <literal>__REALTIME_TIMESTAMP</literal>, <literal>__MONOTONIC_TIMESTAMP</literal>, and <literal>_BOOT_ID</literal> fields are always @@ -416,8 +416,13 @@ <varlistentry> <term><option>--no-hostname</option></term> - <listitem><para>Don't show the hostname field of log messages originating from the local host. This switch only - has an effect on the <option>short</option> family of output modes (see above).</para></listitem> + <listitem><para>Don't show the hostname field of log messages originating from the local host. This + switch has an effect only on the <option>short</option> family of output modes (see above). + </para> + + <para>Note: this option does not remove occurrences of the hostname from log entries themselves, so + it does not prevent the hostname from being visible in the logs.</para> + </listitem> </varlistentry> <varlistentry> diff --git a/man/man.in b/man/man.in index 75680b860c..812c6767fc 100755 --- a/man/man.in +++ b/man/man.in @@ -6,6 +6,9 @@ if [ -z "$1" ]; then exit 1 fi +# make sure the rules have been regenrated (in case man/update-man-rules was just run) +ninja -C "@BUILD_ROOT@" version.h + page="$(echo "$1" | sed 's/\./\\./')" target=$(ninja -C "@BUILD_ROOT@" -t query man/man | grep -E -m1 "man/$page\.[0-9]$" | awk '{print $2}') if [ -z "$target" ]; then diff --git a/man/networkctl.xml b/man/networkctl.xml index 4906f7a330..a6bc61a44f 100644 --- a/man/networkctl.xml +++ b/man/networkctl.xml @@ -261,6 +261,20 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR) <varlistentry> <term> + <command>up</command> + </term> + <listitem><para>Bring devices up. Takes interface name or index number.</para></listitem> + </varlistentry> + + <varlistentry> + <term> + <command>down</command> + </term> + <listitem><para>Bring devices down. Takes interface name or index number.</para></listitem> + </varlistentry> + + <varlistentry> + <term> <command>renew</command> </term> <listitem><para>Renew dynamic configurations e.g. addresses received from DHCP server. diff --git a/man/path-documents.c b/man/path-documents.c new file mode 100644 index 0000000000..a6c1f9371a --- /dev/null +++ b/man/path-documents.c @@ -0,0 +1,9 @@ +#include <stdio.h> +#include <sd-path.h> + +int main(void) { + char *t; + + sd_path_lookup(SD_PATH_USER_DOCUMENTS, NULL, &t); + printf("~/Documents: %s\n", t); +} diff --git a/man/rules/meson.build b/man/rules/meson.build index b95ef6964a..16e0ffca3f 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -121,7 +121,7 @@ manpages = [ 'sd_bus_match_signal', 'sd_bus_match_signal_async'], ''], - ['sd_bus_add_object_vtable', + ['sd_bus_add_object', '3', ['SD_BUS_METHOD', 'SD_BUS_METHOD_WITH_NAMES', @@ -134,11 +134,18 @@ manpages = [ 'SD_BUS_VTABLE_END', 'SD_BUS_VTABLE_START', 'SD_BUS_WRITABLE_PROPERTY', - 'sd_bus_add_fallback_vtable'], + 'sd_bus_add_fallback', + 'sd_bus_add_fallback_vtable', + 'sd_bus_add_object_vtable'], ''], ['sd_bus_attach_event', '3', ['sd_bus_detach_event', 'sd_bus_get_event'], ''], ['sd_bus_call', '3', ['sd_bus_call_async'], ''], - ['sd_bus_call_method', '3', ['sd_bus_call_method_async'], ''], + ['sd_bus_call_method', + '3', + ['sd_bus_call_method_async', + 'sd_bus_call_method_asyncv', + 'sd_bus_call_methodv'], + ''], ['sd_bus_close', '3', ['sd_bus_default_flush_close', 'sd_bus_flush'], ''], ['sd_bus_creds_get_pid', '3', @@ -323,9 +330,11 @@ manpages = [ '3', ['sd_bus_reply_method_errno', 'sd_bus_reply_method_errnof', - 'sd_bus_reply_method_errorf'], + 'sd_bus_reply_method_errnofv', + 'sd_bus_reply_method_errorf', + 'sd_bus_reply_method_errorfv'], ''], - ['sd_bus_reply_method_return', '3', [], ''], + ['sd_bus_reply_method_return', '3', ['sd_bus_reply_method_returnv'], ''], ['sd_bus_request_name', '3', ['sd_bus_release_name', @@ -352,10 +361,13 @@ manpages = [ ''], ['sd_bus_set_sender', '3', ['sd_bus_get_sender'], ''], ['sd_bus_set_watch_bind', '3', ['sd_bus_get_watch_bind'], ''], - ['sd_bus_slot_ref', + ['sd_bus_slot_get_bus', '3', - ['sd_bus_slot_get_bus', 'sd_bus_slot_unref', 'sd_bus_slot_unrefp'], + ['sd_bus_slot_get_current_handler', + 'sd_bus_slot_get_current_message', + 'sd_bus_slot_get_current_userdata'], ''], + ['sd_bus_slot_ref', '3', ['sd_bus_slot_unref', 'sd_bus_slot_unrefp'], ''], ['sd_bus_slot_set_description', '3', ['sd_bus_slot_get_description'], ''], ['sd_bus_slot_set_destroy_callback', '3', @@ -623,6 +635,7 @@ manpages = [ '3', ['sd_notifyf', 'sd_pid_notify', 'sd_pid_notify_with_fds', 'sd_pid_notifyf'], ''], + ['sd_path_lookup', '3', ['sd_path_lookup_strv'], ''], ['sd_pid_get_owner_uid', '3', ['sd_peer_get_cgroup', diff --git a/man/sd-bus.xml b/man/sd-bus.xml index e11e6ec794..4f1d8355d6 100644 --- a/man/sd-bus.xml +++ b/man/sd-bus.xml @@ -41,7 +41,10 @@ <para>See <literallayout><citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_add_object</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_add_object_vtable</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_add_fallback</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_add_fallback_vtable</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_attach_event</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_call</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_call_async</refentrytitle><manvolnum>3</manvolnum></citerefentry>, @@ -67,6 +70,7 @@ <citerefentry><refentrytitle>sd_bus_message_dump</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_get_cookie</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_get_monotonic_usec</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_message_get_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_get_signature</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_get_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>, @@ -79,6 +83,7 @@ <citerefentry><refentrytitle>sd_bus_message_rewind</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_seal</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_message_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_set_expect_reply</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_skip</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_message_verify_type</refentrytitle><manvolnum>3</manvolnum></citerefentry>, @@ -96,7 +101,10 @@ <citerefentry><refentrytitle>sd_bus_set_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_set_sender</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_set_watch_bind</refentrytitle><manvolnum>3</manvolnum></citerefentry> -<citerefentry><refentrytitle>sd_bus_set_close_on_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry> +<citerefentry><refentrytitle>sd_bus_set_close_on_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_slot_get_current_handler</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_slot_get_current_message</refentrytitle><manvolnum>3</manvolnum></citerefentry>, +<citerefentry><refentrytitle>sd_bus_slot_get_current_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_slot_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_slot_set_destroy_callback</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_bus_slot_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>, diff --git a/man/sd-daemon.xml b/man/sd-daemon.xml index 84deda188d..64ed5f3779 100644 --- a/man/sd-daemon.xml +++ b/man/sd-daemon.xml @@ -68,16 +68,14 @@ #define SD_INFO "<6>" /* informational */ #define SD_DEBUG "<7>" /* debug-level messages */</programlisting> - <para>These prefixes are intended to be used in conjunction with - stderr-based logging as implemented by systemd. If a systemd - service definition file is configured with - <varname>StandardError=journal</varname>, - <varname>StandardError=syslog</varname> or - <varname>StandardError=kmsg</varname>, these prefixes can be used - to encode a log level in lines printed. This is similar to the - kernel <function>printk()</function>-style logging. See - <citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> - for more information.</para> + <para>These prefixes are intended to be used in conjunction with stderr-based logging (or stdout-based + logging) as implemented by systemd. If a systemd service definition file is configured with + <varname>StandardError=journal</varname>, <varname>StandardError=syslog</varname> or + <varname>StandardError=kmsg</varname> (and similar with <varname>StandardOutput=</varname>), these + prefixes can be used to encode a log level in lines printed. This is similar to the kernel + <function>printk()</function>-style logging. See + <citerefentry><refentrytitle>klogctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> for more + information.</para> <para>The log levels are identical to <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s diff --git a/man/sd_bus_add_object_vtable.xml b/man/sd_bus_add_object.xml index 9d7e30a504..2abe2342f0 100644 --- a/man/sd_bus_add_object_vtable.xml +++ b/man/sd_bus_add_object.xml @@ -3,20 +3,22 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <!-- SPDX-License-Identifier: LGPL-2.1+ --> -<refentry id="sd_bus_add_object_vtable" +<refentry id="sd_bus_add_object" xmlns:xi="http://www.w3.org/2001/XInclude"> <refentryinfo> - <title>sd_bus_add_object_vtable</title> + <title>sd_bus_add_object</title> <productname>systemd</productname> </refentryinfo> <refmeta> - <refentrytitle>sd_bus_add_object_vtable</refentrytitle> + <refentrytitle>sd_bus_add_object</refentrytitle> <manvolnum>3</manvolnum> </refmeta> <refnamediv> + <refname>sd_bus_add_object</refname> + <refname>sd_bus_add_fallback</refname> <refname>sd_bus_add_object_vtable</refname> <refname>sd_bus_add_fallback_vtable</refname> <refname>SD_BUS_VTABLE_START</refname> @@ -77,6 +79,24 @@ </funcprototype> <funcprototype> + <funcdef>int <function>sd_bus_add_object</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_add_fallback</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + </funcprototype> + + <funcprototype> <funcdef>int <function>sd_bus_add_object_vtable</function></funcdef> <paramdef>sd_bus *<parameter>bus</parameter></paramdef> <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> @@ -188,40 +208,82 @@ <refsect1> <title>Description</title> - <para><function>sd_bus_add_object_vtable()</function> is used to declare attributes for the path object - path <parameter>path</parameter> connected to the bus connection <parameter>bus</parameter> under the - interface <parameter>interface</parameter>. The table <parameter>vtable</parameter> may contain property - declarations using <constant>SD_BUS_PROPERTY()</constant> or - <constant>SD_BUS_WRITABLE_PROPERTY()</constant>, method declarations using - <constant>SD_BUS_METHOD()</constant>, <constant>SD_BUS_METHOD_WITH_NAMES()</constant>, + <para><function>sd_bus_add_object_vtable()</function> is used to declare attributes for the + object path <parameter>path</parameter> connected to the bus connection + <parameter>bus</parameter> under the interface <parameter>interface</parameter>. The table + <parameter>vtable</parameter> may contain property declarations using + <constant>SD_BUS_PROPERTY()</constant> or <constant>SD_BUS_WRITABLE_PROPERTY()</constant>, + method declarations using <constant>SD_BUS_METHOD()</constant>, + <constant>SD_BUS_METHOD_WITH_NAMES()</constant>, <constant>SD_BUS_METHOD_WITH_OFFSET()</constant>, or <constant>SD_BUS_METHOD_WITH_NAMES_OFFSET()</constant>, and signal declarations using - <constant>SD_BUS_SIGNAL_WITH_NAMES()</constant> or <constant>SD_BUS_SIGNAL()</constant>, see below. The - <replaceable>userdata</replaceable> parameter contains a pointer that will be passed to various callback - functions. It may be specified as <constant>NULL</constant> if no value is necessary.</para> + <constant>SD_BUS_SIGNAL_WITH_NAMES()</constant> or <constant>SD_BUS_SIGNAL()</constant>, see + below. The <replaceable>userdata</replaceable> parameter contains a pointer that will be passed + to various callback functions. It may be specified as <constant>NULL</constant> if no value is + necessary. An interface can have any number of vtables attached to it.</para> <para><function>sd_bus_add_fallback_vtable()</function> is similar to - <function>sd_bus_add_object_vtable()</function>, but is used to register "fallback" attributes. When - looking for an attribute declaration, bus object paths registered with - <function>sd_bus_add_object_vtable()</function> are checked first. If no match is found, the fallback - vtables are checked for each prefix of the bus object path, i.e. with the last slash-separated components - successively removed. This allows the vtable to be used for an arbitrary number of dynamically created - objects.</para> - - <para>Parameter <replaceable>find</replaceable> is a function which is used to locate the target object - based on the bus object path <replaceable>path</replaceable>. It must return <constant>1</constant> and - set the <parameter>ret_found</parameter> output parameter if the object is found, return - <constant>0</constant> if the object was not found, and return a negative errno-style error code or - initialize the error structure <replaceable>ret_error</replaceable> on error. The pointer passed in - <parameter>ret_found</parameter> will be used as the <parameter>userdata</parameter> parameter for the - callback functions (offset by the <parameter>offset</parameter> offsets as specified in the vtable - entries).</para> - - <para>For both functions, a match slot is created internally. If the output parameter - <replaceable>slot</replaceable> is <constant>NULL</constant>, a "floating" slot object is created, see + <function>sd_bus_add_object_vtable()</function>, but is used to register "fallback" attributes. + When looking for an attribute declaration, bus object paths registered with + <function>sd_bus_add_object_vtable()</function> are checked first. If no match is found, the + fallback vtables are checked for each prefix of the bus object path, i.e. with the last + slash-separated components successively removed. This allows the vtable to be used for an + arbitrary number of dynamically created objects.</para> + + <para>Parameter <replaceable>find</replaceable> is a function which is used to locate the target + object based on the bus object path <replaceable>path</replaceable>. It must return + <constant>1</constant> and set the <parameter>ret_found</parameter> output parameter if the + object is found, return <constant>0</constant> if the object was not found, and return a + negative errno-style error code or initialize the error structure + <replaceable>ret_error</replaceable> on error. The pointer passed in + <parameter>ret_found</parameter> will be used as the <parameter>userdata</parameter> parameter + for the callback functions (offset by the <parameter>offset</parameter> offsets as specified in + the vtable entries).</para> + + <para><function>sd_bus_add_object()</function> attaches a callback directly to the object path + <parameter>path</parameter>. An object path can have any number of callbacks attached to it. + Each callback is prepended to the list of callbacks which are always called in order. + <function>sd_bus_add_fallback()</function> is similar to + <function>sd_bus_add_object()</function> but applies to fallback paths instead.</para> + + <para>When a request is received, any associated callbacks are called sequentially until a + callback returns a non-zero integer. Return zero from a callback to give other callbacks the + chance to process the request. Callbacks are called in the following order: first, callbacks + attached directly to the request object path are called, followed by any D-Bus method callbacks + attached to the request object path, interface and member. Finally, the property callbacks + attached to the request object path, interface and member are called. If the final callback + returns zero, an error reply is sent back to the caller indicating no matching object for the + request was found. Note that you can return a positive integer from a callback without + immediately sending a reply. This informs sd-bus this callback will take responsibility for + replying to the request without forcing the callback to produce a reply immediately. This allows + a callback to perform any number of asynchronous operations required to construct a reply. Note + that if producing a reply takes too long, the method call will time out at the caller.</para> + + <para>If a callback was invoked to handle a request that expects a reply and the callback + returns a negative value, the value is interpreted as a negative errno-style error code and sent + back to the caller as a D-Bus error as if + <citerefentry><refentrytitle>sd_bus_reply_method_errno</refentrytitle><manvolnum>3</manvolnum></citerefentry> + was called. Additionally, all callbacks take a <structname>sd_bus_error</structname> output + parameter that can be used to provide more detailed error information. If + <parameter>ret_error</parameter> is set when the callback finishes, the corresponding D-Bus + error is sent back to the caller as if + <citerefentry><refentrytitle>sd_bus_reply_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry> + was called. Any error stored in <parameter>ret_error</parameter> takes priority over any + negative values returned by the same callback when determining which error to send back to + the caller. Use + <citerefentry><refentrytitle>sd_bus_error_set</refentrytitle><manvolnum>3</manvolnum></citerefentry> + or one of its variants to set <parameter>ret_error</parameter> and return a negative integer + from a callback with a single function call. To send an error reply after a callback has already + finished, use + <citerefentry><refentrytitle>sd_bus_reply_method_errno</refentrytitle><manvolnum>3</manvolnum></citerefentry> + or one of its variants.</para> + + <para>For all functions, a match slot is created internally. If the output parameter + <replaceable>slot</replaceable> is <constant>NULL</constant>, a "floating" slot object is + created, see <citerefentry><refentrytitle>sd_bus_slot_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>. - Otherwise, a pointer to the slot object is returned. In that case, the reference to the slot object - should be dropped when the vtable is not needed anymore, see + Otherwise, a pointer to the slot object is returned. In that case, the reference to the slot + object should be dropped when the vtable is not needed anymore, see <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>. </para> @@ -245,23 +307,28 @@ <term><constant>SD_BUS_METHOD_WITH_OFFSET()</constant></term> <term><constant>SD_BUS_METHOD()</constant></term> - <listitem><para>Declare a D-Bus method with the name <replaceable>member</replaceable>, parameter - signature <replaceable>signature</replaceable>, result signature <replaceable>result</replaceable>. - Parameters <replaceable>in_names</replaceable> and <replaceable>out_names</replaceable> specify the - argument names of the input and output arguments in the function signature. The handler function - <replaceable>handler</replaceable> must be of type <function>sd_bus_message_handler_t</function>. - It will be called to handle the incoming messages that call this method. It receives a pointer that - is the <replaceable>userdata</replaceable> parameter passed to the registration function offset by - <replaceable>offset</replaceable> bytes. This may be used to pass pointers to different fields in - the same data structure to different methods in the same - vtable. <replaceable>in_names</replaceable> and <replaceable>out_names</replaceable> should be - created using the <constant>SD_BUS_PARAM()</constant> macro, see below. Parameter + <listitem><para>Declare a D-Bus method with the name <replaceable>member</replaceable>, + parameter signature <replaceable>signature</replaceable>, result signature + <replaceable>result</replaceable>. Parameters <replaceable>in_names</replaceable> and + <replaceable>out_names</replaceable> specify the argument names of the input and output + arguments in the function signature. The handler function + <replaceable>handler</replaceable> must be of type + <function>sd_bus_message_handler_t</function>. It will be called to handle the incoming + messages that call this method. It receives a pointer that is the + <replaceable>userdata</replaceable> parameter passed to the registration function offset + by <replaceable>offset</replaceable> bytes. This may be used to pass pointers to different + fields in the same data structure to different methods in the same vtable. To send a reply + from <parameter>handler</parameter>, call + <citerefentry><refentrytitle>sd_bus_reply_method_return</refentrytitle><manvolnum>3</manvolnum></citerefentry> + with the message the callback was invoked with. <replaceable>in_names</replaceable> and + <replaceable>out_names</replaceable> should be created using the + <constant>SD_BUS_PARAM()</constant> macro, see below. Parameter <replaceable>flags</replaceable> is a combination of flags, see below.</para> <para><constant>SD_BUS_METHOD_WITH_NAMES()</constant>, - <constant>SD_BUS_METHOD_WITH_OFFSET()</constant>, and <constant>SD_BUS_METHOD()</constant> are - variants which specify zero offset (<replaceable>userdata</replaceable> parameter is passed with - no change), leave the names unset (i.e. no parameter names), or both.</para> + <constant>SD_BUS_METHOD_WITH_OFFSET()</constant>, and <constant>SD_BUS_METHOD()</constant> + are variants which specify zero offset (<replaceable>userdata</replaceable> parameter is + passed with no change), leave the names unset (i.e. no parameter names), or both.</para> </listitem> </varlistentry> @@ -285,29 +352,31 @@ <term><constant>SD_BUS_WRITABLE_PROPERTY()</constant></term> <term><constant>SD_BUS_PROPERTY()</constant></term> - <listitem><para>Declare a D-Bus property with the name <replaceable>member</replaceable> and value - signature <replaceable>signature</replaceable>. Parameters <replaceable>get</replaceable> and - <replaceable>set</replaceable> are the getter and setter methods. They are called with a pointer - that is the <replaceable>userdata</replaceable> parameter passed to the registration function - offset by <replaceable>offset</replaceable> bytes. This may be used pass pointers to different - fields in the same data structure to different setters and getters in the same vtable. Parameter - <replaceable>flags</replaceable> is a combination of flags, see below.</para> - - <para>The setter and getter methods may be omitted (specified as <constant>NULL</constant>), if the - property has one of the basic types or <literal>as</literal> in case of read-only properties. In - those cases, the <replaceable>userdata</replaceable> and <replaceable>offset</replaceable> - parameters must together point to valid variable of the corresponding type. A default setter and - getters will be provided, which simply copy the argument between this variable and the message. + <listitem><para>Declare a D-Bus property with the name <replaceable>member</replaceable> + and value signature <replaceable>signature</replaceable>. Parameters + <replaceable>get</replaceable> and <replaceable>set</replaceable> are the getter and + setter methods. They are called with a pointer that is the + <replaceable>userdata</replaceable> parameter passed to the registration function offset + by <replaceable>offset</replaceable> bytes. This may be used pass pointers to different + fields in the same data structure to different setters and getters in the same vtable. + Parameter <replaceable>flags</replaceable> is a combination of flags, see below.</para> + + <para>The setter and getter methods may be omitted (specified as + <constant>NULL</constant>), if the property is one of the basic types or + <literal>as</literal> in case of read-only properties. In those cases, the + <replaceable>userdata</replaceable> and <replaceable>offset</replaceable> parameters must + together point to a valid variable of the corresponding type. A default setter and getter + will be provided, which simply copy the argument between this variable and the message. </para> - <para><constant>SD_BUS_PROPERTY()</constant> is used to define a read-only property.</para> - </listitem> + <para><constant>SD_BUS_PROPERTY()</constant> is used to define a read-only property. + </para></listitem> </varlistentry> <varlistentry> <term><constant>SD_BUS_PARAM()</constant></term> - <listitem><para>Parameter names should be wrapped in this macro, see the example below.</para> - </listitem> + <listitem><para>Parameter names should be wrapped in this macro, see the example below. + </para></listitem> </varlistentry> </variablelist> </refsect2> @@ -324,7 +393,7 @@ <term><constant>SD_BUS_VTABLE_DEPRECATED</constant></term> <listitem><para>Mark this vtable entry as deprecated using the - <constant>org.freedesktop.DBus.Deprecated</constant> annotation in introspection data. If + <constant>org.freedesktop.DBus.Deprecated</constant> annotation in introspection data. If specified for <constant>SD_BUS_VTABLE_START()</constant>, the annotation is applied to the enclosing interface.</para></listitem> </varlistentry> @@ -332,10 +401,9 @@ <varlistentry> <term><constant>SD_BUS_VTABLE_HIDDEN</constant></term> - <listitem><para>Make this vtable entry hidden. It will not be shown in introspection data. If - specified for <constant>SD_BUS_VTABLE_START()</constant>, all entries in the array are hidden. - </para> - </listitem> + <listitem><para>Make this vtable entry hidden. It will not be shown in introspection data. + If specified for <constant>SD_BUS_VTABLE_START()</constant>, all entries in the array are + hidden.</para></listitem> </varlistentry> <varlistentry> @@ -343,8 +411,7 @@ <listitem><para>Mark this vtable entry as unprivileged. If not specified, the <constant>org.freedesktop.systemd1.Privileged</constant> annotation with value - <literal>true</literal> will be shown in introspection data.</para> - </listitem> + <literal>true</literal> will be shown in introspection data.</para></listitem> </varlistentry> <varlistentry> @@ -361,27 +428,28 @@ <term><constant>SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION</constant></term> <listitem><para>Those three flags correspond to different values of the - <constant>org.freedesktop.DBus.Property.EmitsChangedSignal</constant> annotation, which specifies - whether the <constant>org.freedesktop.DBus.Properties.PropertiesChanged</constant> signal is - emitted whenever the property changes. <constant>SD_BUS_VTABLE_PROPERTY_CONST</constant> corresponds to - <constant>const</constant> and means that the property never changes during the lifetime of the - object it belongs to, so no signal needs to be emitted. - <constant>SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE</constant> corresponds to <constant>true</constant> and means - that the signal is emitted. <constant>SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION</constant> corresponds to - <constant>invalidates</constant> and means that the signal is emitted, but the value is not included - in the signal.</para> - </listitem> + <constant>org.freedesktop.DBus.Property.EmitsChangedSignal</constant> annotation, which + specifies whether the + <constant>org.freedesktop.DBus.Properties.PropertiesChanged</constant> signal is emitted + whenever the property changes. <constant>SD_BUS_VTABLE_PROPERTY_CONST</constant> + corresponds to <constant>const</constant> and means that the property never changes during + the lifetime of the object it belongs to, so no signal needs to be emitted. + <constant>SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE</constant> corresponds to + <constant>true</constant> and means that the signal is emitted. + <constant>SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION</constant> corresponds to + <constant>invalidates</constant> and means that the signal is emitted, but the value is + not included in the signal.</para></listitem> </varlistentry> <varlistentry> <term><constant>SD_BUS_VTABLE_PROPERTY_EXPLICIT</constant></term> - <listitem><para>Mark this vtable property entry as requiring explicit request to for the value to - be shown (generally because the value is large or slow to calculate). This entry cannot be combined - with <constant>SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE</constant>, and will not be shown in property listings by - default (e.g. <command>busctl introspect</command>). This corresponds to the - <constant>org.freedesktop.systemd1.Explicit</constant> annotation in introspection data.</para> - </listitem> + <listitem><para>Mark this vtable property entry as requiring explicit request to for the + value to be shown (generally because the value is large or slow to calculate). This entry + cannot be combined with <constant>SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE</constant>, and will + not be shown in property listings by default (e.g. <command>busctl introspect</command>). + This corresponds to the <constant>org.freedesktop.systemd1.Explicit</constant> annotation + in introspection data.</para></listitem> </varlistentry> </variablelist> </refsect2> @@ -395,9 +463,9 @@ <programlisting><xi:include href="vtable-example.c" parse="text" /></programlisting> - <para>This creates a simple client on the bus (the user bus, when run as normal user). - We may use the D-Bus <constant>org.freedesktop.DBus.Introspectable.Introspect</constant> - call to acquire the XML description of the interface:</para> + <para>This creates a simple client on the bus (the user bus, when run as normal user). We may + use the D-Bus <constant>org.freedesktop.DBus.Introspectable.Introspect</constant> call to + acquire the XML description of the interface:</para> <programlisting><xi:include href="vtable-example.xml" parse="text" /></programlisting> </example> @@ -407,8 +475,8 @@ <title>Return Value</title> <para>On success, <function>sd_bus_add_object_vtable</function> and - <function>sd_bus_add_fallback_vtable</function> calls return 0 or a positive integer. On failure, they - return a negative errno-style error code.</para> + <function>sd_bus_add_fallback_vtable</function> calls return 0 or a positive integer. On + failure, they return a negative errno-style error code.</para> <refsect2> <title>Errors</title> @@ -419,8 +487,9 @@ <varlistentry> <term><constant>-EINVAL</constant></term> - <listitem><para>One of the required parameters is <constant>NULL</constant> or invalid. A reserved - D-Bus interface was passed as the <replaceable>interface</replaceable> parameter.</para></listitem> + <listitem><para>One of the required parameters is <constant>NULL</constant> or invalid. A + reserved D-Bus interface was passed as the <replaceable>interface</replaceable> parameter. + </para></listitem> </varlistentry> <varlistentry> @@ -445,8 +514,8 @@ <term><constant>-EPROTOTYPE</constant></term> <listitem><para><function>sd_bus_add_object_vtable</function> and - <function>sd_bus_add_fallback_vtable</function> have been both called - for the same bus object path, which is not allowed.</para></listitem> + <function>sd_bus_add_fallback_vtable</function> have been both called for the same bus + object path, which is not allowed.</para></listitem> </varlistentry> <varlistentry> diff --git a/man/sd_bus_call.xml b/man/sd_bus_call.xml index f2d725a29f..93462f24b5 100644 --- a/man/sd_bus_call.xml +++ b/man/sd_bus_call.xml @@ -52,34 +52,39 @@ <title>Description</title> <para><function>sd_bus_call()</function> takes a complete bus message object and calls the - corresponding D-Bus method. The response is stored in <parameter>reply</parameter>. + corresponding D-Bus method. On success, the response is stored in <parameter>reply</parameter>. <parameter>usec</parameter> indicates the timeout in microseconds. If <parameter>ret_error</parameter> is not <constant>NULL</constant> and - <function>sd_bus_call()</function> returns an error, <parameter>ret_error</parameter> is - initialized to an instance of <structname>sd_bus_error</structname> describing the error.</para> + <function>sd_bus_call()</function> fails (either because of an internal error or because it + received a D-Bus error reply), <parameter>ret_error</parameter> is initialized to an instance of + <structname>sd_bus_error</structname> describing the error.</para> <para><function>sd_bus_call_async()</function> is like <function>sd_bus_call()</function> but - works asynchronously. The <parameter>callback</parameter> shall reference a function to call - when the event source is triggered. The <parameter>userdata</parameter> pointer will be passed - to the callback function, and may be chosen freely by the caller. If <parameter>slot</parameter> - is not <constant>NULL</constant> and <function>sd_bus_call_async()</function> succeeds, + works asynchronously. The <parameter>callback</parameter> indicates the function to call when + the response arrives. The <parameter>userdata</parameter> pointer will be passed to the callback + function, and may be chosen freely by the caller. If <parameter>slot</parameter> is not + <constant>NULL</constant> and <function>sd_bus_call_async()</function> succeeds, <parameter>slot</parameter> is set to a slot object which can be used to cancel the method call at a later time using <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If <parameter>slot</parameter> is <constant>NULL</constant>, the lifetime of the method call is bound to the lifetime of the bus object itself, and it cannot be cancelled independently. See <citerefentry><refentrytitle>sd_bus_slot_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry> - for details. The <parameter>callback</parameter> function is called when the response arrives - and receives the response, <parameter>userdata</parameter> and a - <structname>sd_bus_error</structname> object as its arguments. The - <structname>sd_bus_error</structname> object is unused here and should be ignored. If - <parameter>callback</parameter> returns a non-negative integer when called, a debug message is - logged along with details about the response.</para> - - <para>To determine whether the method call succeeded, use + for details. <parameter>callback</parameter> is called when a reply arrives with the reply, + <parameter>userdata</parameter> and an <structname>sd_bus_error</structname> output + parameter as its arguments. Unlike <function>sd_bus_call()</function>, the + <structname>sd_bus_error</structname> output parameter passed to the callback will be empty. To + determine whether the method call succeeded, use <citerefentry><refentrytitle>sd_bus_message_is_method_error</refentrytitle><manvolnum>3</manvolnum></citerefentry> - on the reply object returned by <function>sd_bus_call()</function> or passed to the callback of - <function>sd_bus_call_async()</function>.</para> + on the reply message passed to the callback instead. If the callback returns zero and the + <structname>sd_bus_error</structname> output parameter is still empty when the callback + inishes, other handlers registered with functions such as + <citerefentry><refentrytitle>sd_bus_add_filter</refentrytitle><manvolnum>3</manvolnum></citerefentry> or + <citerefentry><refentrytitle>sd_bus_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry> + are given a chance to process the message. If the callback returns a non-zero value or the + <structname>sd_bus_error</structname> output parameter is not empty when the callback finishes, + no further processing of the message is done. Generally, you want to return zero from the + callback to give other registered handlers a chance to process the reply as well.</para> <para>If <parameter>usec</parameter> is zero, the default D-Bus method call timeout is used. See <citerefentry><refentrytitle>sd_bus_get_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>. diff --git a/man/sd_bus_call_method.xml b/man/sd_bus_call_method.xml index de29ac9610..870a78035a 100644 --- a/man/sd_bus_call_method.xml +++ b/man/sd_bus_call_method.xml @@ -18,7 +18,9 @@ <refnamediv> <refname>sd_bus_call_method</refname> + <refname>sd_bus_call_methodv</refname> <refname>sd_bus_call_method_async</refname> + <refname>sd_bus_call_method_asyncv</refname> <refpurpose>Initialize a bus message object and invoke the corresponding D-Bus method call </refpurpose> @@ -42,6 +44,19 @@ </funcprototype> <funcprototype> + <funcdef>int <function>sd_bus_call_methodv</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>const char *<parameter>destination</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + <paramdef>sd_bus_error *<parameter>ret_error</parameter></paramdef> + <paramdef>sd_bus_message **<parameter>reply</parameter></paramdef> + <paramdef>const char *<parameter>types</parameter></paramdef> + <paramdef>va_list <parameter>ap</parameter></paramdef> + </funcprototype> + + <funcprototype> <funcdef>int <function>sd_bus_call_method_async</function></funcdef> <paramdef>sd_bus *<parameter>bus</parameter></paramdef> <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> @@ -54,6 +69,20 @@ <paramdef>const char *<parameter>types</parameter></paramdef> <paramdef>...</paramdef> </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_bus_call_method_asyncv</function></funcdef> + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> + <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef> + <paramdef>const char *<parameter>destination</parameter></paramdef> + <paramdef>const char *<parameter>path</parameter></paramdef> + <paramdef>const char *<parameter>interface</parameter></paramdef> + <paramdef>const char *<parameter>member</parameter></paramdef> + <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef> + <paramdef>void *<parameter>userdata</parameter></paramdef> + <paramdef>const char *<parameter>types</parameter></paramdef> + <paramdef>va_list <parameter>ap</parameter></paramdef> + </funcprototype> </funcsynopsis> </refsynopsisdiv> diff --git a/man/sd_bus_message_dump.xml b/man/sd_bus_message_dump.xml index db9e46d991..720b114273 100644 --- a/man/sd_bus_message_dump.xml +++ b/man/sd_bus_message_dump.xml @@ -65,7 +65,7 @@ <para>Output for a signal message (with <constant>SD_BUS_MESSAGE_DUMP_WITH_HEADER</constant>): <programlisting> -‣ Type=signal Endian=l Flags=1 Version=1 Priority=0 Cookie=22 +‣ Type=signal Endian=l Flags=1 Version=1 Cookie=22 Path=/value/a Interface=org.freedesktop.DBus.Properties Member=PropertiesChanged MESSAGE "sa{sv}as" { STRING "org.freedesktop.systemd.ValueTest"; diff --git a/man/sd_bus_message_set_destination.xml b/man/sd_bus_message_set_destination.xml index ca3e466d7a..51da5ff3b8 100644 --- a/man/sd_bus_message_set_destination.xml +++ b/man/sd_bus_message_set_destination.xml @@ -82,12 +82,10 @@ member fields from <parameter>message</parameter> header. The return value will be <constant>NULL</constant> is <parameter>message</parameter> is <constant>NULL</constant> or the message is of a type that doesn't use those fields or the message doesn't have them set. See - <citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>3</manvolnum></citerefentry> - and + <citerefentry><refentrytitle>sd_bus_message_new_method_call</refentrytitle><manvolnum>3</manvolnum></citerefentry> and <citerefentry><refentrytitle>sd_bus_message_set_destination</refentrytitle><manvolnum>3</manvolnum></citerefentry> for more discussion of those values.</para> - <para><function>sd_bus_message_set_sender()</function> sets the sender service name for the specified bus message object. The specified name must be a valid unique or well-known service name. This function is useful only for messages to send on direct connections as for connections to bus brokers the broker will fill in the destination @@ -123,9 +121,9 @@ <varlistentry> <term><constant>-EPERM</constant></term> - <listitem><para>For <function>sd_bus_message_set_destination</function> or - <function>sd_bus_message_set_sender</function>, the message is already - sealed.</para></listitem> + <listitem><para>For <function>sd_bus_message_set_destination()</function> and + <function>sd_bus_message_set_sender()</function>, the message is already sealed.</para> + </listitem> </varlistentry> <varlistentry> diff --git a/man/sd_bus_reply_method_error.xml b/man/sd_bus_reply_method_error.xml index a1062ce2a9..0a85557ec6 100644 --- a/man/sd_bus_reply_method_error.xml +++ b/man/sd_bus_reply_method_error.xml @@ -19,8 +19,10 @@ <refnamediv> <refname>sd_bus_reply_method_error</refname> <refname>sd_bus_reply_method_errorf</refname> + <refname>sd_bus_reply_method_errorfv</refname> <refname>sd_bus_reply_method_errno</refname> <refname>sd_bus_reply_method_errnof</refname> + <refname>sd_bus_reply_method_errnofv</refname> <refpurpose>Reply with an error to a D-Bus method call</refpurpose> </refnamediv> @@ -40,7 +42,15 @@ <paramdef>sd_bus_message *<parameter>call</parameter></paramdef> <paramdef>const char *<parameter>name</parameter></paramdef> <paramdef>const char *<parameter>format</parameter></paramdef> - <paramdef>…</paramdef> + <paramdef>...</paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int sd_bus_reply_method_errorfv</funcdef> + <paramdef>sd_bus_message *<parameter>call</parameter></paramdef> + <paramdef>const char *<parameter>name</parameter></paramdef> + <paramdef>const char *<parameter>format</parameter></paramdef> + <paramdef>va_list <parameter>ap</parameter></paramdef> </funcprototype> <funcprototype> @@ -55,7 +65,15 @@ <paramdef>sd_bus_message *<parameter>call</parameter></paramdef> <paramdef>int <parameter>error</parameter></paramdef> <paramdef>const char *<parameter>format</parameter></paramdef> - <paramdef>…</paramdef> + <paramdef>...</paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int sd_bus_reply_method_errnofv</funcdef> + <paramdef>sd_bus_message *<parameter>call</parameter></paramdef> + <paramdef>int <parameter>error</parameter></paramdef> + <paramdef>const char *<parameter>format</parameter></paramdef> + <paramdef>va_list <parameter>ap</parameter></paramdef> </funcprototype> </funcsynopsis> </refsynopsisdiv> diff --git a/man/sd_bus_reply_method_return.xml b/man/sd_bus_reply_method_return.xml index 8669730d0f..a6052c61fd 100644 --- a/man/sd_bus_reply_method_return.xml +++ b/man/sd_bus_reply_method_return.xml @@ -18,6 +18,7 @@ <refnamediv> <refname>sd_bus_reply_method_return</refname> + <refname>sd_bus_reply_method_returnv</refname> <refpurpose>Reply to a D-Bus method call</refpurpose> </refnamediv> @@ -32,6 +33,13 @@ <paramdef>const char *<parameter>types</parameter></paramdef> <paramdef>...</paramdef> </funcprototype> + + <funcprototype> + <funcdef>int sd_bus_reply_method_returnv</funcdef> + <paramdef>sd_bus_message *<parameter>call</parameter></paramdef> + <paramdef>const char *<parameter>types</parameter></paramdef> + <paramdef>va_list <parameter>ap</parameter></paramdef> + </funcprototype> </funcsynopsis> </refsynopsisdiv> diff --git a/man/sd_bus_slot_get_bus.xml b/man/sd_bus_slot_get_bus.xml new file mode 100644 index 0000000000..ed3e55b057 --- /dev/null +++ b/man/sd_bus_slot_get_bus.xml @@ -0,0 +1,88 @@ +<?xml version='1.0'?> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" + "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> +<!-- SPDX-License-Identifier: LGPL-2.1+ --> + +<refentry id="sd_bus_slot_get_bus" xmlns:xi="http://www.w3.org/2001/XInclude"> + <refentryinfo> + <title>sd_bus_slot_get_bus</title> + <productname>systemd</productname> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_bus_slot_get_bus</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_bus_slot_get_bus</refname> + <refname>sd_bus_slot_get_current_handler</refname> + <refname>sd_bus_slot_get_current_message</refname> + <refname>sd_bus_slot_get_current_userdata</refname> + + <refpurpose>Query information attached to a bus slot object</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> + + <funcprototype> + <funcdef>sd_bus *<function>sd_bus_slot_get_bus</function></funcdef> + <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>sd_bus_message_handler_t <function>sd_bus_slot_get_current_handler</function> + </funcdef> + <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>sd_bus_message *<function>sd_bus_slot_get_current_message</function></funcdef> + <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>void *<function>sd_bus_slot_get_current_userdata</function></funcdef> + <paramdef>sd_bus_slot *<parameter>slot</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_bus_slot_get_bus()</function> returns the bus object that message + <parameter>slot</parameter> is attached to.</para> + + <para><function>sd_bus_slot_get_current_handler()</function>, + <function>sd_bus_slot_get_current_message()</function> and + <function>sd_bus_slot_get_current_userdata()</function> return the current handler, message and + userdata respectively of the bus <parameter>slot</parameter> is attached to if we're currently + executing the callback associated with <parameter>slot</parameter>.</para> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para><function>sd_bus_slot_get_bus()</function> always returns the bus object.</para> + + <para>On success, <function>sd_bus_slot_get_current_handler()</function>, + <function>sd_bus_slot_get_current_message()</function> and + <function>sd_bus_slot_get_current_userdata()</function> return the requested object. On failure, + they return <constant>NULL</constant>.</para> + </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>, + </para> + </refsect1> + +</refentry> diff --git a/man/sd_bus_slot_ref.xml b/man/sd_bus_slot_ref.xml index 22b288bfcc..ef144ece6d 100644 --- a/man/sd_bus_slot_ref.xml +++ b/man/sd_bus_slot_ref.xml @@ -18,7 +18,6 @@ <refname>sd_bus_slot_ref</refname> <refname>sd_bus_slot_unref</refname> <refname>sd_bus_slot_unrefp</refname> - <refname>sd_bus_slot_get_bus</refname> <refpurpose>Create and destroy references to a bus slot object</refpurpose> </refnamediv> @@ -41,11 +40,6 @@ <funcdef>void <function>sd_bus_slot_unrefp</function></funcdef> <paramdef>sd_bus_slot **<parameter>slotp</parameter></paramdef> </funcprototype> - - <funcprototype> - <funcdef>sd_bus *<function>sd_bus_slot_get_bus</function></funcdef> - <paramdef>sd_bus_slot *<parameter>m</parameter></paramdef> - </funcprototype> </funcsynopsis> </refsynopsisdiv> @@ -72,11 +66,7 @@ execute no operation if the passed in bus object address is <constant>NULL</constant>. <function>sd_bus_slot_unrefp()</function> will first dereference its argument, which must not be <constant>NULL</constant>, and will execute no operation if - <emphasis>that</emphasis> is <constant>NULL</constant>. - </para> - - <para><function>sd_bus_slot_get_bus()</function> returns the bus object that message - <parameter>slot</parameter> is attached to.</para> + <emphasis>that</emphasis> is <constant>NULL</constant>.</para> </refsect1> <refsect1> @@ -85,8 +75,6 @@ <para><function>sd_bus_slot_ref()</function> always returns the argument.</para> <para><function>sd_bus_slot_unref()</function> always returns <constant>NULL</constant>.</para> - - <para><function>sd_bus_slot_get_bus()</function> always returns the bus object.</para> </refsect1> <xi:include href="libsystemd-pkgconfig.xml" /> diff --git a/man/sd_path_lookup.xml b/man/sd_path_lookup.xml new file mode 100644 index 0000000000..68c6812ab1 --- /dev/null +++ b/man/sd_path_lookup.xml @@ -0,0 +1,215 @@ +<?xml version='1.0'?> +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" + "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> +<!-- SPDX-License-Identifier: LGPL-2.1+ --> + +<refentry id="sd_path_lookup" xmlns:xi="http://www.w3.org/2001/XInclude"> + + <refentryinfo> + <title>sd_path_lookup</title> + <productname>systemd</productname> + </refentryinfo> + + <refmeta> + <refentrytitle>sd_path_lookup</refentrytitle> + <manvolnum>3</manvolnum> + </refmeta> + + <refnamediv> + <refname>sd_path_lookup</refname> + <refname>sd_path_lookup_strv</refname> + + <refpurpose>Query well-known file system paths</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo>#include <systemd/sd-path.h></funcsynopsisinfo> + + <!-- note: individual constants are not added as <refname>s, there's just too many --> + + <funcsynopsisinfo><token>enum</token> { + <constant>SD_PATH_TEMPORARY</constant>, + <constant>SD_PATH_TEMPORARY_LARGE</constant>, + + <constant>SD_PATH_SYSTEM_BINARIES</constant>, + <constant>SD_PATH_SYSTEM_INCLUDE</constant>, + <constant>SD_PATH_SYSTEM_LIBRARY_PRIVATE</constant>, + <constant>SD_PATH_SYSTEM_LIBRARY_ARCH</constant>, + <constant>SD_PATH_SYSTEM_SHARED</constant>, + <constant>SD_PATH_SYSTEM_CONFIGURATION_FACTORY</constant>, + <constant>SD_PATH_SYSTEM_STATE_FACTORY</constant>, + + <constant>SD_PATH_SYSTEM_CONFIGURATION</constant>, + <constant>SD_PATH_SYSTEM_RUNTIME</constant>, + <constant>SD_PATH_SYSTEM_RUNTIME_LOGS</constant>, + <constant>SD_PATH_SYSTEM_STATE_PRIVATE</constant>, + <constant>SD_PATH_SYSTEM_STATE_LOGS</constant>, + <constant>SD_PATH_SYSTEM_STATE_CACHE</constant>, + <constant>SD_PATH_SYSTEM_STATE_SPOOL</constant>, + + <constant>SD_PATH_USER_BINARIES</constant>, + <constant>SD_PATH_USER_LIBRARY_PRIVATE</constant>, + <constant>SD_PATH_USER_LIBRARY_ARCH</constant>, + <constant>SD_PATH_USER_SHARED</constant>, + + <constant>SD_PATH_USER_CONFIGURATION</constant>, + <constant>SD_PATH_USER_RUNTIME</constant>, + <constant>SD_PATH_USER_STATE_CACHE</constant>, + + <constant>SD_PATH_USER</constant>, + <constant>SD_PATH_USER_DOCUMENTS</constant>, + <constant>SD_PATH_USER_MUSIC</constant>, + <constant>SD_PATH_USER_PICTURES</constant>, + <constant>SD_PATH_USER_VIDEOS</constant>, + <constant>SD_PATH_USER_DOWNLOAD</constant>, + <constant>SD_PATH_USER_PUBLIC</constant>, + <constant>SD_PATH_USER_TEMPLATES</constant>, + <constant>SD_PATH_USER_DESKTOP</constant>, + + <constant>SD_PATH_SEARCH_BINARIES</constant>, + <constant>SD_PATH_SEARCH_BINARIES_DEFAULT</constant>, + <constant>SD_PATH_SEARCH_LIBRARY_PRIVATE</constant>, + <constant>SD_PATH_SEARCH_LIBRARY_ARCH</constant>, + <constant>SD_PATH_SEARCH_SHARED</constant>, + <constant>SD_PATH_SEARCH_CONFIGURATION_FACTORY</constant>, + <constant>SD_PATH_SEARCH_STATE_FACTORY</constant>, + <constant>SD_PATH_SEARCH_CONFIGURATION</constant>, + + <constant>SD_PATH_SYSTEMD_UTIL_DIR</constant>, + <constant>SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR</constant>, + <constant>SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR</constant>, + <constant>SD_PATH_SYSTEMD_USER_UNIT_DIR</constant>, + <constant>SD_PATH_SYSTEMD_USER_PRESET_DIR</constant>, + <constant>SD_PATH_SYSTEMD_SYSTEM_CONF_DIR</constant>, + <constant>SD_PATH_SYSTEMD_USER_CONF_DIR</constant>, + <constant>SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH</constant>, + <constant>SD_PATH_SYSTEMD_USER_UNIT_PATH</constant>, + <constant>SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR</constant>, + <constant>SD_PATH_SYSTEMD_USER_GENERATOR_DIR</constant>, + <constant>SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH</constant>, + <constant>SD_PATH_SYSTEMD_USER_GENERATOR_PATH</constant>, + <constant>SD_PATH_SYSTEMD_SLEEP_DIR</constant>, + <constant>SD_PATH_SYSTEMD_SHUTDOWN_DIR</constant>, + + <constant>SD_PATH_TMPFILES_DIR</constant>, + <constant>SD_PATH_SYSUSERS_DIR</constant>, + <constant>SD_PATH_SYSCTL_DIR</constant>, + <constant>SD_PATH_BINFMT_DIR</constant>, + <constant>SD_PATH_MODULES_LOAD_DIR</constant>, + <constant>SD_PATH_CATALOG_DIR</constant>, + + <constant>SD_PATH_SYSTEMD_NETWORK_PATH</constant>, +};</funcsynopsisinfo> + + <funcprototype> + <funcdef>int <function>sd_path_lookup</function></funcdef> + <paramdef>uint64_t <parameter>type</parameter></paramdef> + <paramdef>const char *<parameter>suffix</parameter></paramdef> + <paramdef>char **<parameter>paths</parameter></paramdef> + </funcprototype> + + <funcprototype> + <funcdef>int <function>sd_path_lookup_strv</function></funcdef> + <paramdef>uint64_t <parameter>type</parameter></paramdef> + <paramdef>const char *<parameter>suffix</parameter></paramdef> + <paramdef>char ***<parameter>paths</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1> + <title>Description</title> + + <para><function>sd_path_lookup()</function> and <function>sd_bus_path_lookup_strv()</function> return a + single path or set of file system paths specified by the argument <parameter>type</parameter>. In case of + <function>sd_path_lookup()</function> a single <constant>NUL</constant>-terminated string is returned. + When <parameter>type</parameter> specifies a set of paths, they are concatenated using + <literal>:</literal> as a separator (as is traditionally done for e.g. <varname>$PATH</varname> or + <varname>$LD_LIBRARY_PATH</varname>). In case of <function>sd_path_lookup_strv()</function> a + <constant>NULL</constant>-terminated array of strings is returned (strv). If suffix + <parameter>suffix</parameter> is given, it is concatenated to each of the paths after a slash + (<literal>/</literal>). All returned paths are absolute.</para> + + <para>For paths which refer to user directories, the relevant XDG standard is followed, with support for + environment variables like <varname>$XDG_DOCUMENTS_DIR</varname>, <varname>$XDG_DESKTOP_DIR</varname>, + ..., and explicit configuration in <filename>/etc/xdg/user-dirs.conf</filename> or + <filename>${XDG_CONFIG_HOME}/user-dirs.dirs</filename>. See + <ulink url="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html"> + XDG Base Directory Specification</ulink> for details.</para> + + <para><citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry> is + a wrapper around <function>sd_path_lookup()</function> and allows the same set of paths to be queried. + </para> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para>On success, <function>sd_path_lookup()</function> and <function>sd_path_lookup_strv()</function> + return a non-negative integer. On failure, a negative errno-style error number is returned by either + function.</para> + + <para>The returned string or string array (strv) must be + <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>'d by the + caller.</para> + + <refsect2 id='errors'> + <title>Errors</title> + + <para>Returned errors may indicate the following problems:</para> + + <variablelist> + <varlistentry> + <term><constant>-EOPNOTSUPP</constant></term> + + <listitem><para>Unknown identifier <parameter>type</parameter>.</para></listitem> + </varlistentry> + + <varlistentry> + <term><constant>-EINVAL</constant></term> + + <listitem><para>Output argument is <constant>NULL</constant>.</para></listitem> + </varlistentry> + + <varlistentry> + <term><constant>-ENXIO</constant></term> + + <listitem><para>Query failed because of an undefined environment variable (e.g. for + <constant>SD_PATH_USER_RUNTIME</constant> when <varname>$XDG_RUNTIME_DIR</varname> is not + defined).</para></listitem> + </varlistentry> + + <varlistentry> + <term><constant>-ENOMEM</constant></term> + + <listitem><para>Memory allocation failed.</para></listitem> + </varlistentry> + </variablelist> + </refsect2> + </refsect1> + + <refsect1> + <title>Examples</title> + + <refsect2> + <title>Look up the location of ~/Documents</title> + + <programlisting><xi:include href="path-documents.c" parse="text" /></programlisting> + <para>Note that the default answer of <filename index='false'>$HOME/Documents</filename> may be + overridden by <filename index='false'>user-dirs.conf</filename> or + <varname>$XDG_DOCUMENTS_DIR</varname>.</para> + </refsect2> + </refsect1> + + <xi:include href="libsystemd-pkgconfig.xml" /> + + <refsect1> + <title>See Also</title> + + <para> + <citerefentry><refentrytitle>systemd-path</refentrytitle><manvolnum>1</manvolnum></citerefentry> + </para> + </refsect1> + +</refentry> diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml index 4df71e21eb..2735cb10dd 100644 --- a/man/sysctl.d.xml +++ b/man/sysctl.d.xml @@ -32,7 +32,7 @@ key.middle/part/with/dots.foo = 123 -key.that.will.not.fail = value key.pattern.*.with.glob = whatever -key.pattern.excluded.with.glob -key.pattern.overriden.with.glob = custom +key.pattern.overridden.with.glob = custom </programlisting> </refsynopsisdiv> diff --git a/man/systemctl.xml b/man/systemctl.xml index e8d5f9f4d8..fe8b77423a 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1503,6 +1503,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err </varlistentry> <varlistentry> + <term><option>-P</option></term> + + <listitem> + <para>Equivalent to <option>--value</option> <option>--property=</option>, i.e. shows the + value of the property without the property name or <literal>=</literal>. Note that using + <option>-P</option> once will also affect all properties listed with + <option>-p</option>/<option>--property=</option>.</para> + </listitem> + </varlistentry> + + <varlistentry> <term><option>-a</option></term> <term><option>--all</option></term> @@ -1627,9 +1638,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err <term><option>--value</option></term> <listitem> - <para>When printing properties with <command>show</command>, - only print the value, and skip the property name and - <literal>=</literal>.</para> + <para>When printing properties with <command>show</command>, only print the value, and skip the + property name and <literal>=</literal>. Also see option <option>-P</option> above.</para> </listitem> </varlistentry> diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 3a1d18dae9..a88f60fbb6 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -146,8 +146,24 @@ <varlistentry> <term><option>--slice=</option></term> - <listitem><para>Make the new <filename>.service</filename> or <filename>.scope</filename> unit part of the - specified slice, instead of <filename>system.slice</filename>.</para> + <listitem><para>Make the new <filename>.service</filename> or <filename>.scope</filename> unit part + of the specified slice, instead of <filename>system.slice</filename> (when running in + <option>--system</option> mode) or the root slice (when running in <option>--user</option> + mode).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><option>--slice-inherit</option></term> + + <listitem><para>Make the new <filename>.service</filename> or <filename>.scope</filename> unit part + of the inherited slice. This option can be combined with <option>--slice=</option>.</para> + + <para>An inherited slice is located within <command>systemd-run</command> slice. Example: if + <command>systemd-run</command> slice is <filename>foo.slice</filename>, and the + <option>--slice=</option> argument is <filename>bar</filename>, the unit will be placed under the + <filename>foo-bar.slice</filename>.</para> + </listitem> </varlistentry> diff --git a/man/systemd-socket-activate.xml b/man/systemd-socket-activate.xml index f3dbb47a61..20a5572192 100644 --- a/man/systemd-socket-activate.xml +++ b/man/systemd-socket-activate.xml @@ -141,6 +141,7 @@ <varlistentry> <term><varname>$SYSTEMD_LOG_TARGET</varname></term> <term><varname>$SYSTEMD_LOG_LEVEL</varname></term> + <term><varname>$SYSTEMD_LOG_TIME</varname></term> <term><varname>$SYSTEMD_LOG_COLOR</varname></term> <term><varname>$SYSTEMD_LOG_LOCATION</varname></term> diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index e22b335d30..435c3882db 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -63,10 +63,11 @@ <variablelist class='config-directives'> <varlistentry> - <term><varname>LogLevel=</varname></term> - <term><varname>LogTarget=</varname></term> <term><varname>LogColor=</varname></term> + <term><varname>LogLevel=</varname></term> <term><varname>LogLocation=</varname></term> + <term><varname>LogTarget=</varname></term> + <term><varname>LogTime=</varname></term> <term><varname>DumpCore=yes</varname></term> <term><varname>CrashChangeVT=no</varname></term> <term><varname>CrashShell=no</varname></term> diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index dfb8520e11..401233475e 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -662,6 +662,32 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting> </varlistentry> <varlistentry> + <term><varname>CoredumpFilter=</varname></term> + + <listitem><para>Controls which types of memory mappings will be saved if the process dumps core + (using the <filename>/proc/<replaceable>pid</replaceable>/coredump_filter</filename> file). Takes a + whitespace-separated combination of mapping type names or numbers (with the default base 16). Mapping + type names are <constant>private-anonymous</constant>, <constant>shared-anonymous</constant>, + <constant>private-file-backed</constant>, <constant>shared-file-backed</constant>, + <constant>elf-headers</constant>, <constant>private-huge</constant>, + <constant>shared-huge</constant>, <constant>private-dax</constant>, <constant>shared-dax</constant>, + and the special values <constant>all</constant> (all types) and <constant>default</constant> (the + kernel default of <literal><constant>private-anonymous</constant> + <constant>shared-anonymous</constant> <constant>elf-headers</constant> + <constant>private-huge</constant></literal>). See + <citerefentry><refentrytitle>core</refentrytitle><manvolnum>5</manvolnum></citerefentry> for the + meaning of the mapping types. When specified multiple times, all specified masks are ORed. When not + set, or if the empty value is assigned, the inherited value is not changed.</para> + + <example> + <title>Add DAX pages to the dump filter</title> + + <programlisting>CoredumpFilter=default private-dax shared-dax</programlisting> + </example> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>KeyringMode=</varname></term> <listitem><para>Controls how the kernel session keyring is set up for the service (see <citerefentry diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 5457e668dd..8d11922c71 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -459,6 +459,7 @@ reception.</para> </listitem> </varlistentry> + <varlistentry> <term><varname>BindCarrier=</varname></term> <listitem> @@ -1386,6 +1387,7 @@ read via <function>sd_network_link_get_sip_servers()</function> function.</para> </listitem> </varlistentry> + <varlistentry> <term><varname>UseMTU=</varname></term> <listitem> @@ -1429,6 +1431,18 @@ sent even if this is set to true.</para> </listitem> </varlistentry> + + <varlistentry> + <term><varname>MUDURL=</varname></term> + <listitem> + <para>When configured, the Manufacturer Usage Descriptions (MUD) URL will be sent to the + DHCPv4 server. Takes an URL of length up to 255 characters. A superficial verification that + the string is a valid URL will be performed. DHCPv4 clients are intended to have at most one + MUD URL associated with them. See + <ulink url="https://tools.ietf.org/html/rfc8520">RFC 8520</ulink>.</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>UseHostname=</varname></term> <listitem> @@ -1692,6 +1706,16 @@ </varlistentry> <varlistentry> + <term><varname>MUDURL=</varname></term> + <listitem> + <para>When configured, the Manufacturer Usage Descriptions (MUD) URL will be sent to the DHCPV6 server. + Takes an URL of length up to 255 characters. A superficial verification that the string is a valid URL + will be performed. DHCPv6 clients are intended to have at most one MUD URL associated with them. See + <ulink url="https://tools.ietf.org/html/rfc8520">RFC 8520</ulink>.</para> + </listitem> + </varlistentry> + + <varlistentry> <term><varname>ForceDHCPv6PDOtherInformation=</varname></term> <listitem> <para>Takes a boolean that enforces DHCPv6 stateful mode when the 'Other information' bit is set in @@ -1904,6 +1928,25 @@ </varlistentry> <varlistentry> + <term><varname>POP3Servers=</varname></term> + + <listitem><para>Similar to the <varname>DNS=</varname> settings described above, these + settings configure whether and what POP3 server information shall be emitted as part of + the DHCP lease. The same syntax, propagation semantics and defaults apply as for + <term><varname>SMTPServers=</varname></term> + <varname>DNS=</varname>.</para></listitem> + </varlistentry> + + <varlistentry> + <term><varname>SMTPServers=</varname></term> + + <listitem><para>Similar to the <varname>DNS=</varname> setting described above, this + setting configures whether and what SMTP server information shall be emitted as part of + the DHCP lease. The same syntax, propagation semantics and defaults apply as for + <varname>DNS=</varname>.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>EmitRouter=</varname></term> <listitem><para>Similar to the <varname>EmitDNS=</varname> @@ -2310,6 +2353,28 @@ </refsect1> <refsect1> + <title>[LLDP] Section Options</title> + <para>The <literal>[LLDP]</literal> section manages the Link Layer Discovery Protocol (LLDP) and accepts the + following keys.</para> + <variablelist class='network-directives'> + <varlistentry> + <term><varname>MUDURL=</varname></term> + <listitem> + <para>Controls support for Ethernet LLDP packet's Manufacturer Usage Description (MUD). MUD is an embedded software + standard defined by the IETF that allows IoT Device makers to advertise device specifications, including the intended + communication patterns for their device when it connects to the network. The network can then use this intent to author + a context-specific access policy, so the device functions only within those parameters. Takes an URL of length up to 255 + characters. A superficial verification that the string is a valid URL + will be performed. See + <ulink url="https://tools.ietf.org/html/rfc8520">RFC 8520</ulink> for details. The MUD URL received + from the LLDP packets will be saved at the state files and can be read via + <function>sd_lldp_neighbor_get_mud_url()</function> function.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> <title>[CAN] Section Options</title> <para>The <literal>[CAN]</literal> section manages the Controller Area Network (CAN bus) and accepts the following keys.</para> @@ -2318,7 +2383,7 @@ <term><varname>BitRate=</varname></term> <listitem> <para>The bitrate of CAN device in bits per second. The usual SI prefixes (K, M) with the base of 1000 can - be used here.</para> + be used here. Takes a number in the range 1..4294967295.</para> </listitem> </varlistentry> <varlistentry> @@ -2329,6 +2394,29 @@ </listitem> </varlistentry> <varlistentry> + <term><varname>DataBitRate=</varname></term> + <term><varname>DataSamplePoint=</varname></term> + <listitem> + <para>The bitrate and sample point for the data phase, if CAN-FD is used. These settings are + analogous to the <varname>BitRate=</varname> and <varname>SamplePoint=</varname> keys.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>FDMode=</varname></term> + <listitem> + <para>Takes a boolean. When <literal>yes</literal>, CAN-FD mode is enabled for the interface. + Note, that a bitrate and optional sample point should also be set for the CAN-FD data phase using + the <varname>DataBitRate=</varname> and <varname>DataSamplePoint=</varname> keys.</para> + </listitem> + </varlistentry> + <varlistentry> + <term><varname>FDNonISO=</varname></term> + <listitem> + <para>Takes a boolean. When <literal>yes</literal>, non-ISO CAN-FD mode is enabled for the + interface. When unset, the kernel's default will be used.</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>RestartSec=</varname></term> <listitem> <para>Automatic restart delay time. If set to a non-zero value, a restart of the CAN controller will be diff --git a/man/systemd.service.xml b/man/systemd.service.xml index e178724c55..02eb706789 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -217,8 +217,7 @@ this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see below) should be set to open access to the notification socket provided by systemd. If <varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to - <option>main</option>. Note that currently <varname>Type=</varname><option>notify</option> will not work if - used in combination with <varname>PrivateNetwork=</varname><option>yes</option>.</para></listitem> + <option>main</option></para></listitem>. <listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however, actual execution of the service program is delayed until all active jobs are dispatched. This may be used @@ -424,6 +423,9 @@ <varname>ExecStart=</varname>, or <varname>ExecStartPost=</varname> fail (and are not prefixed with <literal>-</literal>, see above) or time out before the service is fully up, execution continues with commands specified in <varname>ExecStopPost=</varname>, the commands in <varname>ExecStop=</varname> are skipped.</para> + + <para>Note that the execution of <varname>ExecStartPost=</varname> is taken into account for the purpose of + <varname>Before=</varname>/<varname>After=</varname> ordering constraints.</para> </listitem> </varlistentry> @@ -535,7 +537,10 @@ service, as well as the main process' exit code and status, set in the <varname>$SERVICE_RESULT</varname>, <varname>$EXIT_CODE</varname> and <varname>$EXIT_STATUS</varname> environment variables, see <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for - details.</para></listitem> + details.</para> + + <para>Note that the execution of <varname>ExecStopPost=</varname> is taken into account for the purpose of + <varname>Before=</varname>/<varname>After=</varname> ordering constraints.</para></listitem> </varlistentry> <varlistentry> diff --git a/man/systemd.special.xml b/man/systemd.special.xml index d54a5de871..c37e732b5f 100644 --- a/man/systemd.special.xml +++ b/man/systemd.special.xml @@ -106,7 +106,7 @@ </refsect1> <refsect1> - <title>Units managed by the system's service manager</title> + <title>Units managed by the system service manager</title> <refsect2> <title>Special System Units</title> @@ -1058,7 +1058,7 @@ </refsect1> <refsect1> - <title>Units managed by the user's service manager</title> + <title>Units managed by the user service manager</title> <refsect2> <title>Special User Units</title> diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 64240208c2..d0de9aa500 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -750,7 +750,8 @@ type when precisely a unit has finished starting up. Most importantly, for service units start-up is considered completed for the purpose of <varname>Before=</varname>/<varname>After=</varname> when all its configured start-up commands have been invoked and they either failed or reported start-up - success.</para> + success. Note that this does includes <varname>ExecStartPost=</varname> (or + <varname>ExecStopPost=</varname> for the shutdown case).</para> <para>Note that those settings are independent of and orthogonal to the requirement dependencies as configured by <varname>Requires=</varname>, <varname>Wants=</varname>, <varname>Requisite=</varname>, diff --git a/man/systemd.xml b/man/systemd.xml index 94b3845a0e..f5e4a9526c 100644 --- a/man/systemd.xml +++ b/man/systemd.xml @@ -607,6 +607,13 @@ <variablelist class='environment-variables'> <varlistentry> + <term><varname>$SYSTEMD_LOG_COLOR</varname></term> + <listitem><para>Controls whether systemd highlights important + log messages. This can be overridden with + <option>--log-color</option>.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>$SYSTEMD_LOG_LEVEL</varname></term> <listitem><para>systemd reads the log level from this environment variable. This can be overridden with @@ -614,6 +621,13 @@ </varlistentry> <varlistentry> + <term><varname>$SYSTEMD_LOG_LOCATION</varname></term> + <listitem><para>Controls whether systemd prints the code + location along with log messages. This can be overridden with + <option>--log-location</option>.</para></listitem> + </varlistentry> + + <varlistentry> <term><varname>$SYSTEMD_LOG_TARGET</varname></term> <listitem><para>systemd reads the log target from this environment variable. This can be overridden with @@ -621,17 +635,10 @@ </varlistentry> <varlistentry> - <term><varname>$SYSTEMD_LOG_COLOR</varname></term> - <listitem><para>Controls whether systemd highlights important - log messages. This can be overridden with - <option>--log-color=</option>.</para></listitem> - </varlistentry> - - <varlistentry> - <term><varname>$SYSTEMD_LOG_LOCATION</varname></term> - <listitem><para>Controls whether systemd prints the code - location along with log messages. This can be overridden with - <option>--log-location=</option>.</para></listitem> + <term><varname>$SYSTEMD_LOG_TIME</varname></term> + <listitem><para>Controls whether systemd prefixes log + messages with the current time. This can be overridden with + <option>--log-time=</option>.</para></listitem> </varlistentry> <varlistentry> @@ -829,18 +836,21 @@ </varlistentry> <varlistentry> - <term><varname>systemd.log_target=</varname></term> - <term><varname>systemd.log_level=</varname></term> - <term><varname>systemd.log_location=</varname></term> <term><varname>systemd.log_color</varname></term> + <term><varname>systemd.log_level=</varname></term> + <term><varname>systemd.log_location</varname></term> + <term><varname>systemd.log_target=</varname></term> + <term><varname>systemd.log_time</varname></term> <listitem><para>Controls log output, with the same effect as the - <varname>$SYSTEMD_LOG_TARGET</varname>, + <varname>$SYSTEMD_LOG_COLOR</varname>, <varname>$SYSTEMD_LOG_LEVEL</varname>, <varname>$SYSTEMD_LOG_LOCATION</varname>, - <varname>$SYSTEMD_LOG_COLOR</varname> environment variables described above. - <varname>systemd.log_color</varname> can be specified without an argument, - with the same effect as a positive boolean.</para></listitem> + <varname>$SYSTEMD_LOG_TARGET</varname>, + <varname>$SYSTEMD_LOG_TIME</varname>, environment variables described above. + <varname>systemd.log_color</varname>, <varname>systemd.log_location</varname>, and + <varname>systemd.log_time</varname> can be specified without an argument, with the + same effect as a positive boolean.</para></listitem> </varlistentry> <varlistentry> @@ -1135,9 +1145,10 @@ </varlistentry> <varlistentry> - <term><option>--log-target=</option></term> + <term><option>--log-color</option></term> - <listitem><para>Set log target. See <varname>systemd.log_target</varname> above.</para></listitem> + <listitem><para>Highlight important log messages. See <varname>systemd.log_color</varname> above. + </para></listitem> </varlistentry> <varlistentry> @@ -1147,17 +1158,23 @@ </varlistentry> <varlistentry> - <term><option>--log-color</option></term> + <term><option>--log-location</option></term> - <listitem><para>Highlight important log messages. See <varname>systemd.log_color</varname> above. - </para></listitem> + <listitem><para>Include code location in log messages. See <varname>systemd.log_location</varname> + above.</para></listitem> </varlistentry> <varlistentry> - <term><option>--log-location</option></term> + <term><option>--log-target=</option></term> - <listitem><para>Include code location in log messages. See <varname>systemd.log_location</varname> - above.</para></listitem> + <listitem><para>Set log target. See <varname>systemd.log_target</varname> above.</para></listitem> + </varlistentry> + + <varlistentry> + <term><option>--log-time=</option></term> + + <listitem><para>Prefix messages with timestamp. See <varname>systemd.log_time</varname> above. + </para></listitem> </varlistentry> <varlistentry> diff --git a/meson.build b/meson.build index d6c09cb18a..fb90077563 100644 --- a/meson.build +++ b/meson.build @@ -39,20 +39,22 @@ conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path) want_ossfuzz = get_option('oss-fuzz') want_libfuzzer = get_option('llvm-fuzz') -want_fuzzbuzz = get_option('fuzzbuzz') -if want_ossfuzz + want_libfuzzer + want_fuzzbuzz > 1 - error('only one of oss-fuzz, llvm-fuzz or fuzzbuzz can be specified') +if want_ossfuzz + want_libfuzzer > 1 + error('only one of oss-fuzz or llvm-fuzz can be specified') endif skip_deps = want_ossfuzz or want_libfuzzer -fuzzer_build = want_ossfuzz or want_libfuzzer or want_fuzzbuzz +fuzzer_build = want_ossfuzz or want_libfuzzer ##################################################################### # Try to install the git pre-commit hook -git_hook = run_command(join_paths(project_source_root, 'tools/add-git-hook.sh')) -if git_hook.returncode() == 0 - message(git_hook.stdout().strip()) +add_git_hook_sh = find_program('tools/add-git-hook.sh', required : false) +if add_git_hook_sh.found() + git_hook = run_command(add_git_hook_sh) + if git_hook.returncode() == 0 + message(git_hook.stdout().strip()) + endif endif ##################################################################### @@ -196,7 +198,7 @@ memory_accounting_default = get_option('memory-accounting-default') status_unit_format_default = get_option('status-unit-format-default') conf.set_quoted('PKGSYSCONFDIR', pkgsysconfdir) -conf.set_quoted('SYSTEM_CONFIG_UNIT_PATH', join_paths(pkgsysconfdir, 'system')) +conf.set_quoted('SYSTEM_CONFIG_UNIT_DIR', join_paths(pkgsysconfdir, 'system')) conf.set_quoted('SYSTEM_DATA_UNIT_PATH', systemunitdir) conf.set_quoted('SYSTEM_SYSVINIT_PATH', sysvinit_path) conf.set_quoted('SYSTEM_SYSVRCND_PATH', sysvrcnd_path) @@ -204,8 +206,8 @@ conf.set_quoted('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-loc conf.set('ANSI_OK_COLOR', 'ANSI_' + get_option('ok-color').underscorify().to_upper()) -conf.set_quoted('USER_CONFIG_UNIT_PATH', join_paths(pkgsysconfdir, 'user')) -conf.set_quoted('USER_DATA_UNIT_PATH', userunitdir) +conf.set_quoted('USER_CONFIG_UNIT_DIR', join_paths(pkgsysconfdir, 'user')) +conf.set_quoted('USER_DATA_UNIT_DIR', userunitdir) conf.set_quoted('CERTIFICATE_ROOT', get_option('certificate-root')) conf.set_quoted('CATALOG_DATABASE', join_paths(catalogstatedir, 'database')) conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlibexecdir, 'systemd-cgroups-agent')) @@ -221,10 +223,10 @@ conf.set_quoted('ROOTPREFIX', rootprefixdir) conf.set_quoted('RANDOM_SEED_DIR', randomseeddir) conf.set_quoted('RANDOM_SEED', join_paths(randomseeddir, 'random-seed')) conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', join_paths(rootlibexecdir, 'systemd-cryptsetup')) -conf.set_quoted('SYSTEM_GENERATOR_PATH', systemgeneratordir) -conf.set_quoted('USER_GENERATOR_PATH', usergeneratordir) -conf.set_quoted('SYSTEM_ENV_GENERATOR_PATH', systemenvgeneratordir) -conf.set_quoted('USER_ENV_GENERATOR_PATH', userenvgeneratordir) +conf.set_quoted('SYSTEM_GENERATOR_DIR', systemgeneratordir) +conf.set_quoted('USER_GENERATOR_DIR', usergeneratordir) +conf.set_quoted('SYSTEM_ENV_GENERATOR_DIR', systemenvgeneratordir) +conf.set_quoted('USER_ENV_GENERATOR_DIR', userenvgeneratordir) conf.set_quoted('SYSTEM_SHUTDOWN_PATH', systemshutdowndir) conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir) conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', join_paths(pkgdatadir, 'kbd-model-map')) @@ -322,8 +324,6 @@ if want_libfuzzer endif elif want_ossfuzz fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine') -elif want_fuzzbuzz - fuzzing_engine = meson.get_compiler('cpp').find_library(get_option('fuzzbuzz-engine'), dirs: get_option('fuzzbuzz-engine-dir')) endif # Those generate many false positives, and we do not want to change the code to @@ -2506,7 +2506,7 @@ if conf.get('ENABLE_BINFMT') == 1 endif if conf.get('ENABLE_REPART') == 1 - executable('systemd-repart', + exe = executable('systemd-repart', systemd_repart_sources, include_directories : includes, link_with : [libshared], @@ -2518,6 +2518,12 @@ if conf.get('ENABLE_REPART') == 1 install_rpath : rootlibexecdir, install : true, install_dir : rootbindir) + + if want_tests != 'false' + test('test-repart', + test_repart_sh, + args : exe.full_path()) + endif endif if conf.get('ENABLE_VCONSOLE') == 1 @@ -2962,13 +2968,20 @@ if conf.get('ENABLE_NETWORKD') == 1 install_dir : rootbindir) public_programs += exe - executable('systemd-network-generator', + exe = executable('systemd-network-generator', network_generator_sources, include_directories : includes, link_with : [networkd_link_with], install_rpath : rootlibexecdir, install : true, install_dir : rootlibexecdir) + + if want_tests != 'false' + test('test-network-generator-conversion', + test_network_generator_conversion_sh, + # https://github.com/mesonbuild/meson/issues/2681 + args : exe.full_path()) + endif endif executable('systemd-sulogin-shell', @@ -3099,7 +3112,7 @@ foreach tuple : fuzzers incs = tuple.length() >= 5 ? tuple[4] : includes link_args = [] - if want_ossfuzz or want_fuzzbuzz + if want_ossfuzz dependencies += fuzzing_engine elif want_libfuzzer if fuzzing_engine.found() @@ -3111,10 +3124,6 @@ foreach tuple : fuzzers sources += 'src/fuzz/fuzz-main.c' endif - if want_fuzzbuzz - sources += 'src/fuzz/fuzzer-entry-point.c' - endif - name = sources[0].split('/')[-1].split('.')[0] fuzzer_exes += executable( @@ -3474,6 +3483,7 @@ foreach tuple : [ ['debug siphash'], ['valgrind', conf.get('VALGRIND') == 1], ['trace logging', conf.get('LOG_TRACE') == 1], + ['install tests', install_tests], ['link-udev-shared', get_option('link-udev-shared')], ['link-systemctl-shared', get_option('link-systemctl-shared')], ['link-networkd-shared', get_option('link-networkd-shared')], diff --git a/meson_options.txt b/meson_options.txt index 4988d41ff3..d1c752fda2 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -354,9 +354,3 @@ option('oss-fuzz', type : 'boolean', value : 'false', description : 'build against oss-fuzz') option('llvm-fuzz', type : 'boolean', value : 'false', description : 'build against LLVM libFuzzer') -option('fuzzbuzz', type : 'boolean', value : 'false', - description : 'build against FuzzBuzz') -option('fuzzbuzz-engine', type : 'string', - description : 'the name of the FuzzBuzz fuzzing engine') -option('fuzzbuzz-engine-dir', type : 'string', - description : 'the directory where the FuzzBuzz fuzzing engine is') diff --git a/presets/90-systemd.preset b/presets/90-systemd.preset index dc9d02f0b9..2b4d625fc9 100644 --- a/presets/90-systemd.preset +++ b/presets/90-systemd.preset @@ -19,6 +19,9 @@ enable getty@.service enable systemd-timesyncd.service enable systemd-networkd.service enable systemd-resolved.service +enable systemd-homed.service +enable systemd-userdbd.socket +enable systemd-pstore.service disable console-getty.service disable debug-shell.service @@ -30,14 +33,17 @@ enable reboot.target disable rescue.target disable exit.target +disable systemd-networkd-wait-online.service +disable systemd-time-wait-sync.service +disable systemd-boot-check-no-failures.service +disable systemd-network-generator.service + disable syslog.socket disable systemd-journal-gatewayd.* disable systemd-journal-remote.* disable systemd-journal-upload.* -enable systemd-pstore.service - # Passive targets: always off by default, since they should only be pulled in # by dependent units. diff --git a/semaphoreci/semaphore-runner.sh b/semaphoreci/semaphore-runner.sh index 2bf8ce0d52..04f6ee2605 100755 --- a/semaphoreci/semaphore-runner.sh +++ b/semaphoreci/semaphore-runner.sh @@ -5,7 +5,7 @@ set -eux # default to Debian testing DISTRO=${DISTRO:-debian} RELEASE=${RELEASE:-buster} -BRANCH=${BRANCH:-debian/master} +BRANCH=${BRANCH:-upstream-ci} ARCH=${ARCH:-amd64} CONTAINER=${RELEASE}-${ARCH} CACHE_DIR=${SEMAPHORE_CACHE_DIR:=/tmp} @@ -17,7 +17,7 @@ PHASES=(${@:-SETUP RUN}) create_container() { # create autopkgtest LXC image; this sometimes fails with "Unable to fetch # GPG key from keyserver", so retry a few times - for retry in $(seq 5); do + for retry in {1..5}; do sudo lxc-create -n $CONTAINER -t download -- -d $DISTRO -r $RELEASE -a $ARCH --keyserver hkp://keyserver.ubuntu.com:80 && break sleep $((retry*retry)) done diff --git a/shell-completion/zsh/_machinectl b/shell-completion/zsh/_machinectl index 5ffb7e8b9f..5955c765aa 100644 --- a/shell-completion/zsh/_machinectl +++ b/shell-completion/zsh/_machinectl @@ -28,6 +28,7 @@ "start:Start container as a service" "stop:Stop container (equal to poweroff)" "login:Get a login prompt on a VM/container" + "shell:Invoke a shell (or other command) in a container" "enable:Enable automatic container start at boot" "disable:Disable automatic container start at boot" "poweroff:Power off one or more VMs/containers" diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c index 93237646cc..9dbebfa167 100644 --- a/src/basic/capability-util.c +++ b/src/basic/capability-util.c @@ -107,7 +107,13 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) { unsigned long i; int r; - /* Add the capabilities to the ambient set. */ + /* Add the capabilities to the ambient set (an possibly also the inheritable set) */ + + /* Check that we can use PR_CAP_AMBIENT or quit early. */ + if (!ambient_capabilities_supported()) + return (set & all_capabilities()) == 0 ? + 0 : -EOPNOTSUPP; /* if actually no ambient caps are to be set, be silent, + * otherwise fail recognizably */ if (also_inherit) { caps = cap_get_proc(); diff --git a/src/basic/copy.c b/src/basic/copy.c index 97d566c5b9..b384010ae3 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -15,6 +15,7 @@ #include "copy.h" #include "dirent-util.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "io-util.h" #include "macro.h" @@ -569,10 +570,9 @@ static int fd_copy_directory( if (fdf < 0) return -errno; - d = fdopendir(fdf); + d = take_fdopendir(&fdf); if (!d) return -errno; - fdf = -1; exists = false; if (copy_flags & COPY_MERGE_EMPTY) { diff --git a/src/basic/escape.c b/src/basic/escape.c index c5c44d2e7d..116efa4119 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -518,22 +518,28 @@ char* shell_maybe_quote(const char *s, EscapeStyle style) { return NULL; t = r; - if (style == ESCAPE_BACKSLASH) + switch (style) { + case ESCAPE_BACKSLASH: + case ESCAPE_BACKSLASH_ONELINE: *(t++) = '"'; - else if (style == ESCAPE_POSIX) { + break; + case ESCAPE_POSIX: *(t++) = '$'; *(t++) = '\''; - } else + break; + default: assert_not_reached("Bad EscapeStyle"); + } t = mempcpy(t, s, p - s); - if (style == ESCAPE_BACKSLASH) - t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false); + if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE)) + t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, + style == ESCAPE_BACKSLASH_ONELINE); else t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true); - if (style == ESCAPE_BACKSLASH) + if (IN_SET(style, ESCAPE_BACKSLASH, ESCAPE_BACKSLASH_ONELINE)) *(t++) = '"'; else *(t++) = '\''; diff --git a/src/basic/escape.h b/src/basic/escape.h index b8eb137c3d..0b00b116ed 100644 --- a/src/basic/escape.h +++ b/src/basic/escape.h @@ -34,8 +34,13 @@ typedef enum UnescapeFlags { } UnescapeFlags; typedef enum EscapeStyle { - ESCAPE_BACKSLASH = 1, - ESCAPE_POSIX = 2, + ESCAPE_BACKSLASH = 1, /* Add shell quotes ("") so the shell will consider this a single + argument, possibly multiline. Tabs and newlines are not escaped. */ + ESCAPE_BACKSLASH_ONELINE = 2, /* Similar to ESCAPE_BACKSLASH, but always produces a single-line + string instead. Shell escape sequences are produced for tabs and + newlines. */ + ESCAPE_POSIX = 3, /* Similar to ESCAPE_BACKSLASH_ONELINE, but uses POSIX shell escape + * syntax (a string enclosed in $'') instead of plain quotes. */ } EscapeStyle; char *cescape(const char *s); diff --git a/src/basic/fileio.c b/src/basic/fileio.c index fe0c4f4707..4c365ad6fa 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -54,6 +54,44 @@ int fdopen_unlocked(int fd, const char *options, FILE **ret) { return 0; } +int take_fdopen_unlocked(int *fd, const char *options, FILE **ret) { + int r; + + assert(fd); + + r = fdopen_unlocked(*fd, options, ret); + if (r < 0) + return r; + + *fd = -1; + + return 0; +} + +FILE* take_fdopen(int *fd, const char *options) { + assert(fd); + + FILE *f = fdopen(*fd, options); + if (!f) + return NULL; + + *fd = -1; + + return f; +} + +DIR* take_fdopendir(int *dfd) { + assert(dfd); + + DIR *d = fdopendir(*dfd); + if (!d) + return NULL; + + *dfd = -1; + + return d; +} + FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc) { FILE *f = open_memstream(ptr, sizeloc); if (!f) diff --git a/src/basic/fileio.h b/src/basic/fileio.h index e6fea2afd4..58daabaa8f 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -39,6 +39,9 @@ typedef enum { int fopen_unlocked(const char *path, const char *options, FILE **ret); int fdopen_unlocked(int fd, const char *options, FILE **ret); +int take_fdopen_unlocked(int *fd, const char *options, FILE **ret); +FILE* take_fdopen(int *fd, const char *options); +DIR* take_fdopendir(int *dfd); FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc); FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode); diff --git a/src/basic/log.c b/src/basic/log.c index 17557e1844..ca024d970e 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -51,6 +51,7 @@ static bool syslog_is_stream = false; static bool show_color = false; static bool show_location = false; +static bool show_time = false; static bool upgrade_syslog_to_journal = false; static bool always_reopen_console = false; @@ -332,8 +333,10 @@ static int write_to_console( const char *func, const char *buffer) { - char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2]; - struct iovec iovec[6] = {}; + char location[256], + header_time[FORMAT_TIMESTAMP_MAX], + prefix[1 + DECIMAL_STR_MAX(int) + 2]; + struct iovec iovec[8] = {}; const char *on = NULL, *off = NULL; size_t n = 0; @@ -345,6 +348,13 @@ static int write_to_console( iovec[n++] = IOVEC_MAKE_STRING(prefix); } + if (show_time) { + if (format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) { + iovec[n++] = IOVEC_MAKE_STRING(header_time); + iovec[n++] = IOVEC_MAKE_STRING(" "); + } + } + if (show_color) get_log_colors(LOG_PRI(level), &on, &off, NULL); @@ -1099,6 +1109,12 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (log_show_location_from_string(value ?: "1") < 0) log_warning("Failed to parse log location setting '%s'. Ignoring.", value); + + } else if (proc_cmdline_key_streq(key, "systemd.log_time")) { + + if (log_show_time_from_string(value ?: "1") < 0) + log_warning("Failed to parse log time setting '%s'. Ignoring.", value); + } return 0; @@ -1130,6 +1146,10 @@ void log_parse_environment_realm(LogRealm realm) { e = getenv("SYSTEMD_LOG_LOCATION"); if (e && log_show_location_from_string(e) < 0) log_warning("Failed to parse log location '%s'. Ignoring.", e); + + e = getenv("SYSTEMD_LOG_TIME"); + if (e && log_show_time_from_string(e) < 0) + log_warning("Failed to parse log time '%s'. Ignoring.", e); } LogTarget log_get_target(void) { @@ -1156,6 +1176,14 @@ bool log_get_show_location(void) { return show_location; } +void log_show_time(bool b) { + show_time = b; +} + +bool log_get_show_time(void) { + return show_time; +} + int log_show_color_from_string(const char *e) { int t; @@ -1178,6 +1206,17 @@ int log_show_location_from_string(const char *e) { return 0; } +int log_show_time_from_string(const char *e) { + int t; + + t = parse_boolean(e); + if (t < 0) + return t; + + log_show_time(t); + return 0; +} + bool log_on_console(void) { if (IN_SET(log_target, LOG_TARGET_CONSOLE, LOG_TARGET_CONSOLE_PREFIXED)) diff --git a/src/basic/log.h b/src/basic/log.h index 740fdbf617..2c1b00fb88 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -59,9 +59,12 @@ void log_show_color(bool b); bool log_get_show_color(void) _pure_; void log_show_location(bool b); bool log_get_show_location(void) _pure_; +void log_show_time(bool b); +bool log_get_show_time(void) _pure_; int log_show_color_from_string(const char *e); int log_show_location_from_string(const char *e); +int log_show_time_from_string(const char *e); LogTarget log_get_target(void) _pure_; int log_get_max_level_realm(LogRealm realm) _pure_; diff --git a/src/basic/meson.build b/src/basic/meson.build index ccb22e1595..5bb49ef401 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -159,6 +159,8 @@ basic_sources = files(''' ordered-set.h parse-util.c parse-util.h + path-lookup.c + path-lookup.h path-util.c path-util.h prioq.c @@ -169,6 +171,7 @@ basic_sources = files(''' process-util.h procfs-util.c procfs-util.h + pthread-util.h quota-util.c quota-util.h random-util.c diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index e0094b0f37..8de5cd5c56 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -395,7 +395,7 @@ int safe_atoi(const char *s, int *ret_i) { return 0; } -int safe_atollu(const char *s, long long unsigned *ret_llu) { +int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu) { char *x = NULL; unsigned long long l; @@ -404,7 +404,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) { s += strspn(s, WHITESPACE); errno = 0; - l = strtoull(s, &x, 0); + l = strtoull(s, &x, base); if (errno > 0) return -errno; if (!x || x == s || *x != 0) diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index 36d76ba576..970bdefbf0 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -28,7 +28,6 @@ static inline int safe_atou(const char *s, unsigned *ret_u) { } int safe_atoi(const char *s, int *ret_i); -int safe_atollu(const char *s, unsigned long long *ret_u); int safe_atolli(const char *s, long long int *ret_i); int safe_atou8(const char *s, uint8_t *ret); @@ -59,6 +58,12 @@ static inline int safe_atoi32(const char *s, int32_t *ret_i) { return safe_atoi(s, (int*) ret_i); } +int safe_atollu_full(const char *s, unsigned base, long long unsigned *ret_llu); + +static inline int safe_atollu(const char *s, long long unsigned *ret_llu) { + return safe_atollu_full(s, 0, ret_llu); +} + static inline int safe_atou64(const char *s, uint64_t *ret_u) { assert_cc(sizeof(uint64_t) == sizeof(unsigned long long)); return safe_atollu(s, (unsigned long long*) ret_u); @@ -69,6 +74,11 @@ static inline int safe_atoi64(const char *s, int64_t *ret_i) { return safe_atolli(s, (long long int*) ret_i); } +static inline int safe_atoux64(const char *s, uint64_t *ret) { + assert_cc(sizeof(int64_t) == sizeof(long long unsigned)); + return safe_atollu_full(s, 16, (long long unsigned*) ret); +} + #if LONG_MAX == INT_MAX static inline int safe_atolu(const char *s, unsigned long *ret_u) { assert_cc(sizeof(unsigned long) == sizeof(unsigned)); diff --git a/src/shared/path-lookup.c b/src/basic/path-lookup.c index 2707dce7a8..52968dee34 100644 --- a/src/shared/path-lookup.c +++ b/src/basic/path-lookup.c @@ -6,19 +6,15 @@ #include "alloc-util.h" #include "fs-util.h" -#include "install.h" #include "log.h" #include "macro.h" -#include "mkdir.h" #include "path-lookup.h" #include "path-util.h" -#include "rm-rf.h" #include "stat-util.h" #include "string-util.h" #include "strv.h" #include "tmpfile-util.h" #include "user-util.h" -#include "util.h" int xdg_user_runtime_dir(char **ret, const char *suffix) { const char *e; @@ -100,14 +96,14 @@ int xdg_user_data_dir(char **ret, const char *suffix) { static const char* const user_data_unit_paths[] = { "/usr/local/lib/systemd/user", "/usr/local/share/systemd/user", - USER_DATA_UNIT_PATH, + USER_DATA_UNIT_DIR, "/usr/lib/systemd/user", "/usr/share/systemd/user", NULL }; static const char* const user_config_unit_paths[] = { - USER_CONFIG_UNIT_PATH, + USER_CONFIG_UNIT_DIR, "/etc/systemd/user", NULL }; @@ -325,12 +321,12 @@ static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **ru switch (scope) { case UNIT_FILE_SYSTEM: - a = strdup(SYSTEM_CONFIG_UNIT_PATH); + a = strdup(SYSTEM_CONFIG_UNIT_DIR); b = strdup("/run/systemd/system"); break; case UNIT_FILE_GLOBAL: - a = strdup(USER_CONFIG_UNIT_PATH); + a = strdup(USER_CONFIG_UNIT_DIR); b = strdup("/run/systemd/user"); break; @@ -618,7 +614,7 @@ int lookup_paths_init( STRV_IFNOTNULL(transient), STRV_IFNOTNULL(generator_early), persistent_config, - SYSTEM_CONFIG_UNIT_PATH, + SYSTEM_CONFIG_UNIT_DIR, "/etc/systemd/system", STRV_IFNOTNULL(persistent_attached), runtime_config, @@ -642,7 +638,7 @@ int lookup_paths_init( STRV_IFNOTNULL(transient), STRV_IFNOTNULL(generator_early), persistent_config, - USER_CONFIG_UNIT_PATH, + USER_CONFIG_UNIT_DIR, "/etc/systemd/user", runtime_config, "/run/systemd/user", @@ -650,7 +646,7 @@ int lookup_paths_init( "/usr/local/share/systemd/user", "/usr/share/systemd/user", "/usr/local/lib/systemd/user", - USER_DATA_UNIT_PATH, + USER_DATA_UNIT_DIR, "/usr/lib/systemd/user", STRV_IFNOTNULL(generator_late)); break; @@ -783,56 +779,6 @@ void lookup_paths_log(LookupPaths *p) { } } -int lookup_paths_mkdir_generator(LookupPaths *p) { - int r, q; - - assert(p); - - if (!p->generator || !p->generator_early || !p->generator_late) - return -EINVAL; - - r = mkdir_p_label(p->generator, 0755); - - q = mkdir_p_label(p->generator_early, 0755); - if (q < 0 && r >= 0) - r = q; - - q = mkdir_p_label(p->generator_late, 0755); - if (q < 0 && r >= 0) - r = q; - - return r; -} - -void lookup_paths_trim_generator(LookupPaths *p) { - assert(p); - - /* Trim empty dirs */ - - if (p->generator) - (void) rmdir(p->generator); - if (p->generator_early) - (void) rmdir(p->generator_early); - if (p->generator_late) - (void) rmdir(p->generator_late); -} - -void lookup_paths_flush_generator(LookupPaths *p) { - assert(p); - - /* Flush the generated unit files in full */ - - if (p->generator) - (void) rm_rf(p->generator, REMOVE_ROOT|REMOVE_PHYSICAL); - if (p->generator_early) - (void) rm_rf(p->generator_early, REMOVE_ROOT|REMOVE_PHYSICAL); - if (p->generator_late) - (void) rm_rf(p->generator_late, REMOVE_ROOT|REMOVE_PHYSICAL); - - if (p->temporary_dir) - (void) rm_rf(p->temporary_dir, REMOVE_ROOT|REMOVE_PHYSICAL); -} - char **generator_binary_paths(UnitFileScope scope) { bool append = false; /* Add items from SYSTEMD_GENERATOR_PATH before normal directories */ _cleanup_strv_free_ char **paths = NULL; @@ -852,7 +798,7 @@ char **generator_binary_paths(UnitFileScope scope) { add = strv_new("/run/systemd/system-generators", "/etc/systemd/system-generators", "/usr/local/lib/systemd/system-generators", - SYSTEM_GENERATOR_PATH); + SYSTEM_GENERATOR_DIR); break; case UNIT_FILE_GLOBAL: @@ -860,7 +806,7 @@ char **generator_binary_paths(UnitFileScope scope) { add = strv_new("/run/systemd/user-generators", "/etc/systemd/user-generators", "/usr/local/lib/systemd/user-generators", - USER_GENERATOR_PATH); + USER_GENERATOR_DIR); break; default: @@ -899,12 +845,12 @@ char **env_generator_binary_paths(bool is_system) { add = strv_new("/run/systemd/system-environment-generators", "/etc/systemd/system-environment-generators", "/usr/local/lib/systemd/system-environment-generators", - SYSTEM_ENV_GENERATOR_PATH); + SYSTEM_ENV_GENERATOR_DIR); else add = strv_new("/run/systemd/user-environment-generators", "/etc/systemd/user-environment-generators", "/usr/local/lib/systemd/user-environment-generators", - USER_ENV_GENERATOR_PATH); + USER_ENV_GENERATOR_DIR); if (!add) return NULL; diff --git a/src/shared/path-lookup.h b/src/basic/path-lookup.h index b99e918144..ae37f9feb9 100644 --- a/src/shared/path-lookup.h +++ b/src/basic/path-lookup.h @@ -5,6 +5,7 @@ typedef struct LookupPaths LookupPaths; +#include "def.h" #include "unit-file.h" #include "macro.h" @@ -64,12 +65,10 @@ bool path_is_user_data_dir(const char *path); bool path_is_user_config_dir(const char *path); void lookup_paths_log(LookupPaths *p); - -int lookup_paths_mkdir_generator(LookupPaths *p); -void lookup_paths_trim_generator(LookupPaths *p); -void lookup_paths_flush_generator(LookupPaths *p); - void lookup_paths_free(LookupPaths *p); char **generator_binary_paths(UnitFileScope scope); char **env_generator_binary_paths(bool is_system); + +#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network")) +#define NETWORK_DIRS_NULSTR CONF_PATHS_NULSTR("systemd/network") diff --git a/src/basic/process-util.c b/src/basic/process-util.c index b84515fb21..704d668253 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1195,6 +1195,11 @@ int must_be_root(void) { return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root."); } +static void restore_sigsetp(sigset_t **ssp) { + if (*ssp) + (void) sigprocmask(SIG_SETMASK, *ssp, NULL); +} + int safe_fork_full( const char *name, const int except_fds[], @@ -1204,7 +1209,8 @@ int safe_fork_full( pid_t original_pid, pid; sigset_t saved_ss, ss; - bool block_signals = false; + _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL; + bool block_signals = false, block_all = false; int prio, r; /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always @@ -1219,7 +1225,7 @@ int safe_fork_full( * be sure that SIGTERMs are not lost we might send to the child. */ assert_se(sigfillset(&ss) >= 0); - block_signals = true; + block_signals = block_all = true; } else if (flags & FORK_WAIT) { /* Let's block SIGCHLD at least, so that we can safely watch for the child process */ @@ -1229,28 +1235,31 @@ int safe_fork_full( block_signals = true; } - if (block_signals) + if (block_signals) { if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0) return log_full_errno(prio, errno, "Failed to set signal mask: %m"); + saved_ssp = &saved_ss; + } if (flags & FORK_NEW_MOUNTNS) pid = raw_clone(SIGCHLD|CLONE_NEWNS); else pid = fork(); - if (pid < 0) { - r = -errno; - - if (block_signals) /* undo what we did above */ - (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL); - - return log_full_errno(prio, r, "Failed to fork: %m"); - } + if (pid < 0) + return log_full_errno(prio, errno, "Failed to fork: %m"); if (pid > 0) { /* We are in the parent process */ log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid); if (flags & FORK_WAIT) { + if (block_all) { + /* undo everything except SIGCHLD */ + ss = saved_ss; + assert_se(sigaddset(&ss, SIGCHLD) >= 0); + (void) sigprocmask(SIG_SETMASK, &ss, NULL); + } + r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0)); if (r < 0) return r; @@ -1258,9 +1267,6 @@ int safe_fork_full( return -EPROTO; } - if (block_signals) /* undo what we did above */ - (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL); - if (ret_pid) *ret_pid = pid; @@ -1269,6 +1275,9 @@ int safe_fork_full( /* We are in the child process */ + /* Restore signal mask manually */ + saved_ssp = NULL; + if (flags & FORK_REOPEN_LOG) { /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */ log_close(); diff --git a/src/basic/pthread-util.h b/src/basic/pthread-util.h new file mode 100644 index 0000000000..dc3eaba436 --- /dev/null +++ b/src/basic/pthread-util.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include <pthread.h> + +#include "macro.h" + +static inline pthread_mutex_t* pthread_mutex_lock_assert(pthread_mutex_t *mutex) { + assert_se(pthread_mutex_lock(mutex) == 0); + return mutex; +} + +static inline void pthread_mutex_unlock_assertp(pthread_mutex_t **mutexp) { + if (*mutexp) + assert_se(pthread_mutex_unlock(*mutexp) == 0); +} diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c index 2d5e750ea5..33ff427ae7 100644 --- a/src/basic/selinux-util.c +++ b/src/basic/selinux-util.c @@ -44,8 +44,10 @@ static struct selabel_handle *label_hnd = NULL; bool mac_selinux_use(void) { #if HAVE_SELINUX - if (cached_use < 0) + if (_unlikely_(cached_use < 0)) { cached_use = is_selinux_enabled() > 0; + log_debug("SELinux enabled state cached to: %s", cached_use ? "enabled" : "disabled"); + } return cached_use; #else @@ -55,14 +57,15 @@ bool mac_selinux_use(void) { bool mac_selinux_enforcing(void) { #if HAVE_SELINUX - if (cached_enforcing < 0) { + if (_unlikely_(cached_enforcing < 0)) { cached_enforcing = security_getenforce(); - if (cached_enforcing == -1) { - log_error_errno(errno, "Failed to get SELinux enforced status: %m"); - } + if (cached_enforcing == -1) + log_error_errno(errno, "Failed to get SELinux enforced status, continue in enforcing mode: %m"); + else + log_debug("SELinux enforcing state cached to: %s", cached_enforcing ? "enforcing" : "permissive"); } - /* treat failure as enforced mode */ + /* treat failure as enforcing mode */ return (cached_enforcing != 0); #else return false; @@ -80,6 +83,8 @@ void mac_selinux_retest(void) { static int setenforce_callback(int enforcing) { cached_enforcing = enforcing; + log_debug("SELinux enforcing state updated to: %s", cached_enforcing ? "enforcing" : "permissive"); + return 0; } #endif diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c index 8ef90e96b7..5412ccbf7d 100644 --- a/src/basic/stat-util.c +++ b/src/basic/stat-util.c @@ -10,6 +10,7 @@ #include "alloc-util.h" #include "dirent-util.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "macro.h" #include "missing_fs.h" @@ -77,10 +78,9 @@ int dir_is_empty_at(int dir_fd, const char *path) { if (fd < 0) return -errno; - d = fdopendir(fd); + d = take_fdopendir(&fd); if (!d) return -errno; - fd = -1; FOREACH_DIRENT(de, d, return -errno) return 0; diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 8f812d7cbe..9983aa826e 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -113,7 +113,7 @@ static size_t strcspn_escaped(const char *s, const char *reject) { bool escaped = false; int n; - for (n=0; s[n]; n++) { + for (n = 0; s[n] != '\0'; n++) { if (escaped) escaped = false; else if (s[n] == '\\') @@ -122,50 +122,62 @@ static size_t strcspn_escaped(const char *s, const char *reject) { break; } - /* if s ends in \, return index of previous char */ - return n - escaped; + return n; } /* Split a string into words. */ -const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags) { +const char* split( + const char **state, + size_t *l, + const char *separator, + SplitFlags flags) { + const char *current; + assert(state); + assert(l); + + if (!separator) + separator = WHITESPACE; + current = *state; - if (!*current) { - assert(**state == '\0'); + if (*current == '\0') /* already at the end? */ return NULL; - } - current += strspn(current, separator); - if (!*current) { + current += strspn(current, separator); /* skip leading separators */ + if (*current == '\0') { /* at the end now? */ *state = current; return NULL; } - if (flags & SPLIT_QUOTES && strchr("\'\"", *current)) { - char quotechars[2] = {*current, '\0'}; - - *l = strcspn_escaped(current + 1, quotechars); - if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] || - (current[*l + 2] && !strchr(separator, current[*l + 2]))) { - /* right quote missing or garbage at the end */ - if (flags & SPLIT_RELAX) { - *state = current + *l + 1 + (current[*l + 1] != '\0'); - return current + 1; + if (FLAGS_SET(flags, SPLIT_QUOTES)) { + + if (strchr(QUOTES, *current)) { + /* We are looking at a quote */ + *l = strcspn_escaped(current + 1, CHAR_TO_STR(*current)); + if (current[*l + 1] != *current || + (current[*l + 2] != 0 && !strchr(separator, current[*l + 2]))) { + /* right quote missing or garbage at the end */ + if (FLAGS_SET(flags, SPLIT_RELAX)) { + *state = current + *l + 1 + (current[*l + 1] != '\0'); + return current + 1; + } + *state = current; + return NULL; } - *state = current; - return NULL; - } - *state = current++ + *l + 2; - } else if (flags & SPLIT_QUOTES) { - *l = strcspn_escaped(current, separator); - if (current[*l] && !strchr(separator, current[*l]) && !(flags & SPLIT_RELAX)) { - /* unfinished escape */ - *state = current; - return NULL; + *state = current++ + *l + 2; + + } else { + /* We are looking at a something that is not a quote */ + *l = strcspn_escaped(current, separator); + if (current[*l] && !strchr(separator, current[*l]) && !FLAGS_SET(flags, SPLIT_RELAX)) { + /* unfinished escape */ + *state = current; + return NULL; + } + *state = current + *l; } - *state = current + *l; } else { *l = strcspn(current, separator); *state = current + *l; diff --git a/src/basic/string-util.h b/src/basic/string-util.h index f98fbdddda..2a344b996f 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -112,8 +112,10 @@ typedef enum SplitFlags { SPLIT_RELAX = 0x01 << 1, } SplitFlags; +/* Smelly. Do not use this anymore. Use extract_first_word() instead! */ const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags); +/* Similar, don't use this anymore */ #define FOREACH_WORD(word, length, s, state) \ _FOREACH_WORD(word, length, s, WHITESPACE, 0, state) diff --git a/src/basic/strv.h b/src/basic/strv.h index e7c2b1a604..dd3323c223 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -87,6 +87,16 @@ char **strv_parse_nulstr(const char *s, size_t l); char **strv_split_nulstr(const char *s); int strv_make_nulstr(char * const *l, char **p, size_t *n); +static inline int strv_from_nulstr(char ***a, const char *nulstr) { + char **t; + + t = strv_split_nulstr(nulstr); + if (!t) + return -ENOMEM; + *a = t; + return 0; +} + bool strv_overlap(char * const *a, char * const *b) _pure_; #define STRV_FOREACH(s, l) \ diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index efc22b1591..c7570c7a61 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -30,7 +30,7 @@ /* Underlined */ #define ANSI_HIGHLIGHT_RED_UNDERLINE "\x1B[0;1;4;31m" #define ANSI_HIGHLIGHT_GREEN_UNDERLINE "\x1B[0;1;4;32m" -#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;33m" +#define ANSI_HIGHLIGHT_YELLOW_UNDERLINE "\x1B[0;1;4;38;5;185m" #define ANSI_HIGHLIGHT_BLUE_UNDERLINE "\x1B[0;1;4;34m" #define ANSI_HIGHLIGHT_MAGENTA_UNDERLINE "\x1B[0;1;4;35m" #define ANSI_HIGHLIGHT_GREY_UNDERLINE "\x1B[0;1;4;38;5;245m" diff --git a/src/basic/tmpfile-util.c b/src/basic/tmpfile-util.c index decdafb9c9..9cbca312fc 100644 --- a/src/basic/tmpfile-util.c +++ b/src/basic/tmpfile-util.c @@ -48,14 +48,12 @@ int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) { /* This assumes that returned FILE object is short-lived and used within the same single-threaded * context and never shared externally, hence locking is not necessary. */ - r = fdopen_unlocked(fd, "w", &f); + r = take_fdopen_unlocked(&fd, "w", &f); if (r < 0) { (void) unlink(t); return r; } - TAKE_FD(fd); - if (ret_f) *ret_f = TAKE_PTR(f); @@ -80,18 +78,16 @@ int mkostemp_safe(char *pattern) { } int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) { - int fd; + _cleanup_close_ int fd = -1; FILE *f; fd = mkostemp_safe(pattern); if (fd < 0) return fd; - f = fdopen(fd, mode); - if (!f) { - safe_close(fd); + f = take_fdopen(&fd, mode); + if (!f) return -errno; - } *ret_f = f; return 0; diff --git a/src/basic/user-util.c b/src/basic/user-util.c index a491f5505e..1510fc96ef 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -701,16 +701,18 @@ int take_etc_passwd_lock(const char *root) { bool valid_user_group_name_full(const char *u, bool strict) { const char *i; long sz; + bool warned = false; /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules: * * - We require that names fit into the appropriate utmp field * - We don't allow empty user names - * - No dots or digits in the first character + * - No dots in the first character * * If strict==true, additionally: * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator) + * - We don't allow a digit as the first character * * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. */ @@ -720,17 +722,26 @@ bool valid_user_group_name_full(const char *u, bool strict) { if (!(u[0] >= 'a' && u[0] <= 'z') && !(u[0] >= 'A' && u[0] <= 'Z') && + !(u[0] >= '0' && u[0] <= '9' && !strict) && u[0] != '_') return false; - bool warned = false; + bool only_digits_seen = u[0] >= '0' && u[0] <= '9'; + + if (only_digits_seen) { + log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u); + warned = true; + } for (i = u+1; *i; i++) { if (((*i >= 'a' && *i <= 'z') || (*i >= 'A' && *i <= 'Z') || (*i >= '0' && *i <= '9') || - IN_SET(*i, '_', '-'))) + IN_SET(*i, '_', '-'))) { + if (!(*i >= '0' && *i <= '9')) + only_digits_seen = false; continue; + } if (*i == '.' && !strict) { if (!warned) { @@ -744,6 +755,9 @@ bool valid_user_group_name_full(const char *u, bool strict) { return false; } + if (only_digits_seen) + return false; + sz = sysconf(_SC_LOGIN_NAME_MAX); assert_se(sz > 0); @@ -764,10 +778,10 @@ bool valid_user_group_name_or_id_full(const char *u, bool strict) { if (isempty(u)) return false; - if (valid_user_group_name_full(u, strict)) + if (parse_uid(u, NULL) >= 0) return true; - return parse_uid(u, NULL) >= 0; + return valid_user_group_name_full(u, strict); } bool valid_gecos(const char *d) { diff --git a/src/basic/virt.c b/src/basic/virt.c index 07831634da..f567696265 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -462,13 +462,14 @@ int detect_container(void) { goto finish; } - /* "Official" way of detecting WSL https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364 */ + /* "Official" way of detecting WSL https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364, + * ... and a working one, since the official one doesn't actually work ;( + */ r = read_one_line_file("/proc/sys/kernel/osrelease", &o); - if (r >= 0) { - if (strstr(o, "Microsoft") || strstr(o, "WSL")) { - r = VIRTUALIZATION_WSL; - goto finish; - } + if (r >= 0 && + (strstr(o, "Microsoft") || strstr(o, "microsoft") || strstr(o, "WSL"))) { + r = VIRTUALIZATION_WSL; + goto finish; } if (getpid_cached() == 1) { diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 5874b9ec68..1a2ea0ae65 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -982,8 +982,9 @@ static int install_loader_config(const char *esp_path, sd_id128_t machine_id) { char machine_string[SD_ID128_STRING_MAX]; _cleanup_(unlink_and_freep) char *t = NULL; _cleanup_fclose_ FILE *f = NULL; + _cleanup_close_ int fd = -1; const char *p; - int r, fd; + int r; p = prefix_roota(esp_path, "/loader/loader.conf"); if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */ @@ -993,11 +994,9 @@ static int install_loader_config(const char *esp_path, sd_id128_t machine_id) { if (fd < 0) return log_error_errno(fd, "Failed to open \"%s\" for writing: %m", p); - f = fdopen(fd, "w"); - if (!f) { - safe_close(fd); + f = take_fdopen(&fd, "w"); + if (!f) return log_oom(); - } fprintf(f, "#timeout 3\n" "#console-mode keep\n" diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c index 3c75be381f..3d03eb37a6 100644 --- a/src/busctl/busctl.c +++ b/src/busctl/busctl.c @@ -1200,7 +1200,6 @@ static int message_json(sd_bus_message *m, FILE *f) { JSON_BUILD_PAIR("endian", JSON_BUILD_STRING(e)), JSON_BUILD_PAIR("flags", JSON_BUILD_INTEGER(m->header->flags)), JSON_BUILD_PAIR("version", JSON_BUILD_INTEGER(m->header->version)), - JSON_BUILD_PAIR_CONDITION(m->priority != 0, "priority", JSON_BUILD_INTEGER(m->priority)), JSON_BUILD_PAIR("cookie", JSON_BUILD_INTEGER(BUS_MESSAGE_COOKIE(m))), JSON_BUILD_PAIR_CONDITION(m->reply_cookie != 0, "reply_cookie", JSON_BUILD_INTEGER(m->reply_cookie)), JSON_BUILD_PAIR_CONDITION(m->sender, "sender", JSON_BUILD_STRING(m->sender)), diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index e8be76e315..29b55c62eb 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -102,6 +102,7 @@ static int property_get_oom_score_adjust( ExecContext *c = userdata; int32_t n; + int r; assert(bus); assert(reply); @@ -113,13 +114,55 @@ static int property_get_oom_score_adjust( _cleanup_free_ char *t = NULL; n = 0; - if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0) - safe_atoi32(t, &n); + r = read_one_line_file("/proc/self/oom_score_adj", &t); + if (r < 0) + log_debug_errno(r, "Failed to read /proc/self/oom_score_adj, ignoring: %m"); + else { + r = safe_atoi32(t, &n); + if (r < 0) + log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/oom_score_adj, ignoring: %m", t); + } } return sd_bus_message_append(reply, "i", n); } +static int property_get_coredump_filter( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + uint64_t n; + int r; + + assert(bus); + assert(reply); + assert(c); + + if (c->coredump_filter_set) + n = c->coredump_filter; + else { + _cleanup_free_ char *t = NULL; + + n = COREDUMP_FILTER_MASK_DEFAULT; + r = read_one_line_file("/proc/self/coredump_filter", &t); + if (r < 0) + log_debug_errno(r, "Failed to read /proc/self/coredump_filter, ignoring: %m"); + else { + r = safe_atoux64(t, &n); + if (r < 0) + log_debug_errno(r, "Failed to parse \"%s\" from /proc/self/coredump_filter, ignoring: %m", t); + } + } + + return sd_bus_message_append(reply, "t", n); +} + static int property_get_nice( sd_bus *bus, const char *path, @@ -747,6 +790,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("CoredumpFilter", "t", property_get_coredump_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST), @@ -795,6 +839,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("ProtectClock", "b", bus_property_get_bool, offsetof(ExecContext, protect_clock), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProtectKernelLogs", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_logs), SD_BUS_VTABLE_PROPERTY_CONST), @@ -2189,6 +2234,21 @@ int bus_exec_context_set_transient_property( return 1; + } else if (streq(name, "CoredumpFilter")) { + uint64_t f; + + r = sd_bus_message_read(message, "t", &f); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->coredump_filter = f; + c->coredump_filter_set = true; + unit_write_settingf(u, flags, name, "CoredumpFilter=0x%"PRIx64, f); + } + + return 1; + } else if (streq(name, "EnvironmentFiles")) { _cleanup_free_ char *joined = NULL; diff --git a/src/core/device.c b/src/core/device.c index 06bbbf8d2c..8e00fd3df6 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -83,6 +83,8 @@ static int device_set_sysfs(Device *d, const char *sysfs) { } d->sysfs = TAKE_PTR(copy); + unit_add_to_dbus_queue(UNIT(d)); + return 0; } @@ -562,9 +564,6 @@ static int device_setup_unit(Manager *m, sd_device *dev, const char *path, bool if (dev && device_is_bound_by_mounts(DEVICE(u), dev)) device_upgrade_mount_deps(u); - /* Note that this won't dispatch the load queue, the caller has to do that if needed and appropriate */ - unit_add_to_dbus_queue(u); - return 0; fail: diff --git a/src/core/execute.c b/src/core/execute.c index 8e1e77b4b2..c59acad4ce 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -3323,6 +3323,14 @@ static int exec_child( } } + if (context->coredump_filter_set) { + r = set_coredump_filter(context->coredump_filter); + if (ERRNO_IS_PRIVILEGE(r)) + log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m"); + else if (r < 0) + return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m"); + } + if (context->nice_set) { r = setpriority_closest(context->nice); if (r < 0) @@ -4614,6 +4622,11 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { "%sOOMScoreAdjust: %i\n", prefix, c->oom_score_adjust); + if (c->coredump_filter_set) + fprintf(f, + "%sCoredumpFilter: 0x%"PRIx64"\n", + prefix, c->coredump_filter); + for (i = 0; i < RLIM_NLIMITS; i++) if (c->rlimit[i]) { fprintf(f, "%sLimit%s: " RLIM_FMT "\n", diff --git a/src/core/execute.h b/src/core/execute.h index 4baf5b1a40..f96a2915eb 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -14,6 +14,7 @@ typedef struct Manager Manager; #include <sys/capability.h> #include "cgroup-util.h" +#include "coredump-util.h" #include "cpu-set-util.h" #include "exec-util.h" #include "fdset.h" @@ -161,6 +162,7 @@ struct ExecContext { bool working_directory_home:1; bool oom_score_adjust_set:1; + bool coredump_filter_set:1; bool nice_set:1; bool ioprio_set:1; bool cpu_sched_set:1; @@ -179,6 +181,7 @@ struct ExecContext { int ioprio; int cpu_sched_policy; int cpu_sched_priority; + uint64_t coredump_filter; CPUSet cpu_set; NUMAPolicy numa_policy; diff --git a/src/core/generator-setup.c b/src/core/generator-setup.c new file mode 100644 index 0000000000..78ff590902 --- /dev/null +++ b/src/core/generator-setup.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include <unistd.h> + +#include "generator-setup.h" +#include "macro.h" +#include "mkdir.h" +#include "rm-rf.h" + +int lookup_paths_mkdir_generator(LookupPaths *p) { + int r, q; + + assert(p); + + if (!p->generator || !p->generator_early || !p->generator_late) + return -EINVAL; + + r = mkdir_p_label(p->generator, 0755); + + q = mkdir_p_label(p->generator_early, 0755); + if (q < 0 && r >= 0) + r = q; + + q = mkdir_p_label(p->generator_late, 0755); + if (q < 0 && r >= 0) + r = q; + + return r; +} + +void lookup_paths_trim_generator(LookupPaths *p) { + assert(p); + + /* Trim empty dirs */ + + if (p->generator) + (void) rmdir(p->generator); + if (p->generator_early) + (void) rmdir(p->generator_early); + if (p->generator_late) + (void) rmdir(p->generator_late); +} + +void lookup_paths_flush_generator(LookupPaths *p) { + assert(p); + + /* Flush the generated unit files in full */ + + if (p->generator) + (void) rm_rf(p->generator, REMOVE_ROOT|REMOVE_PHYSICAL); + if (p->generator_early) + (void) rm_rf(p->generator_early, REMOVE_ROOT|REMOVE_PHYSICAL); + if (p->generator_late) + (void) rm_rf(p->generator_late, REMOVE_ROOT|REMOVE_PHYSICAL); + + if (p->temporary_dir) + (void) rm_rf(p->temporary_dir, REMOVE_ROOT|REMOVE_PHYSICAL); +} diff --git a/src/core/generator-setup.h b/src/core/generator-setup.h new file mode 100644 index 0000000000..9688601a76 --- /dev/null +++ b/src/core/generator-setup.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "path-lookup.h" + +int lookup_paths_mkdir_generator(LookupPaths *p); +void lookup_paths_trim_generator(LookupPaths *p); +void lookup_paths_flush_generator(LookupPaths *p); diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 69abdb65ba..165b9ca9c1 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -28,6 +28,7 @@ $1.Group, config_parse_user_group_compat, 0, $1.SupplementaryGroups, config_parse_user_group_strv_compat, 0, offsetof($1, exec_context.supplementary_groups) $1.Nice, config_parse_exec_nice, 0, offsetof($1, exec_context) $1.OOMScoreAdjust, config_parse_exec_oom_score_adjust, 0, offsetof($1, exec_context) +$1.CoredumpFilter, config_parse_exec_coredump_filter, 0, offsetof($1, exec_context) $1.IOSchedulingClass, config_parse_exec_io_class, 0, offsetof($1, exec_context) $1.IOSchedulingPriority, config_parse_exec_io_priority, 0, offsetof($1, exec_context) $1.CPUSchedulingPolicy, config_parse_exec_cpu_sched_policy, 0, offsetof($1, exec_context) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 646364eb89..b4d6c522e4 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -592,6 +592,45 @@ int config_parse_exec_oom_score_adjust( return 0; } +int config_parse_exec_coredump_filter( + const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + ExecContext *c = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + if (isempty(rvalue)) { + c->coredump_filter = 0; + c->coredump_filter_set = false; + return 0; + } + + uint64_t f; + r = coredump_filter_mask_from_string(rvalue, &f); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse the CoredumpFilter=%s, ignoring: %m", rvalue); + return 0; + } + + c->coredump_filter |= f; + c->oom_score_adjust_set = true; + return 0; +} + int config_parse_exec( const char *unit, const char *filename, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index b6b46b2449..bc72ef7745 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -26,6 +26,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_socket_protocol); CONFIG_PARSER_PROTOTYPE(config_parse_socket_bind); CONFIG_PARSER_PROTOTYPE(config_parse_exec_nice); CONFIG_PARSER_PROTOTYPE(config_parse_exec_oom_score_adjust); +CONFIG_PARSER_PROTOTYPE(config_parse_exec_coredump_filter); CONFIG_PARSER_PROTOTYPE(config_parse_exec); CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout); CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout_abort); diff --git a/src/core/main.c b/src/core/main.c index f7cda72fdd..db6521b924 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -542,8 +542,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level"); DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target"); -DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" ); +DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color"); DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location"); +DEFINE_SETTER(config_parse_time, log_show_time_from_string, "time"); static int config_parse_default_timeout_abort( const char *unit, @@ -571,6 +572,7 @@ static int parse_config_file(void) { { "Manager", "LogTarget", config_parse_target, 0, NULL }, { "Manager", "LogColor", config_parse_color, 0, NULL }, { "Manager", "LogLocation", config_parse_location, 0, NULL }, + { "Manager", "LogTime", config_parse_time, 0, NULL }, { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core }, { "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt }, { "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt }, @@ -718,6 +720,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_LOG_TARGET, ARG_LOG_COLOR, ARG_LOG_LOCATION, + ARG_LOG_TIME, ARG_UNIT, ARG_SYSTEM, ARG_USER, @@ -745,6 +748,7 @@ static int parse_argv(int argc, char *argv[]) { { "log-target", required_argument, NULL, ARG_LOG_TARGET }, { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, + { "log-time", optional_argument, NULL, ARG_LOG_TIME }, { "unit", required_argument, NULL, ARG_UNIT }, { "system", no_argument, NULL, ARG_SYSTEM }, { "user", no_argument, NULL, ARG_USER }, @@ -818,6 +822,18 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_LOG_TIME: + + if (optarg) { + r = log_show_time_from_string(optarg); + if (r < 0) + return log_error_errno(r, "Failed to parse log time setting \"%s\": %m", + optarg); + } else + log_show_time(true); + + break; + case ARG_DEFAULT_STD_OUTPUT: r = exec_output_from_string(optarg); if (r < 0) @@ -1037,6 +1053,7 @@ static int help(void) { " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n" " --log-color[=BOOL] Highlight important log messages\n" " --log-location[=BOOL] Include code location in log messages\n" + " --log-time[=BOOL] Prefix log messages with current time\n" " --default-standard-output= Set default standard output for services\n" " --default-standard-error= Set default standard error output for services\n" "\nSee the %s for details.\n" @@ -1419,6 +1436,9 @@ static int become_shutdown( if (log_get_show_location()) command_line[pos++] = "--log-location"; + if (log_get_show_time()) + command_line[pos++] = "--log-time"; + if (streq(shutdown_verb, "exit")) { command_line[pos++] = "--exit-code"; command_line[pos++] = exit_code; @@ -2561,7 +2581,7 @@ int main(int argc, char *argv[]) { if (!skip_setup) kmod_setup(); - r = mount_setup(loaded_policy); + r = mount_setup(loaded_policy, skip_setup); if (r < 0) { error_message = "Failed to mount API filesystems"; goto finish; diff --git a/src/core/manager.c b/src/core/manager.c index 38f7ba1eb8..4a11054e05 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -44,6 +44,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "generator-setup.h" #include "hashmap.h" #include "install.h" #include "io-util.h" @@ -689,7 +690,7 @@ static int manager_setup_prefix(Manager *m) { p = paths_user; for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++) { - r = sd_path_home(p[i].type, p[i].suffix, &m->prefix[i]); + r = sd_path_lookup(p[i].type, p[i].suffix, &m->prefix[i]); if (r < 0) return r; } @@ -3106,7 +3107,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) { } int manager_open_serialization(Manager *m, FILE **_f) { - int fd; + _cleanup_close_ int fd = -1; FILE *f; assert(_f); @@ -3115,11 +3116,9 @@ int manager_open_serialization(Manager *m, FILE **_f) { if (fd < 0) return fd; - f = fdopen(fd, "w+"); - if (!f) { - safe_close(fd); + f = take_fdopen(&fd, "w+"); + if (!f) return -errno; - } *_f = f; return 0; @@ -4248,6 +4247,11 @@ ManagerState manager_state(Manager *m) { assert(m); + /* Is the special shutdown target active or queued? If so, we are in shutdown state */ + u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET); + if (u && unit_active_or_pending(u)) + return MANAGER_STOPPING; + /* Did we ever finish booting? If not then we are still starting up */ if (!MANAGER_IS_FINISHED(m)) { @@ -4258,11 +4262,6 @@ ManagerState manager_state(Manager *m) { return MANAGER_STARTING; } - /* Is the special shutdown target active or queued? If so, we are in shutdown state */ - u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET); - if (u && unit_active_or_pending(u)) - return MANAGER_STOPPING; - if (MANAGER_IS_SYSTEM(m)) { /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */ u = manager_get_unit(m, SPECIAL_RESCUE_TARGET); diff --git a/src/core/meson.build b/src/core/meson.build index 3586838f59..0b31bb79ed 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -72,6 +72,8 @@ libcore_sources = ''' emergency-action.h execute.c execute.h + generator-setup.c + generator-setup.h hostname-setup.c hostname-setup.h ima-setup.c diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 284e3f6b07..ffe3d4cc64 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -478,7 +478,7 @@ static int relabel_extra(void) { } #endif -int mount_setup(bool loaded_policy) { +int mount_setup(bool loaded_policy, bool leave_propagation) { int r = 0; r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy); @@ -524,7 +524,7 @@ int mount_setup(bool loaded_policy) { * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a * container manager we assume the container manager knows what it is doing (for example, because it set up * some directories with different propagation modes). */ - if (detect_container() <= 0) + if (detect_container() <= 0 && !leave_propagation) if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0) log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m"); diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h index b4ca2cf4b4..bccd094961 100644 --- a/src/core/mount-setup.h +++ b/src/core/mount-setup.h @@ -4,7 +4,7 @@ #include <stdbool.h> int mount_setup_early(void); -int mount_setup(bool loaded_policy); +int mount_setup(bool loaded_policy, bool leave_propagation); int mount_cgroup_controllers(void); diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index e40898d10b..56448c18f1 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -272,8 +272,8 @@ int mac_selinux_generic_access_check( sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access."); } - log_debug_errno(r, "SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %m", - scon, fcon, tclass, permission, path, cl); + log_debug_errno(r, "SELinux access check scon=%s tcon=%s tclass=%s perm=%s state=%s path=%s cmdline=%s: %m", + scon, fcon, tclass, permission, enforce ? "enforcing" : "permissive", path, cl); return enforce ? r : 0; } diff --git a/src/core/system.conf.in b/src/core/system.conf.in index 8112125468..40bb548887 100644 --- a/src/core/system.conf.in +++ b/src/core/system.conf.in @@ -16,6 +16,7 @@ #LogTarget=journal-or-kmsg #LogColor=yes #LogLocation=no +#LogTime=no #DumpCore=yes #ShowStatus=yes #CrashChangeVT=no diff --git a/src/core/systemd.pc.in b/src/core/systemd.pc.in index 8331832c7a..da7e74ed7b 100644 --- a/src/core/systemd.pc.in +++ b/src/core/systemd.pc.in @@ -7,36 +7,93 @@ # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. +# Names with prefixes are prefered, and the run-together names should be +# considered deprecated (though there is no plan to remove them). New names +# shall have underscores. + prefix=@prefix@ -rootprefix=@rootprefix_noslash@ -sysconfdir=@sysconfdir@ -systemdutildir=${rootprefix}/lib/systemd -systemdsystemunitdir=${rootprefix}/lib/systemd/system -systemdsystempresetdir=${rootprefix}/lib/systemd/system-preset -systemduserunitdir=${prefix}/lib/systemd/user -systemduserpresetdir=${prefix}/lib/systemd/user-preset -systemdsystemconfdir=${sysconfdir}/systemd/system -systemduserconfdir=${sysconfdir}/systemd/user -systemdsystemunitpath=${systemdsystemconfdir}:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:${systemdsystemunitdir}:/usr/lib/systemd/system:/lib/systemd/system -systemduserunitpath=${systemduserconfdir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemduserunitdir}:/usr/lib/systemd/user:/usr/share/systemd/user -systemdsystemgeneratordir=${rootprefix}/lib/systemd/system-generators -systemdusergeneratordir=${prefix}/lib/systemd/user-generators -systemdsystemgeneratorpath=/run/systemd/system-generators:/etc/systemd/system-generators:/usr/local/lib/systemd/system-generators:${systemdsystemgeneratordir} -systemdusergeneratorpath=/run/systemd/user-generators:/etc/systemd/user-generators:/usr/local/lib/systemd/user-generators:${systemdusergeneratordir} -systemdsleepdir=${rootprefix}/lib/systemd/system-sleep -systemdshutdowndir=${rootprefix}/lib/systemd/system-shutdown -tmpfilesdir=${prefix}/lib/tmpfiles.d -sysusersdir=${prefix}/lib/sysusers.d -sysctldir=${prefix}/lib/sysctl.d -binfmtdir=${prefix}/lib/binfmt.d -modulesloaddir=${prefix}/lib/modules-load.d -catalogdir=${prefix}/lib/systemd/catalog -systemuidmax=@systemuidmax@ -systemgidmax=@systemgidmax@ -dynamicuidmin=@dynamicuidmin@ -dynamicuidmax=@dynamicuidmax@ -containeruidbasemin=@containeruidbasemin@ -containeruidbasemax=@containeruidbasemax@ +root_prefix=@rootprefix_noslash@ +rootprefix=${root_prefix} +sysconf_dir=@sysconfdir@ +sysconfdir=${sysconf_dir} + +systemd_util_dir=${root_prefix}/lib/systemd +systemdutildir=${systemd_util_dir} + +systemd_system_unit_dir=${rootprefix}/lib/systemd/system +systemdsystemunitdir=${systemd_system_unit_dir} + +systemd_system_preset_dir=${rootprefix}/lib/systemd/system-preset +systemdsystempresetdir=${systemd_system_preset_dir} + +systemd_user_unit_dir=${prefix}/lib/systemd/user +systemduserunitdir=${systemd_user_unit_dir} + +systemd_user_preset_dir=${prefix}/lib/systemd/user-preset +systemduserpresetdir=${systemd_user_preset_dir} + +systemd_system_conf_dir=${sysconfdir}/systemd/system +systemdsystemconfdir=${systemd_system_conf_dir} + +systemd_user_conf_dir=${sysconfdir}/systemd/user +systemduserconfdir=${systemd_user_conf_dir} + +systemd_system_unit_path=${systemd_system_conf_dir}:/etc/systemd/system:/run/systemd/system:/usr/local/lib/systemd/system:${systemd_system_unit_dir}:/usr/lib/systemd/system:/lib/systemd/system +systemdsystemunitpath=${systemd_system_unit_path} + +systemd_user_unit_path=${systemd_user_conf_dir}:/etc/systemd/user:/run/systemd/user:/usr/local/lib/systemd/user:/usr/local/share/systemd/user:${systemd_user_unit_dir}:/usr/lib/systemd/user:/usr/share/systemd/user +systemduserunitpath=${systemd_user_unit_path} + +systemd_system_generator_dir=${root_prefix}/lib/systemd/system-generators +systemdsystemgeneratordir=${systemd_system_generator_dir} + +systemd_user_generator_dir=${prefix}/lib/systemd/user-generators +systemdusergeneratordir=${systemd_user_generator_dir} + +systemd_system_generator_path=/run/systemd/system-generators:/etc/systemd/system-generators:/usr/local/lib/systemd/system-generators:${systemd_system_generator_dir} +systemdsystemgeneratorpath=${systemd_system_generator_path} + +systemd_user_generator_path=/run/systemd/user-generators:/etc/systemd/user-generators:/usr/local/lib/systemd/user-generators:${systemd_user_generator_dir} +systemdusergeneratorpath=${systemd_user_generator_path} + +systemd_sleep_dir=${root_prefix}/lib/systemd/system-sleep +systemdsleepdir=${systemd_sleep_dir} + +systemd_shutdown_dir=${root_prefix}/lib/systemd/system-shutdown +systemdshutdowndir=${systemd_shutdown_dir} + +tmpfiles_dir=${prefix}/lib/tmpfiles.d +tmpfilesdir=${tmpfiles_dir} + +sysusers_dir=${prefix}/lib/sysusers.d +sysusersdir=${sysusers_dir} + +sysctl_dir=${prefix}/lib/sysctl.d +sysctldir=${sysctl_dir} + +binfmt_dir=${prefix}/lib/binfmt.d +binfmtdir=${binfmt_dir} + +modules_load_dir=${prefix}/lib/modules-load.d +modulesloaddir=${modules_load_dir} + +catalog_dir=${prefix}/lib/systemd/catalog +catalogdir=${catalog_dir} + +system_uid_max=@systemuidmax@ +systemuidmax=${system_uid_max} +system_gid_max=@systemgidmax@ +systemgidmax=${system_gid_max} + +dynamic_uid_min=@dynamicuidmin@ +dynamicuidmin=${dynamic_uid_min} +dynamic_uid_max=@dynamicuidmax@ +dynamicuidmax=${dynamic_uid_max} + +container_uid_base_min=@containeruidbasemin@ +containeruidbasemin=${container_uid_base_min} +container_uid_base_max=@containeruidbasemax@ +containeruidbasemax=${container_uid_base_max} Name: systemd Description: systemd System and Service Manager diff --git a/src/core/unit.c b/src/core/unit.c index 912dc2d3ab..019eed7236 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -218,11 +218,13 @@ int unit_add_name(Unit *u, const char *text) { if (unit_name_is_valid(text, UNIT_NAME_TEMPLATE)) { if (!u->instance) - return -EINVAL; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), + "instance is not set when adding name '%s': %m", text); r = unit_name_replace_instance(text, u->instance, &s); if (r < 0) - return r; + return log_unit_debug_errno(u, r, + "failed to build instance name from '%s': %m", text); } else { s = strdup(text); if (!s) @@ -232,36 +234,43 @@ int unit_add_name(Unit *u, const char *text) { if (set_contains(u->names, s)) return 0; if (hashmap_contains(u->manager->units, s)) - return -EEXIST; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EEXIST), + "unit already exist when adding name '%s': %m", text); if (!unit_name_is_valid(s, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) - return -EINVAL; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), + "name '%s' is invalid: %m", text); t = unit_name_to_type(s); if (t < 0) - return -EINVAL; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), + "failed to to derive unit type from name '%s': %m", text); if (u->type != _UNIT_TYPE_INVALID && t != u->type) - return -EINVAL; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), + "unit type is illegal: u->type(%d) and t(%d) for name '%s': %m", + u->type, t, text); r = unit_name_to_instance(s, &i); if (r < 0) - return r; + return log_unit_debug_errno(u, r, "failed to extract instance from name '%s': %m", text); if (i && !unit_type_may_template(t)) - return -EINVAL; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), "templates are not allowed for name '%s': %m", text); /* Ensure that this unit is either instanced or not instanced, * but not both. Note that we do allow names with different * instance names however! */ if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) - return -EINVAL; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), + "instance is illegal: u->type(%d), u->instance(%s) and i(%s) for name '%s': %m", + u->type, u->instance, i, text); if (!unit_type_may_alias(t) && !set_isempty(u->names)) - return -EEXIST; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EEXIST), "symlinks are not allowed for name '%s': %m", text); if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) - return -E2BIG; + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(E2BIG), "too many units: %m"); r = set_put(u->names, s); if (r < 0) @@ -271,7 +280,7 @@ int unit_add_name(Unit *u, const char *text) { r = hashmap_put(u->manager->units, s, u); if (r < 0) { (void) set_remove(u->names, s); - return r; + return log_unit_debug_errno(u, r, "add unit to hashmap failed for name '%s': %m", text); } if (u->type == _UNIT_TYPE_INVALID) { diff --git a/src/core/user.conf.in b/src/core/user.conf.in index 95a162e0f6..bbe06319c9 100644 --- a/src/core/user.conf.in +++ b/src/core/user.conf.in @@ -15,6 +15,7 @@ #LogTarget=console #LogColor=yes #LogLocation=no +#LogTime=no #SystemCallArchitectures= #TimerSlackNSec= #StatusUnitFormat=@STATUS_UNIT_FORMAT_DEFAULT@ diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 0e9a3c023c..ee4268b965 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -560,7 +560,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) { FOREACH_DIRENT(dent, proc_fd_dir, return -errno) { _cleanup_fclose_ FILE *fdinfo = NULL; _cleanup_free_ char *fdname = NULL; - int fd; + _cleanup_close_ int fd = -1; r = readlinkat_malloc(dirfd(proc_fd_dir), dent->d_name, &fdname); if (r < 0) @@ -574,11 +574,9 @@ static int compose_open_fds(pid_t pid, char **open_fds) { if (fd < 0) continue; - fdinfo = fdopen(fd, "r"); - if (!fdinfo) { - safe_close(fd); + fdinfo = take_fdopen(&fd, "r"); + if (!fdinfo) continue; - } for (;;) { _cleanup_free_ char *line = NULL; diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c index 5fe51359f6..4a14c23f11 100644 --- a/src/environment-d-generator/environment-d-generator.c +++ b/src/environment-d-generator/environment-d-generator.c @@ -20,7 +20,7 @@ static int environment_dirs(char ***ret) { return -ENOMEM; /* ~/.config/systemd/environment.d */ - r = sd_path_home(SD_PATH_USER_CONFIGURATION, "environment.d", &c); + r = sd_path_lookup(SD_PATH_USER_CONFIGURATION, "environment.d", &c); if (r < 0) return r; diff --git a/src/fuzz/fuzz.h b/src/fuzz/fuzz.h index 83b1ac11ad..1e56526259 100644 --- a/src/fuzz/fuzz.h +++ b/src/fuzz/fuzz.h @@ -6,6 +6,3 @@ /* The entry point into the fuzzer */ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -/* https://docs.fuzzbuzz.io/developer-documentation/porting-targets-to-fuzzbuzz/libfuzzer-targets */ -int FuzzerEntrypoint(const uint8_t *data, size_t size); diff --git a/src/fuzz/fuzzer-entry-point.c b/src/fuzz/fuzzer-entry-point.c deleted file mode 100644 index 020c111650..0000000000 --- a/src/fuzz/fuzzer-entry-point.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "fuzz.h" - -int FuzzerEntrypoint(const uint8_t *data, size_t size) { - return LLVMFuzzerTestOneInput(data, size); -} diff --git a/src/home/homectl.c b/src/home/homectl.c index d35034ac08..1ccc053d3f 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -295,7 +295,7 @@ static int handle_generic_user_record_error( if (sd_bus_error_has_name(error, BUS_ERROR_HOME_ABSENT)) return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), - "Home of user %s is currently absent, please plug in the necessary stroage device or backing file system.", user_name); + "Home of user %s is currently absent, please plug in the necessary storage device or backing file system.", user_name); else if (sd_bus_error_has_name(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT)) return log_error_errno(SYNTHETIC_ERRNO(ETOOMANYREFS), @@ -1207,7 +1207,7 @@ static int add_pkcs11_key_data(JsonVariant **v, const char *uri) { pkey = X509_get0_pubkey(cert); if (!pkey) - return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to exract public key from X.509 certificate."); + return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate."); if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "X.509 certificate does not refer to RSA key."); @@ -1338,7 +1338,7 @@ static int acquire_new_password( string_erase(e); if (unsetenv("NEWPASSWORD") < 0) - return log_error_errno(errno, "Failed to unse $NEWPASSWORD: %m"); + return log_error_errno(errno, "Failed to unset $NEWPASSWORD: %m"); return 0; } @@ -1376,7 +1376,7 @@ static int acquire_new_password( return 0; } - log_error("Password didn't mach, try again."); + log_error("Password didn't match, try again."); } } @@ -3148,7 +3148,7 @@ static int parse_argv(int argc, char *argv[]) { r = read_line(f, LONG_LINE_MAX, &line); if (r < 0) - return log_error_errno(r, "Faile dto read from '%s': %m", optarg+1); + return log_error_errno(r, "Failed to read from '%s': %m", optarg+1); if (r == 0) break; diff --git a/src/home/homed-home-bus.c b/src/home/homed-home-bus.c index 02a87a5ec5..6b4fa58a6f 100644 --- a/src/home/homed-home-bus.c +++ b/src/home/homed-home-bus.c @@ -630,7 +630,7 @@ int bus_home_method_acquire( /* This operation might not be something we can executed immediately, hence queue it */ fd = home_create_fifo(h, please_suspend); if (fd < 0) - return sd_bus_reply_method_errnof(message, fd, "Failed to allocate fifo for %s: %m", h->user_name); + return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name); o = operation_new(OPERATION_ACQUIRE, message); if (!o) @@ -681,7 +681,7 @@ int bus_home_method_ref( fd = home_create_fifo(h, please_suspend); if (fd < 0) - return sd_bus_reply_method_errnof(message, fd, "Failed to allocate fifo for %s: %m", h->user_name); + return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name); return sd_bus_reply_method_return(message, "h", fd); } diff --git a/src/home/homed-home.c b/src/home/homed-home.c index f50de26722..09afbc70c3 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -360,12 +360,10 @@ static int home_parse_worker_stdout(int _fd, UserRecord **ret) { if (lseek(fd, SEEK_SET, 0) == (off_t) -1) return log_error_errno(errno, "Failed to seek to beginning of memfd: %m"); - f = fdopen(fd, "r"); + f = take_fdopen(&fd, "r"); if (!f) return log_error_errno(errno, "Failed to reopen memfd: %m"); - TAKE_FD(fd); - if (DEBUG_LOGGING) { _cleanup_free_ char *text = NULL; @@ -424,7 +422,7 @@ static int home_verify_user_record(Home *h, UserRecord *hr, bool *ret_signed_loc case -ENOKEY: sd_bus_error_setf(ret_error, BUS_ERROR_BAD_SIGNATURE, "User record %s is not signed by any known key, refusing.", hr->user_name); - return log_error_errno(is_signed, "Home %s contians user record that is not signed by any known key, refusing.", hr->user_name); + return log_error_errno(is_signed, "Home %s contains user record that is not signed by any known key, refusing.", hr->user_name); default: assert(is_signed < 0); @@ -438,7 +436,7 @@ static int convert_worker_errno(Home *h, int e, sd_bus_error *error) { switch (e) { case -EMSGSIZE: - return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type cannot shrinked"); + return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type cannot be shrinked"); case -ETXTBSY: return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type can only be shrinked offline"); case -ERANGE: @@ -1472,7 +1470,7 @@ int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *e if (disk_size == UINT64_MAX || disk_size == h->record->disk_size) { if (h->record->disk_size == UINT64_MAX) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Not disk size to resize to specified."); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "No disk size to resize to specified."); c = user_record_ref(h->record); /* Shortcut if size is unspecified or matches the record */ } else { @@ -1904,7 +1902,7 @@ static int home_get_disk_status_luks( goto finish; if (statfs(hd, &sfs) < 0) { - log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd); + log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd); goto finish; } diff --git a/src/home/homed-manager-bus.c b/src/home/homed-manager-bus.c index a6b30d961f..fce8545274 100644 --- a/src/home/homed-manager-bus.c +++ b/src/home/homed-manager-bus.c @@ -584,7 +584,7 @@ static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus return -ENOMEM; } - log_info("Automatically locking of home of user %s.", h->user_name); + log_info("Automatically locking home of user %s.", h->user_name); r = home_schedule_operation(h, o, error); if (r < 0) diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c index 5d77760f21..c9bfb64e7f 100644 --- a/src/home/homed-manager.c +++ b/src/home/homed-manager.c @@ -631,7 +631,7 @@ static int manager_add_home_by_image( } if (!same) { - log_debug("Found a multiple images for a user '%s', ignoring image '%s'.", user_name, image_path); + log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name, image_path); return 0; } } else { @@ -768,7 +768,7 @@ static int manager_assess_image( r = stat(path, &st); if (r < 0) return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno, - "Failed to stat directory entry '%s', ignoring: %m", dentry_name); + "Failed to stat() directory entry '%s', ignoring: %m", dentry_name); if (S_ISREG(st.st_mode)) { _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL; @@ -833,7 +833,7 @@ static int manager_assess_image( if (errno == ENODATA) log_debug_errno(errno, "Determined %s is not fscrypt encrypted.", path); else if (ERRNO_IS_NOT_SUPPORTED(errno)) - log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system don't support it.", path); + log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path); else log_debug_errno(errno, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path); @@ -1307,7 +1307,7 @@ static int manager_generate_key_pair(Manager *m) { /* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */ r = fopen_temporary("/var/lib/systemd/home/local.public", &fpublic, &temp_public); if (r < 0) - return log_error_errno(errno, "Failed ot open key file for writing: %m"); + return log_error_errno(errno, "Failed to open key file for writing: %m"); if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key."); @@ -1321,7 +1321,7 @@ static int manager_generate_key_pair(Manager *m) { /* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */ r = fopen_temporary("/var/lib/systemd/home/local.private", &fprivate, &temp_private); if (r < 0) - return log_error_errno(errno, "Failed ot open key file for writing: %m"); + return log_error_errno(errno, "Failed to open key file for writing: %m"); if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair."); @@ -1660,7 +1660,7 @@ int manager_enqueue_gc(Manager *m, Home *focus) { r = sd_event_add_defer(m->event, &m->deferred_gc_event_source, on_deferred_gc, m); if (r < 0) - return log_error_errno(r, "Failed to allocate gc event source: %m"); + return log_error_errno(r, "Failed to allocate GC event source: %m"); r = sd_event_source_set_priority(m->deferred_gc_event_source, SD_EVENT_PRIORITY_IDLE); if (r < 0) diff --git a/src/home/homed-operation.c b/src/home/homed-operation.c index 80dc555cd0..156a25ec81 100644 --- a/src/home/homed-operation.c +++ b/src/home/homed-operation.c @@ -47,7 +47,7 @@ static Operation *operation_free(Operation *o) { r = sd_bus_reply_method_errnof(o->message, o->ret, "Failed to execute operation: %m"); } if (r < 0) - log_warning_errno(r, "Failed ot reply to %s method call, ignoring: %m", sd_bus_message_get_member(o->message)); + log_warning_errno(r, "Failed to reply to %s method call, ignoring: %m", sd_bus_message_get_member(o->message)); } sd_bus_message_unref(o->message); diff --git a/src/home/homework-cifs.c b/src/home/homework-cifs.c index 27f298144a..1510031a38 100644 --- a/src/home/homework-cifs.c +++ b/src/home/homework-cifs.c @@ -142,7 +142,8 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) { _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT; _cleanup_(user_record_unrefp) UserRecord *new_home = NULL; _cleanup_(closedirp) DIR *d = NULL; - int r, copy; + _cleanup_close_ int copy = -1; + int r; assert(h); assert(user_record_storage(h) == USER_CIFS); @@ -166,11 +167,9 @@ int home_create_cifs(UserRecord *h, UserRecord **ret_home) { if (copy < 0) return -errno; - d = fdopendir(copy); - if (!d) { - safe_close(copy); + d = take_fdopendir(©); + if (!d) return -errno; - } errno = 0; if (readdir_no_dot(d)) diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 0cd5902bff..de7535fc60 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -616,7 +616,7 @@ static int crypt_device_to_evp_cipher(struct crypt_device *cd, const EVP_CIPHER /* Verify that our key length calculations match what OpenSSL thinks */ r = EVP_CIPHER_key_length(cc); if (r < 0 || (uint64_t) r != key_size) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Key size of selected cipher doesn't meet out expectations."); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Key size of selected cipher doesn't meet our expectations."); *ret = cc; return 0; @@ -787,7 +787,7 @@ static int format_luks_token_text( r = json_variant_format(hr->json, 0, &text); if (r < 0) - return log_error_errno(r,"Failed to format user record for LUKS: %m"); + return log_error_errno(r, "Failed to format user record for LUKS: %m"); text_length = strlen(text); encrypted_size = text_length + 2*key_size - 1; @@ -1263,7 +1263,7 @@ int home_activate_luks( r = dm_deferred_remove(setup.dm_name); if (r < 0) - log_warning_errno(r, "Failed to relinquish dm device, ignoring: %m"); + log_warning_errno(r, "Failed to relinquish DM device, ignoring: %m"); setup.undo_dm = false; @@ -1328,7 +1328,7 @@ static int run_mkfs( if (r < 0) return log_error_errno(r, "Failed to check if mkfs for file system %s exists: %m", fstype); if (r == 0) - return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "Nt mkfs for file system %s installed.", fstype); + return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "No mkfs for file system %s installed.", fstype); r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL); if (r < 0) @@ -1584,7 +1584,7 @@ static int make_partition_table( r = fdisk_create_disklabel(c, "gpt"); if (r < 0) - return log_error_errno(r, "Failed to create gpt disk label: %m"); + return log_error_errno(r, "Failed to create GPT disk label: %m"); p = fdisk_new_partition(); if (!p) @@ -1765,6 +1765,45 @@ static int calculate_disk_size(UserRecord *h, const char *parent_dir, uint64_t * return 0; } +static int home_truncate( + UserRecord *h, + int fd, + const char *path, + uint64_t size) { + + bool trunc; + int r; + + assert(h); + assert(fd >= 0); + assert(path); + + trunc = user_record_luks_discard(h); + if (!trunc) { + r = fallocate(fd, 0, 0, size); + if (r < 0 && ERRNO_IS_NOT_SUPPORTED(errno)) { + /* Some file systems do not support fallocate(), let's gracefully degrade + * (ZFS, reiserfs, …) and fall back to truncation */ + log_notice_errno(errno, "Backing file system does not support fallocate(), falling back to ftruncate(), i.e. implicitly using non-discard mode."); + trunc = true; + } + } + + if (trunc) + r = ftruncate(fd, size); + + if (r < 0) { + if (ERRNO_IS_DISK_SPACE(errno)) { + log_error_errno(errno, "Not enough disk space to allocate home."); + return -ENOSPC; /* make recognizable */ + } + + return log_error_errno(errno, "Failed to truncate home image %s: %m", path); + } + + return 0; +} + int home_create_luks( UserRecord *h, char **pkcs11_decrypted_passwords, @@ -1917,20 +1956,9 @@ int home_create_luks( if (r < 0) log_warning_errno(r, "Failed to set file attributes on %s, ignoring: %m", temporary_image_path); - if (user_record_luks_discard(h)) - r = ftruncate(image_fd, host_size); - else - r = fallocate(image_fd, 0, 0, host_size); - if (r < 0) { - if (ERRNO_IS_DISK_SPACE(errno)) { - log_debug_errno(errno, "Not enough disk space to allocate home."); - r = -ENOSPC; /* make recognizable */ - goto fail; - } - - r = log_error_errno(errno, "Failed to truncate home image %s: %m", temporary_image_path); + r = home_truncate(h, image_fd, temporary_image_path, host_size); + if (r < 0) goto fail; - } log_info("Allocating image file completed."); } @@ -2212,7 +2240,7 @@ static int ext4_offline_resize_fs(HomeSetup *setup, uint64_t new_size, bool disc re_mount = true; } - log_info("Temporarary unmounting of file system completed."); + log_info("Temporary unmounting of file system completed."); /* resize2fs requires that the file system is force checked first, do so. */ r = safe_fork("(e2fsck)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR, &fsck_pid); @@ -2426,7 +2454,7 @@ static int apply_resize_partition(int fd, sd_id128_t disk_uuids, struct fdisk_ta if (n < 0) return log_error_errno(errno, "Failed to wipe partition table: %m"); if (n != 1024) - return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while whiping partition table."); + return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while wiping partition table."); c = fdisk_new_context(); if (!c) @@ -2536,7 +2564,7 @@ int home_resize_luks( } else { r = stat_verify_regular(&st); if (r < 0) - return log_error_errno(r, "Image file %s is not a block device nor regular: %m", ip); + return log_error_errno(r, "Image %s is not a block device nor regular file: %m", ip); old_image_size = st.st_size; @@ -2625,19 +2653,9 @@ int home_resize_luks( if (S_ISREG(st.st_mode)) { /* Grow file size */ - - if (user_record_luks_discard(h)) - r = ftruncate(image_fd, new_image_size); - else - r = fallocate(image_fd, 0, 0, new_image_size); - if (r < 0) { - if (ERRNO_IS_DISK_SPACE(errno)) { - log_debug_errno(errno, "Not enough disk space to grow home."); - return -ENOSPC; /* make recognizable */ - } - - return log_error_errno(errno, "Failed to grow image file %s: %m", ip); - } + r = home_truncate(h, image_fd, ip, new_image_size); + if (r < 0) + return r; log_info("Growing of image file completed."); } diff --git a/src/home/homework-pkcs11.c b/src/home/homework-pkcs11.c index 941ba23b3c..915bc0e57e 100644 --- a/src/home/homework-pkcs11.c +++ b/src/home/homework-pkcs11.c @@ -53,7 +53,7 @@ int pkcs11_callback( if (rv != CKR_OK) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to log into security token '%s': %s", token_label, p11_kit_strerror(rv)); - log_info("Successully logged into security token '%s' via protected authentication path.", token_label); + log_info("Successfully logged into security token '%s' via protected authentication path.", token_label); goto decrypt; } diff --git a/src/home/homework.c b/src/home/homework.c index ecf07ffb48..3fccab095c 100644 --- a/src/home/homework.c +++ b/src/home/homework.c @@ -38,7 +38,6 @@ int user_record_authenticate( bool need_password = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false, pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false; - size_t n; int r; assert(h); @@ -70,7 +69,7 @@ int user_record_authenticate( } /* Second, let's see if any of the PKCS#11 security tokens are plugged in and help us */ - for (n = 0; n < h->n_pkcs11_encrypted_key; n++) { + for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) { #if HAVE_P11KIT _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = { .user_record = h, @@ -280,12 +279,10 @@ static int read_identity_file(int root_fd, JsonVariant **ret) { if (r < 0) return log_error_errno(r, "Embedded identity file is not a regular file, refusing: %m"); - identity_file = fdopen(identity_fd, "r"); + identity_file = take_fdopen(&identity_fd, "r"); if (!identity_file) return log_oom(); - identity_fd = -1; - r = json_parse_file(identity_file, ".identity", JSON_PARSE_SENSITIVE, ret, &line, &column); if (r < 0) return log_error_errno(r, "[.identity:%u:%u] Failed to parse JSON data: %m", line, column); @@ -319,14 +316,12 @@ static int write_identity_file(int root_fd, JsonVariant *v, uid_t uid) { if (identity_fd < 0) return log_error_errno(errno, "Failed to create .identity file in home directory: %m"); - identity_file = fdopen(identity_fd, "w"); + identity_file = take_fdopen(&identity_fd, "w"); if (!identity_file) { r = log_oom(); goto fail; } - identity_fd = -1; - json_variant_dump(normalized, JSON_FORMAT_PRETTY, identity_file, NULL); r = fflush_and_check(identity_file); @@ -383,7 +378,7 @@ int home_load_embedded_identity( return r; if (!user_record_compatible(h, embedded_home)) - return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Hmbedded home record not compatible with host record, refusing."); + return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing."); /* Insist that credentials the user supplies also unlocks any embedded records. */ r = user_record_authenticate(embedded_home, h, pkcs11_decrypted_passwords); @@ -986,7 +981,7 @@ static int home_remove(UserRecord *h) { if (stat(ip, &st) < 0) { if (errno != -ENOENT) - return log_error_errno(errno, "Failed to stat %s: %m", ip); + return log_error_errno(errno, "Failed to stat() %s: %m", ip); } else { if (S_ISREG(st.st_mode)) { diff --git a/src/home/pam_systemd_home.c b/src/home/pam_systemd_home.c index 67aff9350f..440ed85e2c 100644 --- a/src/home/pam_systemd_home.c +++ b/src/home/pam_systemd_home.c @@ -41,7 +41,7 @@ static int parse_argv( k = parse_boolean(v); if (k < 0) - pam_syslog(handle, LOG_WARNING, "Failed to parse suspend-please= argument, ignoring: %s", v); + pam_syslog(handle, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v); else if (please_suspend) *please_suspend = k; @@ -95,7 +95,7 @@ static int acquire_user_record( r = pam_get_data(handle, "systemd-user-record-is-homed", &b); if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA)) { /* Failure */ - pam_syslog(handle, LOG_ERR, "Failed to get PAM user record is homed flag: %s", pam_strerror(handle, r)); + pam_syslog(handle, LOG_ERR, "Failed to get PAM user-record-is-homed flag: %s", pam_strerror(handle, r)); return r; } else if (b == NULL) /* Nothing cached yet, need to acquire fresh */ @@ -200,7 +200,7 @@ user_unknown: /* Cache this, so that we don't check again */ r = pam_set_data(handle, "systemd-user-record-is-homed", USER_RECORD_IS_OTHER, NULL); if (r != PAM_SUCCESS) - pam_syslog(handle, LOG_ERR, "Failed to set PAM user record is homed flag, ignoring: %s", pam_strerror(handle, r)); + pam_syslog(handle, LOG_ERR, "Failed to set PAM user-record-is-homed flag, ignoring: %s", pam_strerror(handle, r)); return PAM_USER_UNKNOWN; } @@ -214,7 +214,7 @@ static int release_user_record(pam_handle_t *handle) { k = pam_set_data(handle, "systemd-user-record-is-homed", NULL, NULL); if (k != PAM_SUCCESS) - pam_syslog(handle, LOG_ERR, "Failed to release PAM user record is homed flag: %s", pam_strerror(handle, k)); + pam_syslog(handle, LOG_ERR, "Failed to release PAM user-record-is-homed flag: %s", pam_strerror(handle, k)); return IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA) ? k : r; } diff --git a/src/home/pwquality-util.c b/src/home/pwquality-util.c index f2342b28f8..5863a229b8 100644 --- a/src/home/pwquality-util.c +++ b/src/home/pwquality-util.c @@ -73,7 +73,7 @@ int quality_check_password( r = pwquality_read_config(pwq, NULL, &auxerror); if (r < 0) - log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuation, ignoring: %s", + log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuration, ignoring: %s", pwquality_strerror(buf, sizeof(buf), r, auxerror)); pwquality_maybe_disable_dictionary(pwq); @@ -143,7 +143,7 @@ int suggest_passwords(void) { r = pwquality_read_config(pwq, NULL, &auxerror); if (r < 0) - log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuation, ignoring: %s", + log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to read libpwquality configuration, ignoring: %s", pwquality_strerror(buf, sizeof(buf), r, auxerror)); pwquality_maybe_disable_dictionary(pwq); diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c index 51c12444e0..0183c13f46 100644 --- a/src/import/pull-raw.c +++ b/src/import/pull-raw.c @@ -509,14 +509,17 @@ static void raw_pull_job_on_finished(PullJob *j) { raw_pull_report_progress(i, RAW_FINALIZING); - r = import_make_read_only_fd(i->raw_job->disk_fd); - if (r < 0) - goto finish; + if (i->raw_job->etag) { + /* Only make a read-only copy if ETag header is set. */ + r = import_make_read_only_fd(i->raw_job->disk_fd); + if (r < 0) + goto finish; - r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path); - if (r < 0) { - log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path); - goto finish; + r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path); + if (r < 0) { + log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path); + goto finish; + } } i->temp_path = mfree(i->temp_path); diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c index 459d8e86a1..5177e0d157 100644 --- a/src/journal-remote/journal-gatewayd.c +++ b/src/journal-remote/journal-gatewayd.c @@ -123,17 +123,15 @@ static int request_meta_ensure_tmp(RequestMeta *m) { if (m->tmp) rewind(m->tmp); else { - int fd; + _cleanup_close_ int fd = -1; fd = open_tmpfile_unlinkable("/tmp", O_RDWR|O_CLOEXEC); if (fd < 0) return fd; - m->tmp = fdopen(fd, "w+"); - if (!m->tmp) { - safe_close(fd); + m->tmp = take_fdopen(&fd, "w+"); + if (!m->tmp) return -errno; - } } return 0; diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index 88e42d3a98..551b84130d 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -786,7 +786,7 @@ static int help(void) { " --listen-http=ADDR Listen for HTTP connections at ADDR\n" " --listen-https=ADDR Listen for HTTPS connections at ADDR\n" " -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n" - " --compress[=BOOL] XZ-compress the output journal (default: yes)\n" + " --compress[=BOOL] Use compression in the output journal (default: yes)\n" " --seal[=BOOL] Use event sealing (default: no)\n" " --key=FILENAME SSL key in PEM format (default:\n" " \"" PRIV_KEY_FILE "\")\n" diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 56a6a9c431..a739fa8aaf 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -1718,7 +1718,7 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) { goto fail; } } else { - int dfd; + _cleanup_close_ int dfd = -1; /* If there's no path specified, then we use the top-level fd itself. We duplicate the fd here, since * opendir() will take possession of the fd, and close it, which we don't want. */ @@ -1731,10 +1731,9 @@ static int add_root_directory(sd_journal *j, const char *p, bool missing_ok) { goto fail; } - d = fdopendir(dfd); + d = take_fdopendir(&dfd); if (!d) { r = -errno; - safe_close(dfd); goto fail; } @@ -2675,13 +2674,12 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { Get rid of the deleted files now so they don't stay around indefinitely. */ ORDERED_HASHMAP_FOREACH(f, j->files, i) { r = journal_file_fstat(f); - if (r < 0) { + if (r == -EIDRM) + remove_file_real(j, f); + else if (r < 0) { log_debug_errno(r,"Failed to fstat() journal file '%s' : %m", f->path); continue; } - - if (f->last_stat.st_nlink <= 0) - remove_file_real(j, f); } /* The journal might have changed since the context diff --git a/src/libsystemd-network/dhcp-lease-internal.h b/src/libsystemd-network/dhcp-lease-internal.h index a2d0f8bd5e..5cbebb4a34 100644 --- a/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/libsystemd-network/dhcp-lease-internal.h @@ -61,6 +61,12 @@ struct sd_dhcp_lease { struct in_addr *sip; size_t sip_size; + struct in_addr *pop3_server; + size_t pop3_server_size; + + struct in_addr *smtp_server; + size_t smtp_server_size; + struct sd_dhcp_route *static_route; size_t static_route_size, static_route_allocated; diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 41901894f5..1b42712479 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -55,8 +55,8 @@ struct sd_dhcp_server { char *timezone; - struct in_addr *ntp, *dns, *sip; - unsigned n_ntp, n_dns, n_sip; + struct in_addr *ntp, *dns, *sip, *pop3_server, *smtp_server; + unsigned n_ntp, n_dns, n_sip, n_pop3_server, n_smtp_server; OrderedHashmap *extra_options; OrderedHashmap *vendor_options; diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c index 1e9fe73034..02645b2bcd 100644 --- a/src/libsystemd-network/lldp-neighbor.c +++ b/src/libsystemd-network/lldp-neighbor.c @@ -50,6 +50,7 @@ static void lldp_neighbor_free(sd_lldp_neighbor *n) { free(n->port_description); free(n->system_name); free(n->system_description); + free(n->mud_url); free(n->chassis_id_as_string); free(n->port_id_as_string); free(n); @@ -292,9 +293,20 @@ int lldp_neighbor_parse(sd_lldp_neighbor *n) { break; - case SD_LLDP_TYPE_PRIVATE: + case SD_LLDP_TYPE_PRIVATE: { if (length < 4) log_lldp("Found private TLV that is too short, ignoring."); + else { + /* RFC 8520: MUD URL */ + if (memcmp(p, SD_LLDP_OUI_MUD, sizeof(SD_LLDP_OUI_MUD)) == 0 && + p[sizeof(SD_LLDP_OUI_MUD)] == SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION) { + r = parse_string(&n->mud_url, p + sizeof(SD_LLDP_OUI_MUD) + 1, + length - 1 - sizeof(SD_LLDP_OUI_MUD)); + if (r < 0) + return r; + } + } + } break; } @@ -593,6 +605,17 @@ _public_ int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const ch return 0; } +_public_ int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret) { + assert_return(n, -EINVAL); + assert_return(ret, -EINVAL); + + if (!n->mud_url) + return -ENODATA; + + *ret = n->mud_url; + return 0; +} + _public_ int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret) { assert_return(n, -EINVAL); assert_return(ret, -EINVAL); diff --git a/src/libsystemd-network/lldp-neighbor.h b/src/libsystemd-network/lldp-neighbor.h index 62dbff42ca..74175edf54 100644 --- a/src/libsystemd-network/lldp-neighbor.h +++ b/src/libsystemd-network/lldp-neighbor.h @@ -54,6 +54,7 @@ struct sd_lldp_neighbor { char *port_description; char *system_name; char *system_description; + char *mud_url; uint16_t port_vlan_id; diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 593bad2230..16ff173ac6 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -8,7 +8,6 @@ #include "sd-dhcp-lease.h" #include "conf-parser.h" -#include "def.h" #include "set.h" #include "strv.h" @@ -66,5 +65,3 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t /* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */ int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size); - -#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network")) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 82553e79ca..a59ae4767e 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -27,6 +27,7 @@ #include "random-util.h" #include "string-util.h" #include "strv.h" +#include "web-util.h" #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */ #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN) @@ -83,6 +84,7 @@ struct sd_dhcp_client { size_t client_id_len; char *hostname; char *vendor_class_identifier; + char *mudurl; char **user_class; uint32_t mtu; uint32_t xid; @@ -493,6 +495,18 @@ int sd_dhcp_client_set_vendor_class_identifier( return free_and_strdup(&client->vendor_class_identifier, vci); } +int sd_dhcp_client_set_mud_url( + sd_dhcp_client *client, + const char *mudurl) { + + assert_return(client, -EINVAL); + assert_return(mudurl, -EINVAL); + assert_return(strlen(mudurl) <= 255, -EINVAL); + assert_return(http_url_is_valid(mudurl), -EINVAL); + + return free_and_strdup(&client->mudurl, mudurl); +} + int sd_dhcp_client_set_user_class( sd_dhcp_client *client, const char* const* user_class) { @@ -895,6 +909,15 @@ static int client_send_discover(sd_dhcp_client *client) { return r; } + if (client->mudurl) { + r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, + SD_DHCP_OPTION_MUD_URL, + strlen(client->mudurl), + client->mudurl); + if (r < 0) + return r; + } + if (client->user_class) { r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0, SD_DHCP_OPTION_USER_CLASS, @@ -1032,6 +1055,16 @@ static int client_send_request(sd_dhcp_client *client) { return r; } + if (client->mudurl) { + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, + SD_DHCP_OPTION_MUD_URL, + strlen(client->mudurl), + client->mudurl); + if (r < 0) + return r; + } + + r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0, SD_DHCP_OPTION_END, 0, NULL); if (r < 0) @@ -2101,6 +2134,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) { free(client->req_opts); free(client->hostname); free(client->vendor_class_identifier); + free(client->mudurl); client->user_class = strv_free(client->user_class); ordered_hashmap_free(client->extra_options); ordered_hashmap_free(client->vendor_options); diff --git a/src/libsystemd-network/sd-dhcp-lease.c b/src/libsystemd-network/sd-dhcp-lease.c index d072f1c57a..1b7b6e1068 100644 --- a/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/libsystemd-network/sd-dhcp-lease.c @@ -129,6 +129,28 @@ int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) { return (int) lease->sip_size; } +int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (lease->pop3_server_size <= 0) + return -ENODATA; + + *addr = lease->pop3_server; + return (int) lease->pop3_server_size; +} + +int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) { + assert_return(lease, -EINVAL); + assert_return(addr, -EINVAL); + + if (lease->smtp_server_size <= 0) + return -ENODATA; + + *addr = lease->smtp_server; + return (int) lease->smtp_server_size; +} + int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { assert_return(lease, -EINVAL); assert_return(domainname, -EINVAL); @@ -279,6 +301,8 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) { free(lease->dns); free(lease->ntp); free(lease->sip); + free(lease->pop3_server); + free(lease->smtp_server); free(lease->static_route); free(lease->client_id); free(lease->vendor_specific); @@ -601,6 +625,18 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void log_debug_errno(r, "Failed to parse SIP server, ignoring: %m"); break; + case SD_DHCP_OPTION_POP3_SERVER: + r = lease_parse_in_addrs(option, len, &lease->pop3_server, &lease->pop3_server_size); + if (r < 0) + log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m"); + break; + + case SD_DHCP_OPTION_SMTP_SERVER: + r = lease_parse_in_addrs(option, len, &lease->smtp_server, &lease->smtp_server_size); + if (r < 0) + log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m"); + break; + case SD_DHCP_OPTION_STATIC_ROUTE: r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); if (r < 0) @@ -1037,6 +1073,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { *dns = NULL, *ntp = NULL, *sip = NULL, + *pop3_server = NULL, + *smtp_server = NULL, *mtu = NULL, *routes = NULL, *domains = NULL, @@ -1066,6 +1104,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { "DNS", &dns, "NTP", &ntp, "SIP", &sip, + "POP3_SERVERS", &pop3_server, + "SMTP_SERVERS", &smtp_server, "MTU", &mtu, "DOMAINNAME", &lease->domainname, "HOSTNAME", &lease->hostname, @@ -1178,6 +1218,22 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) { lease->sip_size = r; } + if (pop3_server) { + r = deserialize_in_addrs(&lease->pop3_server, pop3_server); + if (r < 0) + log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3_server); + else + lease->pop3_server_size = r; + } + + if (smtp_server) { + r = deserialize_in_addrs(&lease->smtp_server, smtp_server); + if (r < 0) + log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp_server); + else + lease->smtp_server_size = r; + } + if (mtu) { r = safe_atou16(mtu, &lease->mtu); if (r < 0) diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index a0b779bc09..ee4a7249c2 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -140,6 +140,8 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) { free(server->dns); free(server->ntp); free(server->sip); + free(server->pop3_server); + free(server->smtp_server); hashmap_free(server->leases_by_client_id); @@ -513,6 +515,24 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req, return r; } + if (server->n_pop3_server > 0) { + r = dhcp_option_append( + &packet->dhcp, req->max_optlen, &offset, 0, + SD_DHCP_OPTION_POP3_SERVER, + sizeof(struct in_addr) * server->n_pop3_server, server->pop3_server); + if (r < 0) + return r; + } + + if (server->n_smtp_server > 0) { + r = dhcp_option_append( + &packet->dhcp, req->max_optlen, &offset, 0, + SD_DHCP_OPTION_SMTP_SERVER, + sizeof(struct in_addr) * server->n_smtp_server, server->smtp_server); + if (r < 0) + return r; + } + if (server->timezone) { r = dhcp_option_append( &packet->dhcp, req->max_optlen, &offset, 0, @@ -1181,6 +1201,56 @@ int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], u return 1; } +int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n) { + assert_return(server, -EINVAL); + assert_return(pop3_server || n <= 0, -EINVAL); + + if (server->n_pop3_server == n && + memcmp(server->pop3_server, pop3_server, sizeof(struct in_addr) * n) == 0) + return 0; + + if (n <= 0) { + server->pop3_server = mfree(server->pop3_server); + server->n_pop3_server = 0; + } else { + struct in_addr *c; + + c = newdup(struct in_addr, pop3_server, n); + if (!c) + return -ENOMEM; + + free_and_replace(server->pop3_server, c); + server->n_pop3_server = n; + } + + return 1; +} + +int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n) { + assert_return(server, -EINVAL); + assert_return(smtp_server || n <= 0, -EINVAL); + + if (server->n_smtp_server == n && + memcmp(server->smtp_server, smtp_server, sizeof(struct in_addr) * n) == 0) + return 0; + + if (n <= 0) { + server->smtp_server = mfree(server->smtp_server); + server->n_smtp_server = 0; + } else { + struct in_addr *c; + + c = newdup(struct in_addr, smtp_server, n); + if (!c) + return -ENOMEM; + + free_and_replace(server->smtp_server, c); + server->n_smtp_server = n; + } + + return 1; +} + int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) { assert_return(server, -EINVAL); diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index eac2e725cc..3f6caedfdf 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -25,6 +25,7 @@ #include "socket-util.h" #include "string-table.h" #include "util.h" +#include "web-util.h" #define MAX_MAC_ADDR_LEN INFINIBAND_ALEN @@ -65,6 +66,7 @@ struct sd_dhcp6_client { size_t req_opts_allocated; size_t req_opts_len; char *fqdn; + char *mudurl; sd_event_source *receive_message; usec_t retransmit_time; uint8_t retransmit_count; @@ -363,6 +365,17 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option) return 0; } +int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, char *mudurl) { + + assert_return(client, -EINVAL); + assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY); + assert_return(mudurl, -EINVAL); + assert_return(strlen(mudurl) <= 255, -EINVAL); + assert_return(http_url_is_valid(mudurl), -EINVAL); + + return free_and_strdup(&client->mudurl, mudurl); +} + int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) { assert_return(client, -EINVAL); assert_return(delegation, -EINVAL); @@ -484,6 +497,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { case DHCP6_STATE_INFORMATION_REQUEST: message->type = DHCP6_INFORMATION_REQUEST; + if (client->mudurl) { + r = dhcp6_option_append(&opt, &optlen, + SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl), + client->mudurl); + if (r < 0) + return r; + } + break; case DHCP6_STATE_SOLICITATION: @@ -507,6 +528,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->mudurl) { + r = dhcp6_option_append(&opt, &optlen, + SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl), + client->mudurl); + if (r < 0) + return r; + } + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix); if (r < 0) @@ -545,6 +574,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->mudurl) { + r = dhcp6_option_append(&opt, &optlen, + SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl), + client->mudurl); + if (r < 0) + return r; + } + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL); if (r < 0) @@ -571,6 +608,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) { return r; } + if (client->mudurl) { + r = dhcp6_option_append(&opt, &optlen, + SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl), + client->mudurl); + if (r < 0) + return r; + } + if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) { r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL); if (r < 0) @@ -1521,6 +1566,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) { free(client->req_opts); free(client->fqdn); + free(client->mudurl); return mfree(client); } diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 8b6ebbcf8b..1cfe355089 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -697,3 +697,16 @@ global: sd_event_source_send_child_signal; sd_journal_open_namespace; } LIBSYSTEMD_243; + +LIBSYSTEMD_246 { +global: + sd_bus_call_methodv; + sd_bus_call_method_asyncv; + sd_bus_emit_signalv; + sd_bus_reply_method_errnofv; + sd_bus_reply_method_errorfv; + sd_bus_reply_method_returnv; + sd_bus_set_propertyv; + sd_path_lookup; + sd_path_lookup_strv; +} LIBSYSTEMD_245; diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c index 89547a252d..a5672a831f 100644 --- a/src/libsystemd/sd-bus/bus-convenience.c +++ b/src/libsystemd/sd-bus/bus-convenience.c @@ -10,12 +10,12 @@ #include "bus-util.h" #include "string-util.h" -_public_ int sd_bus_emit_signal( +_public_ int sd_bus_emit_signalv( sd_bus *bus, const char *path, const char *interface, const char *member, - const char *types, ...) { + const char *types, va_list ap) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; @@ -32,11 +32,7 @@ _public_ int sd_bus_emit_signal( return r; if (!isempty(types)) { - va_list ap; - - va_start(ap, types); r = sd_bus_message_appendv(m, types, ap); - va_end(ap); if (r < 0) return r; } @@ -44,7 +40,24 @@ _public_ int sd_bus_emit_signal( return sd_bus_send(bus, m, NULL); } -_public_ int sd_bus_call_method_async( +_public_ int sd_bus_emit_signal( + sd_bus *bus, + const char *path, + const char *interface, + const char *member, + const char *types, ...) { + + va_list ap; + int r; + + va_start(ap, types); + r = sd_bus_emit_signalv(bus, path, interface, member, types, ap); + va_end(ap); + + return r; +} + +_public_ int sd_bus_call_method_asyncv( sd_bus *bus, sd_bus_slot **slot, const char *destination, @@ -53,7 +66,7 @@ _public_ int sd_bus_call_method_async( const char *member, sd_bus_message_handler_t callback, void *userdata, - const char *types, ...) { + const char *types, va_list ap) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; @@ -70,11 +83,7 @@ _public_ int sd_bus_call_method_async( return r; if (!isempty(types)) { - va_list ap; - - va_start(ap, types); r = sd_bus_message_appendv(m, types, ap); - va_end(ap); if (r < 0) return r; } @@ -82,7 +91,28 @@ _public_ int sd_bus_call_method_async( return sd_bus_call_async(bus, slot, m, callback, userdata, 0); } -_public_ int sd_bus_call_method( +_public_ int sd_bus_call_method_async( + sd_bus *bus, + sd_bus_slot **slot, + const char *destination, + const char *path, + const char *interface, + const char *member, + sd_bus_message_handler_t callback, + void *userdata, + const char *types, ...) { + + va_list ap; + int r; + + va_start(ap, types); + r = sd_bus_call_method_asyncv(bus, slot, destination, path, interface, member, callback, userdata, types, ap); + va_end(ap); + + return r; +} + +_public_ int sd_bus_call_methodv( sd_bus *bus, const char *destination, const char *path, @@ -90,7 +120,7 @@ _public_ int sd_bus_call_method( const char *member, sd_bus_error *error, sd_bus_message **reply, - const char *types, ...) { + const char *types, va_list ap) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; @@ -109,11 +139,7 @@ _public_ int sd_bus_call_method( goto fail; if (!isempty(types)) { - va_list ap; - - va_start(ap, types); r = sd_bus_message_appendv(m, types, ap); - va_end(ap); if (r < 0) goto fail; } @@ -124,10 +150,30 @@ fail: return sd_bus_error_set_errno(error, r); } -_public_ int sd_bus_reply_method_return( - sd_bus_message *call, +_public_ int sd_bus_call_method( + sd_bus *bus, + const char *destination, + const char *path, + const char *interface, + const char *member, + sd_bus_error *error, + sd_bus_message **reply, const char *types, ...) { + va_list ap; + int r; + + va_start(ap, types); + r = sd_bus_call_methodv(bus, destination, path, interface, member, error, reply, types, ap); + va_end(ap); + + return r; +} + +_public_ int sd_bus_reply_method_returnv( + sd_bus_message *call, + const char *types, va_list ap) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; @@ -148,11 +194,7 @@ _public_ int sd_bus_reply_method_return( return r; if (!isempty(types)) { - va_list ap; - - va_start(ap, types); r = sd_bus_message_appendv(m, types, ap); - va_end(ap); if (r < 0) return r; } @@ -160,6 +202,20 @@ _public_ int sd_bus_reply_method_return( return sd_bus_send(call->bus, m, NULL); } +_public_ int sd_bus_reply_method_return( + sd_bus_message *call, + const char *types, ...) { + + va_list ap; + int r; + + va_start(ap, types); + r = sd_bus_reply_method_returnv(call, types, ap); + va_end(ap); + + return r; +} + _public_ int sd_bus_reply_method_error( sd_bus_message *call, const sd_bus_error *e) { @@ -187,14 +243,13 @@ _public_ int sd_bus_reply_method_error( return sd_bus_send(call->bus, m, NULL); } -_public_ int sd_bus_reply_method_errorf( +_public_ int sd_bus_reply_method_errorfv( sd_bus_message *call, const char *name, const char *format, - ...) { + va_list ap) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - va_list ap; assert_return(call, -EINVAL); assert_return(call->sealed, -EPERM); @@ -208,13 +263,27 @@ _public_ int sd_bus_reply_method_errorf( if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) return 0; - va_start(ap, format); bus_error_setfv(&error, name, format, ap); - va_end(ap); return sd_bus_reply_method_error(call, &error); } +_public_ int sd_bus_reply_method_errorf( + sd_bus_message *call, + const char *name, + const char *format, + ...) { + + va_list ap; + int r; + + va_start(ap, format); + r = sd_bus_reply_method_errorfv(call, name, format, ap); + va_end(ap); + + return r; +} + _public_ int sd_bus_reply_method_errno( sd_bus_message *call, int error, @@ -242,14 +311,13 @@ _public_ int sd_bus_reply_method_errno( return sd_bus_reply_method_error(call, &berror); } -_public_ int sd_bus_reply_method_errnof( +_public_ int sd_bus_reply_method_errnofv( sd_bus_message *call, int error, const char *format, - ...) { + va_list ap) { _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL; - va_list ap; assert_return(call, -EINVAL); assert_return(call->sealed, -EPERM); @@ -263,13 +331,27 @@ _public_ int sd_bus_reply_method_errnof( if (call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED) return 0; - va_start(ap, format); sd_bus_error_set_errnofv(&berror, error, format, ap); - va_end(ap); return sd_bus_reply_method_error(call, &berror); } +_public_ int sd_bus_reply_method_errnof( + sd_bus_message *call, + int error, + const char *format, + ...) { + + va_list ap; + int r; + + va_start(ap, format); + r = sd_bus_reply_method_errnofv(call, error, format, ap); + va_end(ap); + + return r; +} + _public_ int sd_bus_get_property( sd_bus *bus, const char *destination, @@ -452,17 +534,16 @@ fail: return sd_bus_error_set_errno(error, r); } -_public_ int sd_bus_set_property( +_public_ int sd_bus_set_propertyv( sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, - const char *type, ...) { + const char *type, va_list ap) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; - va_list ap; int r; bus_assert_return(bus, -EINVAL, error); @@ -489,9 +570,7 @@ _public_ int sd_bus_set_property( if (r < 0) goto fail; - va_start(ap, type); r = sd_bus_message_appendv(m, type, ap); - va_end(ap); if (r < 0) goto fail; @@ -505,6 +584,25 @@ fail: return sd_bus_error_set_errno(error, r); } +_public_ int sd_bus_set_property( + sd_bus *bus, + const char *destination, + const char *path, + const char *interface, + const char *member, + sd_bus_error *error, + const char *type, ...) { + + va_list ap; + int r; + + va_start(ap, type); + r = sd_bus_set_propertyv(bus, destination, path, interface, member, error, type, ap); + va_end(ap); + + return r; +} + _public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds) { sd_bus_creds *c; diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c index caab5e5ebe..94107c297f 100644 --- a/src/libsystemd/sd-bus/bus-dump.c +++ b/src/libsystemd/sd-bus/bus-dump.c @@ -56,7 +56,7 @@ _public_ int sd_bus_message_dump(sd_bus_message *m, FILE *f, uint64_t flags) { if (flags & SD_BUS_MESSAGE_DUMP_WITH_HEADER) { fprintf(f, - "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u Priority=%"PRIi64, + "%s%s%s Type=%s%s%s Endian=%c Flags=%u Version=%u", m->header->type == SD_BUS_MESSAGE_METHOD_ERROR ? ansi_highlight_red() : m->header->type == SD_BUS_MESSAGE_METHOD_RETURN ? ansi_highlight_green() : m->header->type != SD_BUS_MESSAGE_SIGNAL ? ansi_highlight() : "", @@ -69,8 +69,7 @@ _public_ int sd_bus_message_dump(sd_bus_message *m, FILE *f, uint64_t flags) { m->header->endian, m->header->flags, - m->header->version, - m->priority); + m->header->version); /* Display synthetic message serial number in a more readable * format than (uint32_t) -1 */ diff --git a/src/libsystemd/sd-bus/bus-internal.c b/src/libsystemd/sd-bus/bus-internal.c index d5f8c6db64..5c3e955c20 100644 --- a/src/libsystemd/sd-bus/bus-internal.c +++ b/src/libsystemd/sd-bus/bus-internal.c @@ -314,13 +314,9 @@ char *bus_address_escape(const char *v) { int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) { assert(m); - if (r < 0) { + if (sd_bus_error_is_set(error) || r < 0) { if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) sd_bus_reply_method_errno(m, r, error); - - } else if (sd_bus_error_is_set(error)) { - if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL) - sd_bus_reply_method_error(m, error); } else return r; diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c index 62c34d9312..8c0234405a 100644 --- a/src/libsystemd/sd-bus/bus-message.c +++ b/src/libsystemd/sd-bus/bus-message.c @@ -5924,18 +5924,31 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) { } _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) { + static bool warned = false; + assert_return(m, -EINVAL); assert_return(priority, -EINVAL); - *priority = m->priority; + if (!warned) { + log_debug("sd_bus_message_get_priority() is deprecated and always returns 0."); + warned = true; + } + + *priority = 0; return 0; } _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) { + static bool warned = false; + assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - m->priority = priority; + if (!warned) { + log_debug("sd_bus_message_set_priority() is deprecated and does nothing."); + warned = true; + } + return 0; } diff --git a/src/libsystemd/sd-bus/bus-message.h b/src/libsystemd/sd-bus/bus-message.h index a88a531e15..5d869213ab 100644 --- a/src/libsystemd/sd-bus/bus-message.h +++ b/src/libsystemd/sd-bus/bus-message.h @@ -76,7 +76,6 @@ struct sd_bus_message { usec_t monotonic; usec_t realtime; uint64_t seqnum; - int64_t priority; uint64_t verify_destination_id; bool sealed:1; diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 5cbd01594c..78e18e3b94 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1833,7 +1833,7 @@ static int dispatch_wqueue(sd_bus *bus) { return ret; } -static int bus_read_message(sd_bus *bus, bool hint_priority, int64_t priority) { +static int bus_read_message(sd_bus *bus) { assert(bus); return bus_socket_read_message(bus); @@ -1860,17 +1860,13 @@ static void rqueue_drop_one(sd_bus *bus, size_t i) { bus->rqueue_size--; } -static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **m) { +static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) { int r, ret = 0; assert(bus); assert(m); assert(IN_SET(bus->state, BUS_RUNNING, BUS_HELLO)); - /* Note that the priority logic is only available on kdbus, - * where the rqueue is unused. We check the rqueue here - * anyway, because it's simple... */ - for (;;) { if (bus->rqueue_size > 0) { /* Dispatch a queued message */ @@ -1880,7 +1876,7 @@ static int dispatch_rqueue(sd_bus *bus, bool hint_priority, int64_t priority, sd } /* Try to read a new message */ - r = bus_read_message(bus, hint_priority, priority); + r = bus_read_message(bus); if (r < 0) return r; if (r == 0) { @@ -2237,7 +2233,7 @@ _public_ int sd_bus_call( i++; } - r = bus_read_message(bus, false, 0); + r = bus_read_message(bus); if (r < 0) { if (ERRNO_IS_DISCONNECT(r)) { bus_enter_closing(bus); @@ -2776,7 +2772,7 @@ static int dispatch_track(sd_bus *bus) { return 1; } -static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { +static int process_running(sd_bus *bus, sd_bus_message **ret) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; @@ -2795,7 +2791,7 @@ static int process_running(sd_bus *bus, bool hint_priority, int64_t priority, sd if (r != 0) goto null_message; - r = dispatch_rqueue(bus, hint_priority, priority, &m); + r = dispatch_rqueue(bus, &m); if (r < 0) return r; if (!m) @@ -2981,7 +2977,7 @@ finish: return r; } -static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priority, sd_bus_message **ret) { +static int bus_process_internal(sd_bus *bus, sd_bus_message **ret) { int r; /* Returns 0 when we didn't do anything. This should cause the @@ -3021,7 +3017,7 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit case BUS_RUNNING: case BUS_HELLO: - r = process_running(bus, hint_priority, priority, ret); + r = process_running(bus, ret); if (r >= 0) return r; @@ -3048,11 +3044,11 @@ static int bus_process_internal(sd_bus *bus, bool hint_priority, int64_t priorit } _public_ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) { - return bus_process_internal(bus, false, 0, ret); + return bus_process_internal(bus, ret); } _public_ int sd_bus_process_priority(sd_bus *bus, int64_t priority, sd_bus_message **ret) { - return bus_process_internal(bus, true, priority, ret); + return bus_process_internal(bus, ret); } static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c index 964200a55e..acfab8ed74 100644 --- a/src/libsystemd/sd-network/sd-network.c +++ b/src/libsystemd/sd-network/sd-network.c @@ -256,6 +256,14 @@ _public_ int sd_network_link_get_sip_servers(int ifindex, char ***ret) { return network_link_get_strv(ifindex, "SIP", ret); } +_public_ int sd_network_link_get_pop3_servers(int ifindex, char ***pop3) { + return network_link_get_strv(ifindex, "POP3_SERVERS", pop3); +} + +_public_ int sd_network_link_get_smtp_servers(int ifindex, char ***ret) { + return network_link_get_strv(ifindex, "SMTP_SERVERS", ret); +} + _public_ int sd_network_link_get_dns_default_route(int ifindex) { char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1]; _cleanup_free_ char *s = NULL; diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c index 95d6551e5c..2a9c04a84d 100644 --- a/src/libsystemd/sd-path/sd-path.c +++ b/src/libsystemd/sd-path/sd-path.c @@ -7,6 +7,7 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +#include "path-lookup.h" #include "path-util.h" #include "string-util.h" #include "strv.h" @@ -318,64 +319,130 @@ static int get_path(uint64_t type, char **buffer, const char **ret) { case SD_PATH_USER_DESKTOP: return from_user_dir("XDG_DESKTOP_DIR", buffer, ret); + + case SD_PATH_SYSTEMD_UTIL_DIR: + *ret = ROOTPREFIX "lib/systemd"; + return 0; + + case SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR: + *ret = SYSTEM_DATA_UNIT_PATH; + return 0; + + case SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR: + *ret = ROOTPREFIX "lib/systemd/system-preset"; + return 0; + + case SD_PATH_SYSTEMD_USER_UNIT_DIR: + *ret = USER_DATA_UNIT_DIR; + return 0; + + case SD_PATH_SYSTEMD_USER_PRESET_DIR: + *ret = ROOTPREFIX "lib/systemd/user-preset"; + return 0; + + case SD_PATH_SYSTEMD_SYSTEM_CONF_DIR: + *ret = SYSTEM_CONFIG_UNIT_DIR; + return 0; + + case SD_PATH_SYSTEMD_USER_CONF_DIR: + *ret = USER_CONFIG_UNIT_DIR; + return 0; + + case SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR: + *ret = SYSTEM_GENERATOR_DIR; + return 0; + + case SD_PATH_SYSTEMD_USER_GENERATOR_DIR: + *ret = USER_GENERATOR_DIR; + return 0; + + case SD_PATH_SYSTEMD_SLEEP_DIR: + *ret = ROOTPREFIX "lib/systemd/system-sleep"; + return 0; + + case SD_PATH_SYSTEMD_SHUTDOWN_DIR: + *ret = ROOTPREFIX "lib/systemd/system-shutdown"; + return 0; + + /* FIXME: systemd.pc uses ${prefix}, but CONF_PATHS_NULSTR doesn't. + * Should ${prefix} use in systemd.pc be removed? */ + case SD_PATH_TMPFILES_DIR: + *ret = "/usr/lib/tmpfiles.d"; + return 0; + + case SD_PATH_SYSUSERS_DIR: + *ret = "/usr/lib/sysusers.d"; + return 0; + + case SD_PATH_SYSCTL_DIR: + *ret = "/usr/lib/sysctl.d"; + return 0; + + case SD_PATH_BINFMT_DIR: + *ret = "/usr/lib/binfmt.d"; + return 0; + + case SD_PATH_MODULES_LOAD_DIR: + *ret = "/usr/lib/modules-load.d"; + return 0; + + case SD_PATH_CATALOG_DIR: + *ret = "/usr/lib/systemd/catalog"; + return 0; } return -EOPNOTSUPP; } -_public_ int sd_path_home(uint64_t type, const char *suffix, char **path) { +static int get_path_alloc(uint64_t type, const char *suffix, char **path) { _cleanup_free_ char *buffer = NULL; + char *buffer2 = NULL; const char *ret; - char *cc; int r; - assert_return(path, -EINVAL); - - if (IN_SET(type, - SD_PATH_SEARCH_BINARIES, - SD_PATH_SEARCH_BINARIES_DEFAULT, - SD_PATH_SEARCH_LIBRARY_PRIVATE, - SD_PATH_SEARCH_LIBRARY_ARCH, - SD_PATH_SEARCH_SHARED, - SD_PATH_SEARCH_CONFIGURATION_FACTORY, - SD_PATH_SEARCH_STATE_FACTORY, - SD_PATH_SEARCH_CONFIGURATION)) { + assert(path); - _cleanup_strv_free_ char **l = NULL; - - r = sd_path_search(type, suffix, &l); - if (r < 0) - return r; + r = get_path(type, &buffer, &ret); + if (r < 0) + return r; - buffer = strv_join(l, ":"); + if (suffix) { + suffix += strspn(suffix, "/"); + buffer2 = path_join(ret, suffix); + if (!buffer2) + return -ENOMEM; + } else if (!buffer) { + buffer = strdup(ret); if (!buffer) return -ENOMEM; - - *path = TAKE_PTR(buffer); - return 0; } - r = get_path(type, &buffer, &ret); - if (r < 0) + *path = buffer2 ?: TAKE_PTR(buffer); + return 0; +} + +_public_ int sd_path_lookup(uint64_t type, const char *suffix, char **path) { + int r; + + assert_return(path, -EINVAL); + + r = get_path_alloc(type, suffix, path); + if (r != -EOPNOTSUPP) return r; - if (!suffix) { - if (!buffer) { - buffer = strdup(ret); - if (!buffer) - return -ENOMEM; - } + /* Fall back to sd_path_lookup_strv */ + _cleanup_strv_free_ char **l = NULL; + char *buffer; - *path = TAKE_PTR(buffer); - return 0; - } + r = sd_path_lookup_strv(type, suffix, &l); + if (r < 0) + return r; - suffix += strspn(suffix, "/"); - cc = path_join(ret, suffix); - if (!cc) + buffer = strv_join(l, ":"); + if (!buffer) return -ENOMEM; - *path = TAKE_PTR(cc); + *path = buffer; return 0; } @@ -454,6 +521,7 @@ static int search_from_environment( #endif static int get_search(uint64_t type, char ***list) { + int r; assert(list); @@ -536,58 +604,69 @@ static int get_search(uint64_t type, char ***list) { "/etc", NULL); - case SD_PATH_SEARCH_BINARIES_DEFAULT: { + case SD_PATH_SEARCH_BINARIES_DEFAULT: + return strv_from_nulstr(list, DEFAULT_PATH_NULSTR); + + case SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH: + case SD_PATH_SYSTEMD_USER_UNIT_PATH: { + _cleanup_(lookup_paths_free) LookupPaths lp = {}; + const UnitFileScope scope = type == SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH ? + UNIT_FILE_SYSTEM : UNIT_FILE_USER; + + r = lookup_paths_init(&lp, scope, 0, NULL); + if (r < 0) + return r; + + *list = TAKE_PTR(lp.search_path); + return 0; + } + + case SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH: + case SD_PATH_SYSTEMD_USER_GENERATOR_PATH: { char **t; + const UnitFileScope scope = type == SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH ? + UNIT_FILE_SYSTEM : UNIT_FILE_USER; - t = strv_split_nulstr(DEFAULT_PATH_NULSTR); + t = generator_binary_paths(scope); if (!t) return -ENOMEM; *list = t; return 0; - }} + } + + case SD_PATH_SYSTEMD_NETWORK_PATH: + return strv_from_nulstr(list, NETWORK_DIRS_NULSTR); + + } return -EOPNOTSUPP; } -_public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { - char **i, **j; +_public_ int sd_path_lookup_strv(uint64_t type, const char *suffix, char ***paths) { _cleanup_strv_free_ char **l = NULL, **n = NULL; int r; assert_return(paths, -EINVAL); - if (!IN_SET(type, - SD_PATH_SEARCH_BINARIES, - SD_PATH_SEARCH_BINARIES_DEFAULT, - SD_PATH_SEARCH_LIBRARY_PRIVATE, - SD_PATH_SEARCH_LIBRARY_ARCH, - SD_PATH_SEARCH_SHARED, - SD_PATH_SEARCH_CONFIGURATION_FACTORY, - SD_PATH_SEARCH_STATE_FACTORY, - SD_PATH_SEARCH_CONFIGURATION)) { - - char *p; + r = get_search(type, &l); + if (r == -EOPNOTSUPP) { + _cleanup_free_ char *t = NULL; - r = sd_path_home(type, suffix, &p); + r = get_path_alloc(type, suffix, &t); if (r < 0) return r; l = new(char*, 2); - if (!l) { - free(p); + if (!l) return -ENOMEM; - } - - l[0] = p; + l[0] = TAKE_PTR(t); l[1] = NULL; *paths = TAKE_PTR(l); return 0; - } - r = get_search(type, &l); - if (r < 0) + } else if (r < 0) return r; if (!suffix) { @@ -599,7 +678,7 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { if (!n) return -ENOMEM; - j = n; + char **i, **j = n; STRV_FOREACH(i, l) { *j = path_join(*i, suffix); if (!*j) @@ -607,8 +686,8 @@ _public_ int sd_path_search(uint64_t type, const char *suffix, char ***paths) { j++; } - *j = NULL; + *paths = TAKE_PTR(n); return 0; } diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index a2990452af..5c0f714184 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -20,6 +20,7 @@ #include "env-file.h" #include "env-util.h" #include "fd-util.h" +#include "fileio.h" #include "format-util.h" #include "fs-util.h" #include "in-addr-util.h" @@ -399,12 +400,10 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s pair[1] = safe_close(pair[1]); - f = fdopen(pair[0], "r"); + f = take_fdopen(&pair[0], "r"); if (!f) return -errno; - pair[0] = -1; - r = load_env_file_pairs(f, "/etc/os-release", &l); if (r < 0) return r; diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index d0cc07678f..97dfb94278 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -620,12 +620,10 @@ 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, "r"); + f = take_fdopen(&operation->extra_fd, "r"); if (!f) return -errno; - operation->extra_fd = -1; - /* The resulting temporary file starts with a boolean value that indicates success or not. */ errno = 0; n = fread(&success, 1, sizeof(success), f); diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index f8121a48ed..bc85d4babb 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -24,6 +24,7 @@ #include "network-internal.h" #include "networkd-manager.h" #include "nlmon.h" +#include "path-lookup.h" #include "siphash24.h" #include "stat-util.h" #include "string-table.h" diff --git a/src/network/networkctl.c b/src/network/networkctl.c index b68798769b..952fd55578 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -1240,7 +1240,8 @@ static int link_status_one( sd_hwdb *hwdb, const LinkInfo *info) { - _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL; + _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL, + **pop3_server = NULL, **smtp_server = NULL; _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL; _cleanup_free_ char *t = NULL, *network = NULL; const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL; @@ -1267,6 +1268,8 @@ static int link_status_one( (void) sd_network_link_get_route_domains(info->ifindex, &route_domains); (void) sd_network_link_get_ntp(info->ifindex, &ntp); (void) sd_network_link_get_sip(info->ifindex, &sip); + (void) sd_network_link_get_pop3_servers(info->ifindex, &pop3_server); + (void) sd_network_link_get_smtp_servers(info->ifindex, &smtp_server); if (info->sd_device) { (void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link); @@ -1829,6 +1832,12 @@ static int link_status_one( r = dump_list(table, "SIP:", sip); if (r < 0) return r; + r = dump_list(table, "POP3 servers:", pop3_server); + if (r < 0) + return r; + r = dump_list(table, "SMTP servers:", smtp_server); + if (r < 0) + return r; r = dump_ifindexes(table, "Carrier Bound To:", carrier_bound_to); if (r < 0) return r; @@ -2175,6 +2184,69 @@ static int link_delete_send_message(sd_netlink *rtnl, int index) { return 0; } +static int link_up_down_send_message(sd_netlink *rtnl, char *command, int index) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + int r; + + assert(rtnl); + + r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, index); + if (r < 0) + return rtnl_log_create_error(r); + + if (streq(command, "up")) + r = sd_rtnl_message_link_set_flags(req, IFF_UP, IFF_UP); + else + r = sd_rtnl_message_link_set_flags(req, 0, IFF_UP); + if (r < 0) + return log_error_errno(r, "Could not set link flags: %m"); + + r = sd_netlink_call(rtnl, req, 0, NULL); + if (r < 0) + return r; + + return 0; +} + +static int link_up_down(int argc, char *argv[], void *userdata) { + _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; + _cleanup_set_free_ Set *indexes = NULL; + int index, r, i; + Iterator j; + void *p; + + r = sd_netlink_open(&rtnl); + if (r < 0) + return log_error_errno(r, "Failed to connect to netlink: %m"); + + indexes = set_new(NULL); + if (!indexes) + return log_oom(); + + for (i = 1; i < argc; i++) { + index = resolve_interface_or_warn(&rtnl, argv[i]); + if (index < 0) + return index; + + r = set_put(indexes, INT_TO_PTR(index)); + if (r < 0) + return log_oom(); + } + + SET_FOREACH(p, indexes, j) { + index = PTR_TO_INT(p); + r = link_up_down_send_message(rtnl, argv[0], index); + if (r < 0) { + char ifname[IF_NAMESIZE + 1]; + + return log_error_errno(r, "Failed to %s interface %s: %m", + argv[1], format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX)); + } + } + + return r; +} + static int link_delete(int argc, char *argv[], void *userdata) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_set_free_ Set *indexes = NULL; @@ -2383,6 +2455,8 @@ static int help(void) { " lldp [PATTERN...] Show LLDP neighbors\n" " label Show current address label entries in the kernel\n" " delete DEVICES... Delete virtual netdevs\n" + " up DEVICES... Bring devices up\n" + " down DEVICES... Bring devices down\n" " renew DEVICES... Renew dynamic configurations\n" " forcerenew DEVICES... Trigger DHCP reconfiguration of all connected clients\n" " reconfigure DEVICES... Reconfigure interfaces\n" @@ -2485,6 +2559,8 @@ static int networkctl_main(int argc, char *argv[]) { { "lldp", VERB_ANY, VERB_ANY, 0, link_lldp_status }, { "label", VERB_ANY, VERB_ANY, 0, list_address_labels }, { "delete", 2, VERB_ANY, 0, link_delete }, + { "up", 2, VERB_ANY, 0, link_up_down }, + { "down", 2, VERB_ANY, 0, link_up_down }, { "renew", 2, VERB_ANY, 0, link_renew }, { "forcerenew", 2, VERB_ANY, 0, link_force_renew }, { "reconfigure", 2, VERB_ANY, 0, verb_reconfigure }, diff --git a/src/network/networkd-can.c b/src/network/networkd-can.c index 18533843e3..fdd99a3a18 100644 --- a/src/network/networkd-can.c +++ b/src/network/networkd-can.c @@ -7,10 +7,51 @@ #include "networkd-can.h" #include "networkd-link.h" #include "networkd-manager.h" +#include "parse-util.h" #include "string-util.h" #define CAN_TERMINATION_OHM_VALUE 120 +int config_parse_can_bitrate( + const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + uint32_t *br = data; + uint64_t sz; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = parse_size(rvalue, 1000, &sz); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse can bitrate '%s', ignoring: %m", rvalue); + return 0; + } + + /* Linux uses __u32 for bitrates, so the value should not exceed that. */ + if (sz <= 0 || sz > UINT32_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Bit rate out of permitted range 1...4294967295"); + return 0; + } + + *br = (uint32_t) sz; + + return 0; +} + static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { int r; @@ -103,11 +144,6 @@ static int link_set_can(Link *link) { .sample_point = link->network->can_sample_point, }; - if (link->network->can_bitrate > UINT32_MAX) { - log_link_error(link, "bitrate (%" PRIu64 ") too big.", link->network->can_bitrate); - return -ERANGE; - } - log_link_debug(link, "Setting bitrate = %d bit/s", bt.bitrate); if (link->network->can_sample_point > 0) log_link_debug(link, "Setting sample point = %d.%d%%", bt.sample_point / 10, bt.sample_point % 10); @@ -119,6 +155,35 @@ static int link_set_can(Link *link) { return log_link_error_errno(link, r, "Could not append IFLA_CAN_BITTIMING attribute: %m"); } + if (link->network->can_data_bitrate > 0 || link->network->can_data_sample_point > 0) { + struct can_bittiming bt = { + .bitrate = link->network->can_data_bitrate, + .sample_point = link->network->can_data_sample_point, + }; + + log_link_debug(link, "Setting data bitrate = %d bit/s", bt.bitrate); + if (link->network->can_data_sample_point > 0) + log_link_debug(link, "Setting data sample point = %d.%d%%", bt.sample_point / 10, bt.sample_point % 10); + else + log_link_debug(link, "Using default data sample point"); + + r = sd_netlink_message_append_data(m, IFLA_CAN_DATA_BITTIMING, &bt, sizeof(bt)); + if (r < 0) + return log_link_error_errno(link, r, "Could not append IFLA_CAN_DATA_BITTIMING attribute: %m"); + } + + if (link->network->can_fd_mode >= 0) { + cm.mask |= CAN_CTRLMODE_FD; + SET_FLAG(cm.flags, CAN_CTRLMODE_FD, link->network->can_fd_mode > 0); + log_link_debug(link, "%sabling FD mode", link->network->can_fd_mode > 0 ? "En" : "Dis"); + } + + if (link->network->can_non_iso >= 0) { + cm.mask |= CAN_CTRLMODE_FD_NON_ISO; + SET_FLAG(cm.flags, CAN_CTRLMODE_FD_NON_ISO, link->network->can_non_iso > 0); + log_link_debug(link, "%sabling FD non-ISO mode", link->network->can_non_iso > 0 ? "En" : "Dis"); + } + if (link->network->can_restart_us > 0) { char time_string[FORMAT_TIMESPAN_MAX]; uint64_t restart_ms; diff --git a/src/network/networkd-can.h b/src/network/networkd-can.h index c744bdfea7..30e99b189d 100644 --- a/src/network/networkd-can.h +++ b/src/network/networkd-can.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +#include "conf-parser.h" + typedef struct Link Link; int link_configure_can(Link *link); + +CONFIG_PARSER_PROTOTYPE(config_parse_can_bitrate); diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 8664d8cdc0..0473aba615 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -8,6 +8,7 @@ #include "parse-util.h" #include "string-table.h" #include "strv.h" +#include "web-util.h" int config_parse_dhcp( const char* unit, @@ -265,6 +266,48 @@ int config_parse_dhcp6_pd_hint( return 0; } +int config_parse_dhcp6_mud_url( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *unescaped = NULL; + Network *network = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + network->dhcp6_mudurl = mfree(network->dhcp6_mudurl); + return 0; + } + + r = cunescape(rvalue, 0, &unescaped); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue); + return 0; + } + + if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Failed to parse MUD URL '%s', ignoring: %m", rvalue); + + return 0; + } + + return free_and_replace(network->dhcp6_mudurl, unescaped); +} + int config_parse_dhcp_send_option( const char *unit, const char *filename, diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index 1d6ddbb8cc..ca86016ef2 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -48,4 +48,5 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_sip); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 2ec742b5e3..bbaa10f5ab 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -140,6 +140,104 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) { return sd_dhcp_server_set_ntp(s, addresses, n_addresses); } +static int link_push_uplink_pop3_to_dhcp_server(Link *link, sd_dhcp_server *s) { + _cleanup_free_ struct in_addr *addresses = NULL; + size_t n_addresses = 0, n_allocated = 0; + char **a; + + if (!link->network) + return 0; + + log_link_debug(link, "Copying POP3 server information from link"); + + STRV_FOREACH(a, link->network->pop3) { + union in_addr_union ia; + + /* Only look for IPv4 addresses */ + if (in_addr_from_string(AF_INET, *a, &ia) <= 0) + continue; + + /* Never propagate obviously borked data */ + if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in)) + continue; + + if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1)) + return log_oom(); + + addresses[n_addresses++] = ia.in; + } + + if (link->dhcp_lease) { + const struct in_addr *da = NULL; + int j, n; + + n = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &da); + if (n > 0) { + + if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n)) + return log_oom(); + + for (j = 0; j < n; j++) + if (in4_addr_is_non_local(&da[j])) + addresses[n_addresses++] = da[j]; + } + } + + if (n_addresses <= 0) + return 0; + + return sd_dhcp_server_set_pop3_server(s, addresses, n_addresses); +} + +static int link_push_uplink_smtp_to_dhcp_server(Link *link, sd_dhcp_server *s) { + _cleanup_free_ struct in_addr *addresses = NULL; + size_t n_addresses = 0, n_allocated = 0; + char **a; + + if (!link->network) + return 0; + + log_link_debug(link, "Copying SMTP server information from link"); + + STRV_FOREACH(a, link->network->smtp) { + union in_addr_union ia; + + /* Only look for IPv4 addresses */ + if (in_addr_from_string(AF_INET, *a, &ia) <= 0) + continue; + + /* Never propagate obviously borked data */ + if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in)) + continue; + + if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1)) + return log_oom(); + + addresses[n_addresses++] = ia.in; + } + + if (link->dhcp_lease) { + const struct in_addr *da = NULL; + int j, n; + + n = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &da); + if (n > 0) { + + if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n)) + return log_oom(); + + for (j = 0; j < n; j++) + if (in4_addr_is_non_local(&da[j])) + addresses[n_addresses++] = da[j]; + } + } + + if (n_addresses <= 0) + return 0; + + return sd_dhcp_server_set_smtp_server(s, addresses, n_addresses); +} + static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) { _cleanup_free_ struct in_addr *addresses = NULL; size_t n_addresses = 0, n_allocated = 0; @@ -281,6 +379,37 @@ int dhcp4_server_configure(Link *link) { log_link_warning_errno(link, r, "Failed to set SIP server for DHCP server, ignoring: %m"); } + if (link->network->n_dhcp_server_pop3 > 0) + r = sd_dhcp_server_set_pop3_server(link->dhcp_server, link->network->dhcp_server_pop3, link->network->n_dhcp_server_pop3); + else { + if (!acquired_uplink) + uplink = manager_find_uplink(link->manager, link); + + if (!uplink) { + log_link_debug(link, "Not emitting POP3 server information on link, couldn't find suitable uplink."); + r = 0; + } else + r = link_push_uplink_pop3_to_dhcp_server(uplink, link->dhcp_server); + } + if (r < 0) + log_link_warning_errno(link, r, "Failed to set POP3 server for DHCP server, ignoring: %m"); + + if (link->network->n_dhcp_server_smtp > 0) + r = sd_dhcp_server_set_smtp_server(link->dhcp_server, link->network->dhcp_server_smtp, link->network->n_dhcp_server_smtp); + else { + if (!acquired_uplink) + uplink = manager_find_uplink(link->manager, link); + + if (!uplink) { + log_link_debug(link, "Not emitting SMTP server information on link, couldn't find suitable uplink."); + r = 0; + } else + r = link_push_uplink_smtp_to_dhcp_server(uplink, link->dhcp_server); + } + if (r < 0) + log_link_warning_errno(link, r, "Failed to SMTP server for DHCP server, ignoring: %m"); + + r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router); if (r < 0) return log_link_error_errno(link, r, "Failed to set router emission for DHCP server: %m"); @@ -485,4 +614,114 @@ int config_parse_dhcp_server_sip( m[n->n_dhcp_server_sip++] = a.in; n->dhcp_server_sip = m; } + + return 0; +} + +int config_parse_dhcp_server_pop3_servers( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = data; + const char *p = rvalue; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + for (;;) { + _cleanup_free_ char *w = NULL; + union in_addr_union a; + struct in_addr *m; + + r = extract_first_word(&p, &w, NULL, 0); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to extract word, ignoring: %s", rvalue); + return 0; + } + if (r == 0) + return 0; + + r = in_addr_from_string(AF_INET, w, &a); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse POP3 server address '%s', ignoring: %m", w); + continue; + } + + m = reallocarray(n->dhcp_server_pop3, n->n_dhcp_server_pop3 + 1, sizeof(struct in_addr)); + if (!m) + return log_oom(); + + m[n->n_dhcp_server_pop3++] = a.in; + n->dhcp_server_pop3 = m; + } + + return 0; +} + +int config_parse_dhcp_server_smtp_servers( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = data; + const char *p = rvalue; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + for (;;) { + _cleanup_free_ char *w = NULL; + union in_addr_union a; + struct in_addr *m; + + r = extract_first_word(&p, &w, NULL, 0); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to extract word, ignoring: %s", rvalue); + return 0; + } + if (r == 0) + return 0; + + r = in_addr_from_string(AF_INET, w, &a); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to parse SMTP server address '%s', ignoring: %m", w); + continue; + } + + m = reallocarray(n->dhcp_server_smtp, n->n_dhcp_server_smtp + 1, sizeof(struct in_addr)); + if (!m) + return log_oom(); + + m[n->n_dhcp_server_smtp++] = a.in; + n->dhcp_server_smtp = m; + } + + return 0; } diff --git a/src/network/networkd-dhcp-server.h b/src/network/networkd-dhcp-server.h index c90d48ec00..9da475dd3f 100644 --- a/src/network/networkd-dhcp-server.h +++ b/src/network/networkd-dhcp-server.h @@ -12,3 +12,5 @@ int dhcp4_server_configure(Link *link); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_pop3_servers); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_smtp_servers); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 83fb25264a..48e5c15fd0 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -5,6 +5,7 @@ #include <linux/if.h> #include <linux/if_arp.h> +#include "escape.h" #include "alloc-util.h" #include "dhcp-client-internal.h" #include "hostname-util.h" @@ -17,6 +18,7 @@ #include "string-table.h" #include "string-util.h" #include "sysctl-util.h" +#include "web-util.h" static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all); static int dhcp_remove_router(Link *link, sd_dhcp_lease *lease, const struct in_addr *address, bool remove_all); @@ -1456,6 +1458,13 @@ int dhcp4_configure(Link *link) { return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set vendor class identifier: %m"); } + if (link->network->dhcp_mudurl) { + r = sd_dhcp_client_set_mud_url(link->dhcp_client, + link->network->dhcp_mudurl); + if (r < 0) + return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set MUD URL: %m"); + } + if (link->network->dhcp_user_class) { r = sd_dhcp_client_set_user_class(link->dhcp_client, (const char **) link->network->dhcp_user_class); if (r < 0) @@ -1744,6 +1753,48 @@ int config_parse_dhcp_ip_service_type( return 0; } +int config_parse_dhcp_mud_url( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *unescaped = NULL; + Network *network = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + if (isempty(rvalue)) { + network->dhcp_mudurl = mfree(network->dhcp_mudurl); + return 0; + } + + r = cunescape(rvalue, 0, &unescaped); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to Failed to unescape MUD URL, ignoring: %s", rvalue); + return 0; + } + + if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Failed to parse MUD URL '%s', ignoring: %m", rvalue); + + return 0; + } + + return free_and_strdup_warn(&network->dhcp_mudurl, unescaped); +} + static const char* const dhcp_client_identifier_table[_DHCP_CLIENT_ID_MAX] = { [DHCP_CLIENT_ID_MAC] = "mac", [DHCP_CLIENT_ID_DUID] = "duid", diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h index 95fa5ee4b5..b0c30b598c 100644 --- a/src/network/networkd-dhcp4.h +++ b/src/network/networkd-dhcp4.h @@ -28,3 +28,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url); diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 7304270c60..3580498e35 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -676,6 +676,12 @@ int dhcp6_configure(Link *link) { return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set request flag for rapid commit: %m"); } + if (link->network->dhcp6_mudurl) { + r = sd_dhcp6_client_set_request_mud_url(client, link->network->dhcp6_mudurl); + if (r < 0) + return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set MUD URL: %m"); + } + r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); if (r < 0) return log_link_error_errno(link, r, "DHCP6 CLIENT: Failed to set callback: %m"); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index f38cc9f3cf..7672b33128 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -4100,6 +4100,36 @@ int link_save(Link *link) { space = true; } + fputc('\n', f); + + fputs("POP3_SERVERS=", f); + space = false; + fputstrv(f, link->network->pop3, NULL, &space); + + fputc('\n', f); + + fputs("SMTP_SERVERS=", f); + space = false; + fputstrv(f, link->network->smtp, NULL, &space); + + if (link->dhcp_lease) { + const struct in_addr *addresses; + + r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses); + if (r > 0) + if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0) + space = true; + } + + if (link->dhcp_lease) { + const struct in_addr *addresses; + + r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses); + if (r > 0) + if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0) + space = true; + } + if (link->network->dhcp6_use_ntp && dhcp6_lease) { struct in6_addr *in6_addrs; char **hosts; diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index 51db60e1f2..1fbf9d0dd9 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -6,6 +6,7 @@ #include <net/if_arp.h> #include "alloc-util.h" +#include "escape.h" #include "env-file.h" #include "fd-util.h" #include "hostname-util.h" @@ -18,6 +19,7 @@ #include "socket-util.h" #include "string-util.h" #include "unaligned.h" +#include "web-util.h" /* The LLDP spec calls this "txFastInit", see 9.2.5.19 */ #define LLDP_TX_FAST_INIT 4U @@ -81,9 +83,11 @@ static int lldp_make_packet( const char *pretty_hostname, uint16_t system_capabilities, uint16_t enabled_capabilities, + char *mud, void **ret, size_t *sz) { - size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, pretty_hostname_length = 0; + size_t machine_id_length, ifname_length, port_description_length = 0, hostname_length = 0, + pretty_hostname_length = 0, mud_length = 0; _cleanup_free_ void *packet = NULL; struct ether_header *h; uint8_t *p; @@ -110,6 +114,9 @@ static int lldp_make_packet( if (pretty_hostname) pretty_hostname_length = strlen(pretty_hostname); + if (mud) + mud_length = strlen(mud); + l = sizeof(struct ether_header) + /* Chassis ID */ 2 + 1 + machine_id_length + @@ -134,6 +141,10 @@ static int lldp_make_packet( if (pretty_hostname) l += 2 + pretty_hostname_length; + /* MUD URL */ + if (mud) + l += 2 + sizeof(SD_LLDP_OUI_MUD) + 1 + mud_length; + packet = malloc(l); if (!packet) return -ENOMEM; @@ -184,6 +195,32 @@ static int lldp_make_packet( p = mempcpy(p, pretty_hostname, pretty_hostname_length); } + if (mud) { + uint8_t oui_mud[sizeof(SD_LLDP_OUI_MUD)] = {0x00, 0x00, 0x5E}; + /* + * +--------+--------+----------+---------+-------------- + * |TLV Type| len | OUI |subtype | MUDString + * | =127 | |= 00 00 5E| = 1 | + * |(7 bits)|(9 bits)|(3 octets)|(1 octet)|(1-255 octets) + * +--------+--------+----------+---------+-------------- + * where: + + * o TLV Type = 127 indicates a vendor-specific TLV + * o len = indicates the TLV string length + * o OUI = 00 00 5E is the organizationally unique identifier of IANA + * o subtype = 1 (as assigned by IANA for the MUDstring) + * o MUDstring = the length MUST NOT exceed 255 octets + */ + + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_PRIVATE, sizeof(SD_LLDP_OUI_MUD) + 1 + mud_length); + if (r < 0) + return r; + + p = mempcpy(p, &oui_mud, sizeof(SD_LLDP_OUI_MUD)); + *(p++) = SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION; + p = mempcpy(p, mud, mud_length); + } + r = lldp_write_tlv_header(&p, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4); if (r < 0) return r; @@ -281,6 +318,7 @@ static int link_send_lldp(Link *link) { pretty_hostname, SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER, caps, + link->network ? link->network->lldp_mud : NULL, &packet, &packet_size); if (r < 0) return r; @@ -414,3 +452,40 @@ int config_parse_lldp_emit( return 0; } + +int config_parse_lldp_mud( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_free_ char *unescaped = NULL; + Network *n = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + r = cunescape(rvalue, 0, &unescaped); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "Failed to Failed to unescape LLDP MUD URL, ignoring: %s", rvalue); + return 0; + } + + if (!http_url_is_valid(unescaped) || strlen(unescaped) > 255) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "Failed to parse LLDP MUD URL '%s', ignoring: %m", rvalue); + + return 0; + } + + return free_and_replace(n->lldp_mud, unescaped); +} diff --git a/src/network/networkd-lldp-tx.h b/src/network/networkd-lldp-tx.h index 561becda41..1409984ac0 100644 --- a/src/network/networkd-lldp-tx.h +++ b/src/network/networkd-lldp-tx.h @@ -20,3 +20,4 @@ int link_lldp_emit_start(Link *link); void link_lldp_emit_stop(Link *link); CONFIG_PARSER_PROTOTYPE(config_parse_lldp_emit); +CONFIG_PARSER_PROTOTYPE(config_parse_lldp_mud); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 804f33d6cb..1348fcb9b3 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -30,6 +30,7 @@ #include "networkd-network-bus.h" #include "networkd-speed-meter.h" #include "ordered-set.h" +#include "path-lookup.h" #include "path-util.h" #include "set.h" #include "signal-util.h" @@ -1488,7 +1489,8 @@ static int ordered_set_put_in4_addrv(OrderedSet *s, } static int manager_save(Manager *m) { - _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL; + _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL, + *smtp = NULL, *search_domains = NULL, *route_domains = NULL; const char *operstate_str, *carrier_state_str, *address_state_str; LinkOperationalState operstate = LINK_OPERSTATE_OFF; LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF; @@ -1496,6 +1498,7 @@ static int manager_save(Manager *m) { _cleanup_free_ char *temp_path = NULL; _cleanup_strv_free_ char **p = NULL; _cleanup_fclose_ FILE *f = NULL; + const struct in_addr *addresses; Link *link; Iterator i; int r; @@ -1512,10 +1515,18 @@ static int manager_save(Manager *m) { if (!ntp) return -ENOMEM; - sip = ordered_set_new(&string_hash_ops); - if (!sip) + sip = ordered_set_new(&string_hash_ops); + if (!sip) return -ENOMEM; + pop3 = ordered_set_new(&string_hash_ops); + if (!pop3) + return -ENOMEM; + + smtp = ordered_set_new(&string_hash_ops); + if (!smtp) + return -ENOMEM; + search_domains = ordered_set_new(&dns_name_hash_ops); if (!search_domains) return -ENOMEM; @@ -1562,8 +1573,6 @@ static int manager_save(Manager *m) { /* Secondly, add the entries acquired via DHCP */ if (link->network->dhcp_use_dns) { - const struct in_addr *addresses; - r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); if (r > 0) { r = ordered_set_put_in4_addrv(dns, addresses, r, in4_addr_is_non_local); @@ -1574,8 +1583,6 @@ static int manager_save(Manager *m) { } if (link->network->dhcp_use_ntp) { - const struct in_addr *addresses; - r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); if (r > 0) { r = ordered_set_put_in4_addrv(ntp, addresses, r, in4_addr_is_non_local); @@ -1586,8 +1593,6 @@ static int manager_save(Manager *m) { } if (link->network->dhcp_use_sip) { - const struct in_addr *addresses; - r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses); if (r > 0) { r = ordered_set_put_in4_addrv(sip, addresses, r, in4_addr_is_non_local); @@ -1597,6 +1602,22 @@ static int manager_save(Manager *m) { return r; } + r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses); + if (r > 0) { + r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local); + if (r < 0) + return r; + } else if (r < 0 && r != -ENODATA) + return r; + + r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses); + if (r > 0) { + r = ordered_set_put_in4_addrv(smtp, addresses, r, in4_addr_is_non_local); + if (r < 0) + return r; + } else if (r < 0 && r != -ENODATA) + return r; + if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) { const char *domainname; char **domains = NULL; @@ -1648,6 +1669,8 @@ static int manager_save(Manager *m) { ordered_set_print(f, "DNS=", dns); ordered_set_print(f, "NTP=", ntp); ordered_set_print(f, "SIP=", sip); + ordered_set_print(f, "POP3_SERVERS=", pop3); + ordered_set_print(f, "SMTP_SERVERS=", smtp); ordered_set_print(f, "DOMAINS=", search_domains); ordered_set_print(f, "ROUTE_DOMAINS=", route_domains); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index fd996327a5..c63f57f962 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -6,6 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"") #include "conf-parser.h" #include "netem.h" #include "network-internal.h" +#include "networkd-can.h" #include "networkd-conf.h" #include "networkd-dhcp-common.h" #include "networkd-dhcp-server.h" @@ -170,6 +171,7 @@ DHCPv4.SendHostname, config_parse_bool, DHCPv4.Hostname, config_parse_hostname, 0, offsetof(Network, dhcp_hostname) DHCPv4.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) DHCPv4.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) +DHCPv4.MUDURL, config_parse_dhcp_mud_url, 0, 0 DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0 DHCPv4.UserClass, config_parse_dhcp_user_class, 0, offsetof(Network, dhcp_user_class) DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) @@ -189,6 +191,7 @@ DHCPv4.RouteMTUBytes, config_parse_mtu, DHCPv6.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp6_use_dns) DHCPv6.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp6_use_ntp) DHCPv6.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit) +DHCPv6.MUDURL, config_parse_dhcp6_mud_url, 0, 0 DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.WithoutRA, config_parse_bool, 0, offsetof(Network, dhcp6_without_ra) @@ -207,6 +210,8 @@ DHCPServer.EmitNTP, config_parse_bool, DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0 DHCPServer.EmitSIP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_sip) DHCPServer.SIP, config_parse_dhcp_server_sip, 0, 0 +DHCPServer.POP3Servers, config_parse_dhcp_server_pop3_servers, 0, 0 +DHCPServer.SMTPServers, config_parse_dhcp_server_smtp_servers, 0, 0 DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router) DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone) DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) @@ -254,8 +259,13 @@ IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, IPv6Prefix.Assign, config_parse_prefix_assign, 0, 0 IPv6RoutePrefix.Route, config_parse_route_prefix, 0, 0 IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime, 0, 0 -CAN.BitRate, config_parse_si_uint64, 0, offsetof(Network, can_bitrate) +LLDP.MUDURL, config_parse_lldp_mud, 0, 0 +CAN.BitRate, config_parse_can_bitrate, 0, offsetof(Network, can_bitrate) CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point) +CAN.DataBitRate, config_parse_can_bitrate, 0, offsetof(Network, can_data_bitrate) +CAN.DataSamplePoint, config_parse_permille, 0, offsetof(Network, can_data_sample_point) +CAN.FDMode, config_parse_tristate, 0, offsetof(Network, can_fd_mode) +CAN.FDNonISO, config_parse_tristate, 0, offsetof(Network, can_non_iso) CAN.RestartSec, config_parse_sec, 0, offsetof(Network, can_restart_us) CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling) CAN.Termination, config_parse_tristate, 0, offsetof(Network, can_termination) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index e7ead446c7..9edf9e1561 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -16,6 +16,7 @@ #include "networkd-manager.h" #include "networkd-network.h" #include "parse-util.h" +#include "path-lookup.h" #include "set.h" #include "socket-util.h" #include "stat-util.h" @@ -484,6 +485,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi "IPv6PrefixDelegation\0" "IPv6Prefix\0" "IPv6RoutePrefix\0" + "LLDP\0" "TrafficControlQueueingDiscipline\0" "CAN\0" "QDisc\0" @@ -639,11 +641,13 @@ static Network *network_free(Network *network) { free(network->description); free(network->dhcp_vendor_class_identifier); + free(network->dhcp_mudurl); strv_free(network->dhcp_user_class); free(network->dhcp_hostname); set_free(network->dhcp_black_listed_ip); set_free(network->dhcp_request_options); free(network->mac); + free(network->dhcp6_mudurl); if (network->dhcp_acd) sd_ipv4acd_unref(network->dhcp_acd); @@ -651,6 +655,7 @@ static Network *network_free(Network *network) { strv_free(network->ntp); free(network->dns); strv_free(network->sip); + strv_free(network->smtp); ordered_set_free_free(network->search_domains); ordered_set_free_free(network->route_domains); strv_free(network->bind_carrier); @@ -722,6 +727,8 @@ static Network *network_free(Network *network) { set_free_free(network->dnssec_negative_trust_anchors); + free(network->lldp_mud); + ordered_hashmap_free(network->dhcp_client_send_options); ordered_hashmap_free(network->dhcp_client_send_vendor_options); ordered_hashmap_free(network->dhcp_server_send_options); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index f747ccaf10..1c600ae7bd 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -91,6 +91,7 @@ struct Network { AddressFamily dhcp; DHCPClientIdentifier dhcp_client_identifier; char *dhcp_vendor_class_identifier; + char *dhcp_mudurl; char **dhcp_user_class; char *dhcp_hostname; uint64_t dhcp_max_attempts; @@ -130,6 +131,7 @@ struct Network { bool dhcp6_use_ntp; bool dhcp6_without_ra; uint8_t dhcp6_pd_length; + char *dhcp6_mudurl; struct in6_addr dhcp6_pd_address; /* DHCP Server Support */ @@ -147,6 +149,12 @@ struct Network { struct in_addr *dhcp_server_sip; unsigned n_dhcp_server_sip; + struct in_addr *dhcp_server_pop3; + unsigned n_dhcp_server_pop3; + + struct in_addr *dhcp_server_smtp; + unsigned n_dhcp_server_smtp; + bool dhcp_server_emit_router; bool dhcp_server_emit_timezone; char *dhcp_server_timezone; @@ -198,12 +206,16 @@ struct Network { uint32_t br_untagged_bitmap[BRIDGE_VLAN_BITMAP_LEN]; /* CAN support */ - uint64_t can_bitrate; + uint32_t can_bitrate; unsigned can_sample_point; + uint32_t can_data_bitrate; + unsigned can_data_sample_point; usec_t can_restart_us; int can_triple_sampling; int can_termination; int can_listen_only; + int can_fd_mode; + int can_non_iso; AddressFamily ip_forward; bool ip_masquerade; @@ -246,8 +258,10 @@ struct Network { bool required_for_online; /* Is this network required to be considered online? */ LinkOperationalStateRange required_operstate_for_online; + /* LLDP support */ LLDPMode lldp_mode; /* LLDP reception */ LLDPEmit lldp_emit; /* LLDP transmission */ + char *lldp_mud; /* LLDP MUD URL */ LIST_HEAD(Address, static_addresses); LIST_HEAD(Route, static_routes); @@ -296,6 +310,8 @@ struct Network { char **ntp; char **sip; + char **pop3; + char **smtp; char **bind_carrier; }; diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index fc591e2725..112c3562ac 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -8,6 +8,7 @@ #include "acl-util.h" #include "dirent-util.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "missing_magic.h" #include "nspawn-def.h" @@ -335,12 +336,11 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift donate_fd = true; } - d = fdopendir(fd); + d = take_fdopendir(&fd); if (!d) { r = -errno; goto finish; } - fd = -1; FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) { struct stat fst; diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c index cb2b2272b6..d0e575fef2 100644 --- a/src/nspawn/nspawn-setuid.c +++ b/src/nspawn/nspawn-setuid.c @@ -118,10 +118,9 @@ int change_uid_gid(const char *user, char **_home) { if (fd < 0) return fd; - f = fdopen(fd, "r"); + f = take_fdopen(&fd, "r"); if (!f) return log_oom(); - fd = -1; r = read_line(f, LONG_LINE_MAX, &line); if (r == 0) @@ -191,10 +190,9 @@ int change_uid_gid(const char *user, char **_home) { if (fd < 0) return fd; - f = fdopen(fd, "r"); + f = take_fdopen(&fd, "r"); if (!f) return log_oom(); - fd = -1; r = read_line(f, LONG_LINE_MAX, &line); if (r == 0) diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index 9c004616f5..581b7959bd 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -9,6 +9,7 @@ #include "group-record-nss.h" #include "macro.h" #include "nss-util.h" +#include "pthread-util.h" #include "signal-util.h" #include "strv.h" #include "user-util.h" @@ -277,10 +278,11 @@ static enum nss_status nss_systemd_endent(GetentData *p) { assert(p); - assert_se(pthread_mutex_lock(&p->mutex) == 0); + _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL; + _l = pthread_mutex_lock_assert(&p->mutex); + p->iterator = userdb_iterator_free(p->iterator); p->by_membership = false; - assert_se(pthread_mutex_unlock(&p->mutex) == 0); return NSS_STATUS_SUCCESS; } @@ -294,45 +296,41 @@ enum nss_status _nss_systemd_endgrent(void) { } enum nss_status _nss_systemd_setpwent(int stayopen) { - enum nss_status ret; - PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); if (userdb_nss_compat_is_enabled() <= 0) return NSS_STATUS_NOTFOUND; - assert_se(pthread_mutex_lock(&getpwent_data.mutex) == 0); + _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL; + int r; + + _l = pthread_mutex_lock_assert(&getpwent_data.mutex); getpwent_data.iterator = userdb_iterator_free(getpwent_data.iterator); getpwent_data.by_membership = false; - ret = userdb_all(nss_glue_userdb_flags(), &getpwent_data.iterator) < 0 ? - NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; - - assert_se(pthread_mutex_unlock(&getpwent_data.mutex) == 0); - return ret; + r = userdb_all(nss_glue_userdb_flags(), &getpwent_data.iterator); + return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; } enum nss_status _nss_systemd_setgrent(int stayopen) { - enum nss_status ret; - PROTECT_ERRNO; BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); if (userdb_nss_compat_is_enabled() <= 0) return NSS_STATUS_NOTFOUND; - assert_se(pthread_mutex_lock(&getgrent_data.mutex) == 0); + _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL; + int r; + + _l = pthread_mutex_lock_assert(&getgrent_data.mutex); getgrent_data.iterator = userdb_iterator_free(getgrent_data.iterator); getpwent_data.by_membership = false; - ret = groupdb_all(nss_glue_userdb_flags(), &getgrent_data.iterator) < 0 ? - NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; - - assert_se(pthread_mutex_unlock(&getgrent_data.mutex) == 0); - return ret; + r = groupdb_all(nss_glue_userdb_flags(), &getgrent_data.iterator); + return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; } enum nss_status _nss_systemd_getpwent_r( @@ -341,7 +339,6 @@ enum nss_status _nss_systemd_getpwent_r( int *errnop) { _cleanup_(user_record_unrefp) UserRecord *ur = NULL; - enum nss_status ret; int r; PROTECT_ERRNO; @@ -359,40 +356,33 @@ enum nss_status _nss_systemd_getpwent_r( if (!r) return NSS_STATUS_NOTFOUND; - assert_se(pthread_mutex_lock(&getpwent_data.mutex) == 0); + _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL; + + _l = pthread_mutex_lock_assert(&getpwent_data.mutex); if (!getpwent_data.iterator) { UNPROTECT_ERRNO; *errnop = EHOSTDOWN; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } r = userdb_iterator_get(getpwent_data.iterator, &ur); - if (r == -ESRCH) { - ret = NSS_STATUS_NOTFOUND; - goto finish; - } + if (r == -ESRCH) + return NSS_STATUS_NOTFOUND; if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } r = nss_pack_user_record(ur, result, buffer, buflen); if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_TRYAGAIN; - goto finish; + return NSS_STATUS_TRYAGAIN; } - ret = NSS_STATUS_SUCCESS; - -finish: - assert_se(pthread_mutex_unlock(&getpwent_data.mutex) == 0); - return ret; + return NSS_STATUS_SUCCESS; } enum nss_status _nss_systemd_getgrent_r( @@ -402,7 +392,6 @@ enum nss_status _nss_systemd_getgrent_r( _cleanup_(group_record_unrefp) GroupRecord *gr = NULL; _cleanup_free_ char **members = NULL; - enum nss_status ret; int r; PROTECT_ERRNO; @@ -420,19 +409,20 @@ enum nss_status _nss_systemd_getgrent_r( if (!r) return NSS_STATUS_UNAVAIL; - assert_se(pthread_mutex_lock(&getgrent_data.mutex) == 0); + _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL; + + _l = pthread_mutex_lock_assert(&getgrent_data.mutex); if (!getgrent_data.iterator) { UNPROTECT_ERRNO; *errnop = EHOSTDOWN; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } if (!getgrent_data.by_membership) { r = groupdb_iterator_get(getgrent_data.iterator, &gr); if (r == -ESRCH) { - /* So we finished iterating native groups now. let's now continue with iterating + /* So we finished iterating native groups now. Let's now continue with iterating * native memberships, and generate additional group entries for any groups * referenced there that are defined in NSS only. This means for those groups there * will be two or more entries generated during iteration, but this is apparently how @@ -444,23 +434,20 @@ enum nss_status _nss_systemd_getgrent_r( if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } getgrent_data.by_membership = true; } else if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } else if (!STR_IN_SET(gr->group_name, root_group.gr_name, nobody_group.gr_name)) { r = membershipdb_by_group_strv(gr->group_name, nss_glue_userdb_flags(), &members); if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } } } @@ -472,15 +459,12 @@ enum nss_status _nss_systemd_getgrent_r( _cleanup_free_ char *user_name = NULL, *group_name = NULL; r = membershipdb_iterator_get(getgrent_data.iterator, &user_name, &group_name); - if (r == -ESRCH) { - ret = NSS_STATUS_NOTFOUND; - goto finish; - } + if (r == -ESRCH) + return NSS_STATUS_NOTFOUND; if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } if (STR_IN_SET(user_name, root_passwd.pw_name, nobody_passwd.pw_name)) @@ -494,8 +478,7 @@ enum nss_status _nss_systemd_getgrent_r( if (lock_fd < 0 && lock_fd != -EBUSY) { UNPROTECT_ERRNO; *errnop = -lock_fd; - ret = NSS_STATUS_UNAVAIL; - goto finish; + return NSS_STATUS_UNAVAIL; } } @@ -525,15 +508,10 @@ enum nss_status _nss_systemd_getgrent_r( if (r < 0) { UNPROTECT_ERRNO; *errnop = -r; - ret = NSS_STATUS_TRYAGAIN; - goto finish; + return NSS_STATUS_TRYAGAIN; } - ret = NSS_STATUS_SUCCESS; - -finish: - assert_se(pthread_mutex_unlock(&getgrent_data.mutex) == 0); - return ret; + return NSS_STATUS_SUCCESS; } enum nss_status _nss_systemd_initgroups_dyn( diff --git a/src/partition/meson.build b/src/partition/meson.build index d0c111a473..3a75d5712d 100644 --- a/src/partition/meson.build +++ b/src/partition/meson.build @@ -3,3 +3,5 @@ systemd_repart_sources = files(''' repart.c '''.split()) + +test_repart_sh = find_program('test-repart.sh') diff --git a/src/partition/test-repart.sh b/src/partition/test-repart.sh new file mode 100755 index 0000000000..7da6b1b027 --- /dev/null +++ b/src/partition/test-repart.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +set -ex + +repart=$1 +test -x $repart + +D=$(mktemp --directory) +trap "rm -rf '$D'" EXIT INT QUIT PIPE +mkdir -p $D/definitions + +truncate -s 1G $D/zzz + +SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8 + +$repart $D/zzz --empty=force --dry-run=no --seed=$SEED + +sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' > $D/empty + +cmp $D/empty - <<EOF +label: gpt +label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D +device: $D/zzz +unit: sectors +first-lba: 2048 +last-lba: 2097118 +EOF + +cat >$D/definitions/root.conf <<EOF +[Partition] +Type=root +EOF + +ln -s root.conf $D/definitions/root2.conf + +cat >$D/definitions/home.conf <<EOF +[Partition] +Type=home +EOF + +cat > $D/definitions/swap.conf <<EOF +[Partition] +Type=swap +SizeMaxBytes=64M +PaddingMinBytes=92M +EOF + +$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions + +sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated + +cmp $D/populated - <<EOF +label: gpt +label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D +device: $D/zzz +unit: sectors +first-lba: 2048 +last-lba: 2097118 +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" +EOF + +cat >$D/definitions/swap.conf <<EOF +[Partition] +Type=swap +SizeMaxBytes=64M +EOF + +cat >$D/definitions/extra.conf <<EOF +[Partition] +Type=linux-generic +EOF + +$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions + +sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated2 + +cmp $D/populated2 - <<EOF +label: gpt +label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D +device: $D/zzz +unit: sectors +first-lba: 2048 +last-lba: 2097118 +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" +$D/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic" +EOF + +truncate -s 2G $D/zzz + +$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions + +sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated3 + +cmp $D/populated3 - <<EOF +label: gpt +label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D +device: $D/zzz +unit: sectors +first-lba: 2048 +last-lba: 4194270 +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" +$D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic" +EOF diff --git a/src/path/path.c b/src/path/path.c index 568b5fb04b..5d6afb96f0 100644 --- a/src/path/path.c +++ b/src/path/path.c @@ -18,46 +18,71 @@ static const char *arg_suffix = NULL; static const char* const path_table[_SD_PATH_MAX] = { - [SD_PATH_TEMPORARY] = "temporary", - [SD_PATH_TEMPORARY_LARGE] = "temporary-large", - [SD_PATH_SYSTEM_BINARIES] = "system-binaries", - [SD_PATH_SYSTEM_INCLUDE] = "system-include", - [SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private", - [SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch", - [SD_PATH_SYSTEM_SHARED] = "system-shared", - [SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory", - [SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory", - [SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration", - [SD_PATH_SYSTEM_RUNTIME] = "system-runtime", - [SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs", - [SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private", - [SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs", - [SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache", - [SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool", - [SD_PATH_USER_BINARIES] = "user-binaries", - [SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private", - [SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch", - [SD_PATH_USER_SHARED] = "user-shared", - [SD_PATH_USER_CONFIGURATION] = "user-configuration", - [SD_PATH_USER_RUNTIME] = "user-runtime", - [SD_PATH_USER_STATE_CACHE] = "user-state-cache", - [SD_PATH_USER] = "user", - [SD_PATH_USER_DOCUMENTS] = "user-documents", - [SD_PATH_USER_MUSIC] = "user-music", - [SD_PATH_USER_PICTURES] = "user-pictures", - [SD_PATH_USER_VIDEOS] = "user-videos", - [SD_PATH_USER_DOWNLOAD] = "user-download", - [SD_PATH_USER_PUBLIC] = "user-public", - [SD_PATH_USER_TEMPLATES] = "user-templates", - [SD_PATH_USER_DESKTOP] = "user-desktop", - [SD_PATH_SEARCH_BINARIES] = "search-binaries", - [SD_PATH_SEARCH_BINARIES_DEFAULT] = "search-binaries-default", - [SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private", - [SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch", - [SD_PATH_SEARCH_SHARED] = "search-shared", - [SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory", - [SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory", - [SD_PATH_SEARCH_CONFIGURATION] = "search-configuration", + [SD_PATH_TEMPORARY] = "temporary", + [SD_PATH_TEMPORARY_LARGE] = "temporary-large", + [SD_PATH_SYSTEM_BINARIES] = "system-binaries", + [SD_PATH_SYSTEM_INCLUDE] = "system-include", + [SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private", + [SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch", + [SD_PATH_SYSTEM_SHARED] = "system-shared", + [SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory", + [SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory", + [SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration", + [SD_PATH_SYSTEM_RUNTIME] = "system-runtime", + [SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs", + [SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private", + [SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs", + [SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache", + [SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool", + [SD_PATH_USER_BINARIES] = "user-binaries", + [SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private", + [SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch", + [SD_PATH_USER_SHARED] = "user-shared", + [SD_PATH_USER_CONFIGURATION] = "user-configuration", + [SD_PATH_USER_RUNTIME] = "user-runtime", + [SD_PATH_USER_STATE_CACHE] = "user-state-cache", + [SD_PATH_USER] = "user", + [SD_PATH_USER_DOCUMENTS] = "user-documents", + [SD_PATH_USER_MUSIC] = "user-music", + [SD_PATH_USER_PICTURES] = "user-pictures", + [SD_PATH_USER_VIDEOS] = "user-videos", + [SD_PATH_USER_DOWNLOAD] = "user-download", + [SD_PATH_USER_PUBLIC] = "user-public", + [SD_PATH_USER_TEMPLATES] = "user-templates", + [SD_PATH_USER_DESKTOP] = "user-desktop", + [SD_PATH_SEARCH_BINARIES] = "search-binaries", + [SD_PATH_SEARCH_BINARIES_DEFAULT] = "search-binaries-default", + [SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private", + [SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch", + [SD_PATH_SEARCH_SHARED] = "search-shared", + [SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory", + [SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory", + [SD_PATH_SEARCH_CONFIGURATION] = "search-configuration", + + [SD_PATH_SYSTEMD_UTIL_DIR] = "systemd-util-dir", + [SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR] = "systemd-system-unit-dir", + [SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR] = "systemd-system-preset-dir", + [SD_PATH_SYSTEMD_USER_UNIT_DIR] = "systemd-user-unit-dir", + [SD_PATH_SYSTEMD_USER_PRESET_DIR] = "systemd-user-preset-dir", + [SD_PATH_SYSTEMD_SYSTEM_CONF_DIR] = "systemd-system-conf-dir", + [SD_PATH_SYSTEMD_USER_CONF_DIR] = "systemd-user-conf-dir", + [SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH] = "systemd-system-unit-path", + [SD_PATH_SYSTEMD_USER_UNIT_PATH] = "systemd-user-unit-path", + [SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR] = "systemd-system-generator-dir", + [SD_PATH_SYSTEMD_USER_GENERATOR_DIR] = "systemd-user-generator-dir", + [SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH] = "systemd-system-generator-path", + [SD_PATH_SYSTEMD_USER_GENERATOR_PATH] = "systemd-user-generator-path", + [SD_PATH_SYSTEMD_SLEEP_DIR] = "systemd-sleep-dir", + [SD_PATH_SYSTEMD_SHUTDOWN_DIR] = "systemd-shutdown-dir", + + [SD_PATH_TMPFILES_DIR] = "tmpfiles-dir", + [SD_PATH_SYSUSERS_DIR] = "sysusers-dir", + [SD_PATH_SYSCTL_DIR] = "sysctl-dir", + [SD_PATH_BINFMT_DIR] = "binfmt-dir", + [SD_PATH_MODULES_LOAD_DIR] = "modules-load-dir", + [SD_PATH_CATALOG_DIR] = "catalog-dir", + + [SD_PATH_SYSTEMD_NETWORK_PATH] = "systemd-network-path", }; static int list_homes(void) { @@ -68,12 +93,12 @@ static int list_homes(void) { _cleanup_free_ char *p = NULL; int q; - q = sd_path_home(i, arg_suffix, &p); - if (q == -ENXIO) - continue; + q = sd_path_lookup(i, arg_suffix, &p); if (q < 0) { - log_error_errno(r, "Failed to query %s: %m", path_table[i]); - r = q; + log_full_errno(q == -ENXIO ? LOG_DEBUG : LOG_ERR, + q, "Failed to query %s: %m", path_table[i]); + if (q != -ENXIO) + r = q; continue; } @@ -91,7 +116,7 @@ static int print_home(const char *n) { if (streq(path_table[i], n)) { _cleanup_free_ char *p = NULL; - r = sd_path_home(i, arg_suffix, &p); + r = sd_path_lookup(i, arg_suffix, &p); if (r < 0) return log_error_errno(r, "Failed to query %s: %m", n); @@ -126,7 +151,6 @@ static int help(void) { } static int parse_argv(int argc, char *argv[]) { - enum { ARG_VERSION = 0x100, ARG_SUFFIX, diff --git a/src/portable/portable.c b/src/portable/portable.c index e18826ab26..58e4a6670d 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -1092,10 +1092,9 @@ static int test_chroot_dropin( return log_debug_errno(errno, "Failed to open %s/%s: %m", where, p); } - r = fdopen_unlocked(fd, "r", &f); + r = take_fdopen_unlocked(&fd, "r", &f); if (r < 0) return log_debug_errno(r, "Failed to convert file handle: %m"); - TAKE_FD(fd); r = read_line(f, LONG_LINE_MAX, &line); if (r < 0) diff --git a/src/portable/portabled-image-bus.c b/src/portable/portabled-image-bus.c index 2bd1c495e4..5988a21037 100644 --- a/src/portable/portabled-image-bus.c +++ b/src/portable/portabled-image-bus.c @@ -79,12 +79,10 @@ static int append_fd(sd_bus_message *m, PortableMetadata *d) { assert(d); assert(d->fd >= 0); - f = fdopen(d->fd, "r"); + f = take_fdopen(&d->fd, "r"); if (!f) return -errno; - d->fd = -1; - r = read_full_stream(f, &buf, &n); if (r < 0) return r; diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c index ec9bfd7ad3..5a4f5c58b6 100644 --- a/src/resolve/resolved-dns-dnssec.c +++ b/src/resolve/resolved-dns-dnssec.c @@ -59,55 +59,6 @@ uint16_t dnssec_keytag(DnsResourceRecord *dnskey, bool mask_revoke) { return sum & UINT32_C(0xFFFF); } -int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max) { - size_t c = 0; - int r; - - /* Converts the specified hostname into DNSSEC canonicalized - * form. */ - - if (buffer_max < 2) - return -ENOBUFS; - - for (;;) { - r = dns_label_unescape(&n, buffer, buffer_max, 0); - if (r < 0) - return r; - if (r == 0) - break; - - if (buffer_max < (size_t) r + 2) - return -ENOBUFS; - - /* The DNSSEC canonical form is not clear on what to - * do with dots appearing in labels, the way DNS-SD - * does it. Refuse it for now. */ - - if (memchr(buffer, '.', r)) - return -EINVAL; - - ascii_strlower_n(buffer, (size_t) r); - buffer[r] = '.'; - - buffer += r + 1; - c += r + 1; - - buffer_max -= r + 1; - } - - if (c <= 0) { - /* Not even a single label: this is the root domain name */ - - assert(buffer_max > 2); - buffer[0] = '.'; - buffer[1] = 0; - - return 1; - } - - return (int) c; -} - #if HAVE_GCRYPT static int rr_compare(DnsResourceRecord * const *a, DnsResourceRecord * const *b) { diff --git a/src/resolve/resolved-dns-dnssec.h b/src/resolve/resolved-dns-dnssec.h index dfee7232c0..1f70861cd0 100644 --- a/src/resolve/resolved-dns-dnssec.h +++ b/src/resolve/resolved-dns-dnssec.h @@ -58,8 +58,6 @@ int dnssec_has_rrsig(DnsAnswer *a, const DnsResourceKey *key); uint16_t dnssec_keytag(DnsResourceRecord *dnskey, bool mask_revoke); -int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max); - int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret); typedef enum DnssecNsecResult { diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 05aaa0fb7f..7a80240b97 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -856,14 +856,14 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns /* RFC 2782 states "Unless and until permitted by future standards * action, name compression is not to be used for this field." */ - r = dns_packet_append_name(p, rr->srv.name, false, false, NULL); + r = dns_packet_append_name(p, rr->srv.name, false, true, NULL); break; case DNS_TYPE_PTR: case DNS_TYPE_NS: case DNS_TYPE_CNAME: case DNS_TYPE_DNAME: - r = dns_packet_append_name(p, rr->ptr.name, true, false, NULL); + r = dns_packet_append_name(p, rr->ptr.name, true, true, NULL); break; case DNS_TYPE_HINFO: @@ -906,11 +906,11 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns break; case DNS_TYPE_SOA: - r = dns_packet_append_name(p, rr->soa.mname, true, false, NULL); + r = dns_packet_append_name(p, rr->soa.mname, true, true, NULL); if (r < 0) goto fail; - r = dns_packet_append_name(p, rr->soa.rname, true, false, NULL); + r = dns_packet_append_name(p, rr->soa.rname, true, true, NULL); if (r < 0) goto fail; @@ -938,7 +938,7 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns if (r < 0) goto fail; - r = dns_packet_append_name(p, rr->mx.exchange, true, false, NULL); + r = dns_packet_append_name(p, rr->mx.exchange, true, true, NULL); break; case DNS_TYPE_LOC: diff --git a/src/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c index e6bf20db54..c2839d425a 100644 --- a/src/resolve/resolved-etc-hosts.c +++ b/src/resolve/resolved-etc-hosts.c @@ -37,6 +37,8 @@ void etc_hosts_free(EtcHosts *hosts) { void manager_etc_hosts_flush(Manager *m) { etc_hosts_free(&m->etc_hosts); m->etc_hosts_mtime = USEC_INFINITY; + m->etc_hosts_ino = 0; + m->etc_hosts_dev = 0; } static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) { @@ -224,8 +226,9 @@ static int manager_etc_hosts_read(Manager *m) { return 0; } - /* Did the mtime change? If not, there's no point in re-reading the file. */ - if (timespec_load(&st.st_mtim) == m->etc_hosts_mtime) + /* Did the mtime or ino/dev change? If not, there's no point in re-reading the file. */ + if (timespec_load(&st.st_mtim) == m->etc_hosts_mtime && + st.st_ino == m->etc_hosts_ino && st.st_dev == m->etc_hosts_dev) return 0; } @@ -249,6 +252,8 @@ static int manager_etc_hosts_read(Manager *m) { return r; m->etc_hosts_mtime = timespec_load(&st.st_mtim); + m->etc_hosts_ino = st.st_ino; + m->etc_hosts_dev = st.st_dev; m->etc_hosts_last = ts; return 1; diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 4f72077720..df25907a4c 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -591,6 +591,8 @@ int manager_new(Manager **ret) { .need_builtin_fallbacks = true, .etc_hosts_last = USEC_INFINITY, .etc_hosts_mtime = USEC_INFINITY, + .etc_hosts_ino = 0, + .etc_hosts_dev = 0, .read_etc_hosts = true, }; diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 7f7d3a6b9c..446f258b49 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -127,6 +127,8 @@ struct Manager { /* Data from /etc/hosts */ EtcHosts etc_hosts; usec_t etc_hosts_last, etc_hosts_mtime; + ino_t etc_hosts_ino; + dev_t etc_hosts_dev; bool read_etc_hosts; /* Local DNS stub on 127.0.0.53:53 */ diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c index 7c6346cb66..bdd96aa9a2 100644 --- a/src/resolve/test-dns-packet.c +++ b/src/resolve/test-dns-packet.c @@ -92,7 +92,6 @@ static void test_packet_from_file(const char* filename, bool canonical) { int main(int argc, char **argv) { int i, N; - _cleanup_free_ char *pkts_glob = NULL; _cleanup_globfree_ glob_t g = {}; char **fnames; @@ -102,7 +101,8 @@ int main(int argc, char **argv) { N = argc - 1; fnames = argv + 1; } else { - pkts_glob = path_join(get_testdata_dir(), "test-resolve/*.pkts"); + _cleanup_free_ char *pkts_glob = NULL; + assert_se(get_testdata_dir("test-resolve/*.pkts", &pkts_glob) >= 0); assert_se(glob(pkts_glob, GLOB_NOSORT, NULL, &g) == 0); N = g.gl_pathc; fnames = g.gl_pathv; diff --git a/src/resolve/test-dnssec.c b/src/resolve/test-dnssec.c index 840c4fa1db..213177d4da 100644 --- a/src/resolve/test-dnssec.c +++ b/src/resolve/test-dnssec.c @@ -13,26 +13,6 @@ #include "string-util.h" #include "hexdecoct.h" -static void test_dnssec_canonicalize_one(const char *original, const char *canonical, int r) { - char canonicalized[DNSSEC_CANONICAL_HOSTNAME_MAX]; - - assert_se(dnssec_canonicalize(original, canonicalized, sizeof(canonicalized)) == r); - if (r < 0) - return; - - assert_se(streq(canonicalized, canonical)); -} - -static void test_dnssec_canonicalize(void) { - test_dnssec_canonicalize_one("", ".", 1); - test_dnssec_canonicalize_one(".", ".", 1); - test_dnssec_canonicalize_one("foo", "foo.", 4); - test_dnssec_canonicalize_one("foo.", "foo.", 4); - test_dnssec_canonicalize_one("FOO.", "foo.", 4); - test_dnssec_canonicalize_one("FOO.bar.", "foo.bar.", 8); - test_dnssec_canonicalize_one("FOO..bar.", NULL, -EINVAL); -} - #if HAVE_GCRYPT static void test_dnssec_verify_dns_key(void) { @@ -463,6 +443,136 @@ static void test_dnssec_verify_rrset2(void) { assert_se(result == DNSSEC_VALIDATED); } +static void test_dnssec_verify_rrset3(void) { + + static const uint8_t signature_blob[] = { + 0x41, 0x09, 0x08, 0x67, 0x51, 0x6d, 0x02, 0xf2, 0x17, 0x1e, 0x61, 0x03, 0xc6, 0x80, 0x7a, 0x82, + 0x8f, 0x6c, 0x8c, 0x4c, 0x68, 0x6f, 0x1c, 0xaa, 0x4a, 0xe0, 0x9b, 0x72, 0xdf, 0x7f, 0x15, 0xfa, + 0x2b, 0xc5, 0x63, 0x6f, 0x52, 0xa2, 0x60, 0x59, 0x24, 0xb6, 0xc3, 0x43, 0x3d, 0x47, 0x38, 0xd8, + 0x0c, 0xcc, 0x6c, 0x10, 0x49, 0x92, 0x97, 0x6c, 0x7d, 0x32, 0xc2, 0x62, 0x83, 0x34, 0x96, 0xdf, + 0xbd, 0xf9, 0xcc, 0xcf, 0xd9, 0x4d, 0x8b, 0x8a, 0xa9, 0x3c, 0x1f, 0x89, 0xc4, 0xad, 0xd5, 0xbb, + 0x74, 0xf8, 0xee, 0x60, 0x54, 0x7a, 0xec, 0x36, 0x45, 0xf2, 0xec, 0xb9, 0x73, 0x66, 0xae, 0x57, + 0x2d, 0xd4, 0x91, 0x02, 0x99, 0xcd, 0xba, 0xbd, 0x6e, 0xfb, 0xa6, 0xf6, 0x34, 0xce, 0x4c, 0x44, + 0x0b, 0xd2, 0x66, 0xdb, 0x4e, 0x5e, 0x00, 0x72, 0x1b, 0xe5, 0x2f, 0x24, 0xd2, 0xc8, 0x72, 0x37, + 0x97, 0x2b, 0xd0, 0xcd, 0xa9, 0x6b, 0x84, 0x32, 0x56, 0x7a, 0x89, 0x6e, 0x3d, 0x8f, 0x03, 0x9a, + 0x9d, 0x6d, 0xf7, 0xe5, 0x13, 0xd7, 0x4b, 0xbc, 0xe2, 0x6c, 0xd1, 0x18, 0x60, 0x0e, 0x1a, 0xe3, + 0xf9, 0xc0, 0x34, 0x4b, 0x1c, 0x82, 0x17, 0x5e, 0xdf, 0x81, 0x32, 0xd7, 0x5b, 0x30, 0x1d, 0xe0, + 0x29, 0x80, 0x6b, 0xb1, 0x69, 0xbf, 0x3f, 0x12, 0x56, 0xb0, 0x80, 0x91, 0x22, 0x1a, 0x31, 0xd5, + 0x5d, 0x3d, 0xdd, 0x70, 0x5e, 0xcb, 0xc7, 0x2d, 0xb8, 0x3e, 0x54, 0x34, 0xd3, 0x50, 0x89, 0x77, + 0x08, 0xc1, 0xf7, 0x11, 0x6e, 0x57, 0xd7, 0x09, 0x94, 0x20, 0x03, 0x38, 0xc3, 0x3a, 0xd3, 0x93, + 0x8f, 0xd0, 0x65, 0xc5, 0xa1, 0xe0, 0x69, 0x2c, 0xf6, 0x0a, 0xce, 0x01, 0xb6, 0x0d, 0x95, 0xa0, + 0x5d, 0x97, 0x94, 0xc3, 0xf1, 0xcd, 0x49, 0xea, 0x20, 0xd3, 0xa9, 0xa6, 0x67, 0x94, 0x64, 0x17 + }; + + static const uint8_t dnskey_blob[] = { + 0x03, 0x01, 0x00, 0x01, 0xbf, 0xdd, 0x24, 0x95, 0x21, 0x70, 0xa8, 0x5b, 0x19, 0xa6, 0x76, 0xd3, + 0x5b, 0x37, 0xcf, 0x59, 0x0d, 0x3c, 0xdb, 0x0c, 0xcf, 0xd6, 0x19, 0x02, 0xc7, 0x8e, 0x56, 0x4d, + 0x14, 0xb7, 0x9d, 0x71, 0xf4, 0xdd, 0x24, 0x36, 0xc8, 0x32, 0x1c, 0x63, 0xf7, 0xc0, 0xfc, 0xe3, + 0x83, 0xa6, 0x22, 0x8b, 0x6a, 0x34, 0x41, 0x72, 0xaa, 0x95, 0x98, 0x06, 0xac, 0x03, 0xec, 0xc3, + 0xa1, 0x6d, 0x8b, 0x1b, 0xfd, 0xa4, 0x05, 0x72, 0xe6, 0xe0, 0xb9, 0x98, 0x07, 0x54, 0x7a, 0xb2, + 0x55, 0x30, 0x96, 0xa3, 0x22, 0x3b, 0xe0, 0x9d, 0x61, 0xf6, 0xdc, 0x31, 0x2b, 0xc9, 0x2c, 0x12, + 0x06, 0x7f, 0x3c, 0x5d, 0x29, 0x76, 0x01, 0x62, 0xe3, 0x41, 0x41, 0x4f, 0xa6, 0x07, 0xfa, 0x2d, + 0x0c, 0x64, 0x88, 0xd1, 0x56, 0x18, 0x4b, 0x2b, 0xc2, 0x19, 0x7e, 0xd0, 0x1a, 0x8c, 0x2d, 0x8d, + 0x06, 0xdf, 0x4d, 0xaf, 0xd9, 0xe3, 0x31, 0x59, 0xbc, 0xc3, 0x36, 0x22, 0xe7, 0x15, 0xf9, 0xb2, + 0x44, 0x8a, 0x33, 0xd7, 0x6c, 0xf1, 0xcc, 0x37, 0x05, 0x69, 0x32, 0x71, 0x76, 0xd8, 0x50, 0x06, + 0xae, 0x27, 0xed, 0x3b, 0xdb, 0x1a, 0x97, 0x9b, 0xa3, 0x3e, 0x40, 0x42, 0x29, 0xaf, 0x75, 0x1c, + 0xff, 0x1d, 0xaf, 0x85, 0x02, 0xb3, 0x2e, 0x99, 0x67, 0x08, 0x13, 0xd5, 0xda, 0x6d, 0x65, 0xb2, + 0x36, 0x6f, 0x2f, 0x64, 0xe0, 0xfa, 0xd3, 0x81, 0x86, 0x6b, 0x41, 0x3e, 0x91, 0xaa, 0x0a, 0xd3, + 0xb2, 0x92, 0xd9, 0x42, 0x36, 0x8a, 0x11, 0x0b, 0x5b, 0xb0, 0xea, 0xad, 0x76, 0xd5, 0xb4, 0x81, + 0x30, 0xca, 0x5c, 0x4f, 0xd9, 0xea, 0xe7, 0x4b, 0x10, 0x0a, 0x09, 0x4b, 0x73, 0x66, 0xed, 0x8e, + 0x84, 0xa2, 0x4f, 0x93, 0x7e, 0x29, 0xdc, 0x6a, 0xbd, 0x12, 0xa1, 0x3d, 0xd2, 0xd6, 0x2a, 0x67, + 0x99, 0x4d, 0xf3, 0x43 + }; + + _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *mx1 = NULL, *mx2 = NULL, *mx3 = NULL, *mx4 = NULL, *rrsig = NULL, *dnskey = NULL; + _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; + DnssecResult result; + + mx1 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se"); + assert_se(mx1); + + mx1->mx.priority = 1; + mx1->mx.exchange = strdup("ASPMX.L.GOOGLE.COM"); + assert_se(mx1->mx.exchange); + + log_info("MX: %s", strna(dns_resource_record_to_string(mx1))); + + mx2 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se"); + assert_se(mx2); + + mx2->mx.priority = 5; + mx2->mx.exchange = strdup("ALT2.ASPMX.L.GOOGLE.COM"); + assert_se(mx2->mx.exchange); + + log_info("MX: %s", strna(dns_resource_record_to_string(mx2))); + + mx3 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se"); + assert_se(mx3); + + mx3->mx.priority = 10; + mx3->mx.exchange = strdup("ASPMX2.GOOGLEMAIL.COM"); + assert_se(mx3->mx.exchange); + + log_info("MX: %s", strna(dns_resource_record_to_string(mx3))); + + mx4 = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_MX, "kodapan.se"); + assert_se(mx4); + + mx4->mx.priority = 10; + mx4->mx.exchange = strdup("ASPMX3.GOOGLEMAIL.COM"); + assert_se(mx4->mx.exchange); + + log_info("MX: %s", strna(dns_resource_record_to_string(mx4))); + + rrsig = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_RRSIG, "kodapan.se"); + assert_se(rrsig); + + rrsig->rrsig.type_covered = DNS_TYPE_MX; + rrsig->rrsig.algorithm = DNSSEC_ALGORITHM_RSASHA256; + rrsig->rrsig.labels = 2; + rrsig->rrsig.original_ttl = 900; + rrsig->rrsig.expiration = 0x5e608a84; + rrsig->rrsig.inception = 0x5e4e1584; + rrsig->rrsig.key_tag = 44028; + rrsig->rrsig.signer = strdup("kodapan.se."); + assert_se(rrsig->rrsig.signer); + rrsig->rrsig.signature_size = sizeof(signature_blob); + rrsig->rrsig.signature = memdup(signature_blob, rrsig->rrsig.signature_size); + assert_se(rrsig->rrsig.signature); + + log_info("RRSIG: %s", strna(dns_resource_record_to_string(rrsig))); + + dnskey = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNSKEY, "kodapan.se"); + assert_se(dnskey); + + dnskey->dnskey.flags = 256; + dnskey->dnskey.protocol = 3; + dnskey->dnskey.algorithm = DNSSEC_ALGORITHM_RSASHA256; + dnskey->dnskey.key_size = sizeof(dnskey_blob); + dnskey->dnskey.key = memdup(dnskey_blob, sizeof(dnskey_blob)); + assert_se(dnskey->dnskey.key); + + log_info("DNSKEY: %s", strna(dns_resource_record_to_string(dnskey))); + log_info("DNSKEY keytag: %u", dnssec_keytag(dnskey, false)); + + assert_se(dnssec_key_match_rrsig(mx1->key, rrsig) > 0); + assert_se(dnssec_key_match_rrsig(mx2->key, rrsig) > 0); + assert_se(dnssec_key_match_rrsig(mx3->key, rrsig) > 0); + assert_se(dnssec_key_match_rrsig(mx4->key, rrsig) > 0); + assert_se(dnssec_rrsig_match_dnskey(rrsig, dnskey, false) > 0); + + answer = dns_answer_new(4); + assert_se(answer); + assert_se(dns_answer_add(answer, mx1, 0, DNS_ANSWER_AUTHENTICATED) >= 0); + assert_se(dns_answer_add(answer, mx2, 0, DNS_ANSWER_AUTHENTICATED) >= 0); + assert_se(dns_answer_add(answer, mx3, 0, DNS_ANSWER_AUTHENTICATED) >= 0); + assert_se(dns_answer_add(answer, mx4, 0, DNS_ANSWER_AUTHENTICATED) >= 0); + + /* Validate the RR as it if was 2020-02-24 today */ + assert_se(dnssec_verify_rrset(answer, mx1->key, rrsig, dnskey, 1582534685*USEC_PER_SEC, &result) >= 0); + assert_se(result == DNSSEC_VALIDATED); +} + static void test_dnssec_nsec3_hash(void) { static const uint8_t salt[] = { 0xB0, 0x1D, 0xFA, 0xCE }; static const uint8_t next_hashed_name[] = { 0x84, 0x10, 0x26, 0x53, 0xc9, 0xfa, 0x4d, 0x85, 0x6c, 0x97, 0x82, 0xe2, 0x8f, 0xdf, 0x2d, 0x5e, 0x87, 0x69, 0xc4, 0x52 }; @@ -499,14 +609,13 @@ static void test_dnssec_nsec3_hash(void) { int main(int argc, char *argv[]) { - test_dnssec_canonicalize(); - #if HAVE_GCRYPT test_dnssec_verify_dns_key(); test_dnssec_verify_rfc8080_ed25519_example1(); test_dnssec_verify_rfc8080_ed25519_example2(); test_dnssec_verify_rrset(); test_dnssec_verify_rrset2(); + test_dnssec_verify_rrset3(); test_dnssec_nsec3_hash(); #endif diff --git a/src/run/run.c b/src/run/run.c index 2b806fb6ac..6076eabe92 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -41,6 +41,7 @@ static bool arg_wait = false; static const char *arg_unit = NULL; static const char *arg_description = NULL; static const char *arg_slice = NULL; +static bool arg_slice_inherit = false; static bool arg_send_sighup = false; static BusTransport arg_transport = BUS_TRANSPORT_LOCAL; static const char *arg_host = NULL; @@ -97,6 +98,7 @@ static int help(void) { " -p --property=NAME=VALUE Set service or scope unit property\n" " --description=TEXT Description for unit\n" " --slice=SLICE Run in the specified slice\n" + " --slice-inherit Inherit the slice\n" " --no-block Do not wait until operation finished\n" " -r --remain-after-exit Leave service around until explicitly stopped\n" " --wait Wait until service stopped again\n" @@ -162,6 +164,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_SCOPE, ARG_DESCRIPTION, ARG_SLICE, + ARG_SLICE_INHERIT, ARG_SEND_SIGHUP, ARG_SERVICE_TYPE, ARG_EXEC_USER, @@ -194,6 +197,7 @@ static int parse_argv(int argc, char *argv[]) { { "unit", required_argument, NULL, 'u' }, { "description", required_argument, NULL, ARG_DESCRIPTION }, { "slice", required_argument, NULL, ARG_SLICE }, + { "slice-inherit", no_argument, NULL, ARG_SLICE_INHERIT }, { "remain-after-exit", no_argument, NULL, 'r' }, { "send-sighup", no_argument, NULL, ARG_SEND_SIGHUP }, { "host", required_argument, NULL, 'H' }, @@ -273,6 +277,10 @@ static int parse_argv(int argc, char *argv[]) { arg_slice = optarg; break; + case ARG_SLICE_INHERIT: + arg_slice_inherit = true; + break; + case ARG_SEND_SIGHUP: arg_send_sighup = true; break; @@ -637,23 +645,50 @@ static int transient_unit_set_properties(sd_bus_message *m, UnitType t, char **p } static int transient_cgroup_set_properties(sd_bus_message *m) { + _cleanup_free_ char *name = NULL; + _cleanup_free_ char *slice = NULL; int r; assert(m); - if (!isempty(arg_slice)) { - _cleanup_free_ char *slice = NULL; + if (arg_slice_inherit) { + char *end; - r = unit_name_mangle_with_suffix(arg_slice, "as slice", - arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, - ".slice", &slice); + if (arg_user) + r = cg_pid_get_user_slice(0, &name); + else + r = cg_pid_get_slice(0, &name); if (r < 0) - return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice); + return log_error_errno(r, "Failed to get PID slice: %m"); - r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); - if (r < 0) - return bus_log_create_error(r); + end = endswith(name, ".slice"); + if (!end) + return -ENXIO; + *end = 0; } + if (!isempty(arg_slice)) { + if (name) { + char *j = strjoin(name, "-", arg_slice); + free_and_replace(name, j); + } else + name = strdup(arg_slice); + if (!name) + return log_oom(); + } + + if (!name) + return 0; + + r = unit_name_mangle_with_suffix(name, "as slice", + arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN, + ".slice", &slice); + if (r < 0) + return log_error_errno(r, "Failed to mangle name '%s': %m", arg_slice); + + r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice); + if (r < 0) + return bus_log_create_error(r); + return 0; } diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 0fc5501e62..b64663bd1e 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -791,14 +791,12 @@ int ask_password_agent( (void) fchmod(fd, 0644); - f = fdopen(fd, "w"); + f = take_fdopen(&fd, "w"); if (!f) { r = -errno; goto finish; } - fd = -1; - signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); if (signal_fd < 0) { r = -errno; diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index a30876c1a1..463a0ddb71 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -8,6 +8,7 @@ #include "cgroup-setup.h" #include "cgroup-util.h" #include "condition.h" +#include "coredump-util.h" #include "cpu-set-util.h" #include "escape.h" #include "exec-util.h" @@ -119,6 +120,7 @@ DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64); DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode); DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou); DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64); +DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, coredump_filter_mask_from_string); static int bus_append_string(sd_bus_message *m, const char *field, const char *eq) { int r; @@ -898,6 +900,9 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con "OOMScoreAdjust")) return bus_append_safe_atoi(m, field, eq); + if (streq(field, "CoredumpFilter")) + return bus_append_coredump_filter_mask_from_string(m, field, eq); + if (streq(field, "Nice")) return bus_append_parse_nice(m, field, eq); diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 4b0a3a3e31..d107a06ce3 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -21,6 +21,7 @@ #include "bus-util.h" #include "cap-list.h" #include "cgroup-util.h" +#include "escape.h" #include "mountpoint-util.h" #include "nsflags.h" #include "parse-util.h" @@ -373,6 +374,12 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b (void) format_timespan(timespan, sizeof(timespan), u, 0); bus_print_property_value(name, expected_value, value, timespan); + } else if (streq(name, "CoredumpFilter")) { + char buf[STRLEN("0xFFFFFFFF")]; + + xsprintf(buf, "0x%"PRIx64, u); + bus_print_property_value(name, expected_value, value, buf); + } else if (streq(name, "RestrictNamespaces")) { _cleanup_free_ char *s = NULL; const char *result; @@ -500,18 +507,20 @@ static int bus_print_property(const char *name, const char *expected_value, sd_b return r; while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) { - bool good; + _cleanup_free_ char *e = NULL; - if (first && !value) - printf("%s=", name); + e = shell_maybe_quote(str, ESCAPE_BACKSLASH_ONELINE); + if (!e) + return -ENOMEM; - /* This property has multiple space-separated values, so - * neither spaces nor newlines can be allowed in a value. */ - good = str[strcspn(str, " \n")] == '\0'; + if (first) { + if (!value) + printf("%s=", name); + first = false; + } else + fputs(" ", stdout); - printf("%s%s", first ? "" : " ", good ? str : "[unprintable]"); - - first = false; + fputs(e, stdout); } if (r < 0) return r; @@ -1390,3 +1399,142 @@ const struct hash_ops bus_message_hash_ops = { .compare = trivial_compare_func, .free_value = bus_message_unref_wrapper, }; + +/* Shorthand flavors of the sd-bus convenience helpers with destination,path,interface + * strings encapsulated within a single struct. + */ +int bus_call_method_async( + sd_bus *bus, + sd_bus_slot **slot, + const BusAddress *address, + const char *member, + sd_bus_message_handler_t callback, + void *userdata, + const char *types, ...) { + + va_list ap; + int r; + + assert(address); + + va_start(ap, types); + r = sd_bus_call_method_asyncv(bus, slot, address->destination, address->path, address->interface, member, callback, userdata, types, ap); + va_end(ap); + + return r; +} + +int bus_call_method( + sd_bus *bus, + const BusAddress *address, + const char *member, + sd_bus_error *error, + sd_bus_message **reply, + const char *types, ...) { + + va_list ap; + int r; + + assert(address); + + va_start(ap, types); + r = sd_bus_call_methodv(bus, address->destination, address->path, address->interface, member, error, reply, types, ap); + va_end(ap); + + return r; +} + +int bus_get_property( + sd_bus *bus, + const BusAddress *address, + const char *member, + sd_bus_error *error, + sd_bus_message **reply, + const char *type) { + + assert(address); + + return sd_bus_get_property(bus, address->destination, address->path, address->interface, member, error, reply, type); +} + +int bus_get_property_trivial( + sd_bus *bus, + const BusAddress *address, + const char *member, + sd_bus_error *error, + char type, void *ptr) { + + assert(address); + + return sd_bus_get_property_trivial(bus, address->destination, address->path, address->interface, member, error, type, ptr); +} + +int bus_get_property_string( + sd_bus *bus, + const BusAddress *address, + const char *member, + sd_bus_error *error, + char **ret) { + + assert(address); + + return sd_bus_get_property_string(bus, address->destination, address->path, address->interface, member, error, ret); +} + +int bus_get_property_strv( + sd_bus *bus, + const BusAddress *address, + const char *member, + sd_bus_error *error, + char ***ret) { + + assert(address); + + return sd_bus_get_property_strv(bus, address->destination, address->path, address->interface, member, error, ret); +} + +int bus_set_property( + sd_bus *bus, + const BusAddress *address, + const char *member, + sd_bus_error *error, + const char *type, ...) { + + va_list ap; + int r; + + assert(address); + + va_start(ap, type); + r = sd_bus_set_propertyv(bus, address->destination, address->path, address->interface, member, error, type, ap); + va_end(ap); + + return r; +} + +int bus_match_signal( + sd_bus *bus, + sd_bus_slot **ret, + const BusAddress *address, + const char *member, + sd_bus_message_handler_t callback, + void *userdata) { + + assert(address); + + return sd_bus_match_signal(bus, ret, address->destination, address->path, address->interface, member, callback, userdata); +} + +int bus_match_signal_async( + sd_bus *bus, + sd_bus_slot **ret, + const BusAddress *address, + const char *member, + sd_bus_message_handler_t callback, + sd_bus_message_handler_t install_callback, + void *userdata) { + + assert(address); + + return sd_bus_match_signal_async(bus, ret, address->destination, address->path, address->interface, member, callback, install_callback, userdata); +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index db245a791e..f3bdde41ae 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -22,6 +22,12 @@ typedef enum BusTransport { _BUS_TRANSPORT_INVALID = -1 } BusTransport; +typedef struct BusAddress { + const char *destination; + const char *path; + const char *interface; +} BusAddress; + typedef int (*bus_property_set_t) (sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata); struct bus_properties_map { @@ -179,3 +185,16 @@ static inline int bus_open_system_watch_bind(sd_bus **ret) { int bus_reply_pair_array(sd_bus_message *m, char **l); extern const struct hash_ops bus_message_hash_ops; + +/* Shorthand flavors of the sd-bus convenience helpers with destination,path,interface + * strings encapsulated within a single struct. + */ +int bus_call_method_async(sd_bus *bus, sd_bus_slot **slot, const BusAddress *address, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...); +int bus_call_method(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *types, ...); +int bus_get_property(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *type); +int bus_get_property_trivial(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, char type, void *ptr); +int bus_get_property_string(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, char **ret); +int bus_get_property_strv(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, char ***ret); +int bus_set_property(sd_bus *bus, const BusAddress *address, const char *member, sd_bus_error *error, const char *type, ...); +int bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const BusAddress *address, const char *member, sd_bus_message_handler_t callback, void *userdata); +int bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const BusAddress *address, const char *member, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata); diff --git a/src/shared/coredump-util.c b/src/shared/coredump-util.c new file mode 100644 index 0000000000..67897414bc --- /dev/null +++ b/src/shared/coredump-util.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "coredump-util.h" +#include "extract-word.h" +#include "fileio.h" +#include "string-table.h" + +static const char *const coredump_filter_table[_COREDUMP_FILTER_MAX] = { + [COREDUMP_FILTER_PRIVATE_ANONYMOUS] = "private-anonymous", + [COREDUMP_FILTER_SHARED_ANONYMOUS] = "shared-anonymous", + [COREDUMP_FILTER_PRIVATE_FILE_BACKED] = "private-file-backed", + [COREDUMP_FILTER_SHARED_FILE_BACKED] = "shared-file-backed", + [COREDUMP_FILTER_ELF_HEADERS] = "elf-headers", + [COREDUMP_FILTER_PRIVATE_HUGE] = "private-huge", + [COREDUMP_FILTER_SHARED_HUGE] = "shared-huge", + [COREDUMP_FILTER_PRIVATE_DAX] = "private-dax", + [COREDUMP_FILTER_SHARED_DAX] = "shared-dax", +}; + +DEFINE_STRING_TABLE_LOOKUP(coredump_filter, CoredumpFilter); + +int coredump_filter_mask_from_string(const char *s, uint64_t *ret) { + uint64_t m = 0; + + assert(s); + assert(ret); + + for (;;) { + _cleanup_free_ char *n = NULL; + CoredumpFilter v; + int r; + + r = extract_first_word(&s, &n, NULL, 0); + if (r < 0) + return r; + if (r == 0) + break; + + if (streq(n, "default")) { + m |= COREDUMP_FILTER_MASK_DEFAULT; + continue; + } + + if (streq(n, "all")) { + m = UINT64_MAX; + continue; + } + + v = coredump_filter_from_string(n); + if (v >= 0) { + m |= 1u << v; + continue; + } + + uint64_t x; + r = safe_atoux64(n, &x); + if (r < 0) + return r; + + m |= x; + } + + *ret = m; + return 0; +} + +int set_coredump_filter(uint64_t value) { + char t[STRLEN("0xFFFFFFFF")]; + + sprintf(t, "0x%"PRIx64, value); + + return write_string_file("/proc/self/coredump_filter", t, + WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER); +} diff --git a/src/shared/coredump-util.h b/src/shared/coredump-util.h new file mode 100644 index 0000000000..ff2e511bf1 --- /dev/null +++ b/src/shared/coredump-util.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "macro.h" + +typedef enum CoredumpFilter { + COREDUMP_FILTER_PRIVATE_ANONYMOUS = 0, + COREDUMP_FILTER_SHARED_ANONYMOUS, + COREDUMP_FILTER_PRIVATE_FILE_BACKED, + COREDUMP_FILTER_SHARED_FILE_BACKED, + COREDUMP_FILTER_ELF_HEADERS, + COREDUMP_FILTER_PRIVATE_HUGE, + COREDUMP_FILTER_SHARED_HUGE, + COREDUMP_FILTER_PRIVATE_DAX, + COREDUMP_FILTER_SHARED_DAX, + _COREDUMP_FILTER_MAX, + _COREDUMP_FILTER_INVALID = -1, +} CoredumpFilter; + +#define COREDUMP_FILTER_MASK_DEFAULT (1u << COREDUMP_FILTER_PRIVATE_ANONYMOUS | \ + 1u << COREDUMP_FILTER_SHARED_ANONYMOUS | \ + 1u << COREDUMP_FILTER_ELF_HEADERS | \ + 1u << COREDUMP_FILTER_PRIVATE_HUGE) + +const char* coredump_filter_to_string(CoredumpFilter i) _const_; +CoredumpFilter coredump_filter_from_string(const char *s) _pure_; +int coredump_filter_mask_from_string(const char *s, uint64_t *ret); + +int set_coredump_filter(uint64_t value); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 1ef69fdf4c..23ad6b06cf 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1188,6 +1188,8 @@ static int decrypt_partition( if (r < 0) return log_debug_errno(r, "Failed to initialize dm-crypt: %m"); + crypt_set_log_callback(cd, cryptsetup_log_glue, NULL); + r = crypt_load(cd, CRYPT_LUKS, NULL); if (r < 0) return log_debug_errno(r, "Failed to load LUKS metadata: %m"); @@ -1246,6 +1248,8 @@ static int verity_partition( if (r < 0) return r; + crypt_set_log_callback(cd, cryptsetup_log_glue, NULL); + r = crypt_load(cd, CRYPT_VERITY, NULL); if (r < 0) return r; @@ -1541,14 +1545,12 @@ int dissected_image_acquire_metadata(DissectedImage *m) { fds[2*k+1] = safe_close(fds[2*k+1]); - f = fdopen(fds[2*k], "r"); + f = take_fdopen(&fds[2*k], "r"); if (!f) { r = -errno; goto finish; } - fds[2*k] = -1; - switch (k) { case META_HOSTNAME: diff --git a/src/shared/install.c b/src/shared/install.c index 48cb6aca7e..0f18b6bee5 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1280,10 +1280,9 @@ static int unit_file_load( if (r < 0) return r; - f = fdopen(fd, "r"); + f = take_fdopen(&fd, "r"); if (!f) return -errno; - fd = -1; /* c is only needed if we actually load the file (it's referenced from items[] btw, in case you wonder.) */ assert(c); diff --git a/src/shared/meson.build b/src/shared/meson.build index 859c0bbfde..d1832a1f53 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -51,6 +51,8 @@ shared_sources = files(''' condition.h conf-parser.c conf-parser.h + coredump-util.c + coredump-util.h cpu-set-util.c cpu-set-util.h crypt-util.c @@ -160,8 +162,6 @@ shared_sources = files(''' output-mode.h pager.c pager.h - path-lookup.c - path-lookup.h pe-header.h pkcs11-util.c pkcs11-util.h diff --git a/src/shared/os-util.c b/src/shared/os-util.c index b2af8535f9..eacebc1ea5 100644 --- a/src/shared/os-util.c +++ b/src/shared/os-util.c @@ -3,6 +3,7 @@ #include "alloc-util.h" #include "env-file.h" #include "fd-util.h" +#include "fileio.h" #include "fs-util.h" #include "macro.h" #include "os-util.h" @@ -76,10 +77,9 @@ int fopen_os_release(const char *root, char **ret_path, FILE **ret_file) { if (r < 0) return r; - f = fdopen(fd, "r"); + f = take_fdopen(&fd, "r"); if (!f) return -errno; - fd = -1; *ret_file = f; diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index e63ef0f261..6dbdff7b28 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -223,7 +223,7 @@ static int calculate_swap_file_offset(const SwapEntry *swap, uint64_t *ret_offse fd = open(swap->device, O_RDONLY|O_CLOEXEC|O_NOCTTY); if (fd < 0) - return log_error_errno(errno, "Failed to open %s: %m", swap->device); + return log_error_errno(errno, "Failed to open swap file %s to determine on-disk offset: %m", swap->device); if (fstat(fd, &sb) < 0) return log_error_errno(errno, "Failed to stat %s: %m", swap->device); diff --git a/src/shared/tests.c b/src/shared/tests.c index 96b5b805a9..764e4656bb 100644 --- a/src/shared/tests.c +++ b/src/shared/tests.c @@ -58,21 +58,25 @@ static void load_testdata_env(void) { setenv(*k, *v, 0); } -const char* get_testdata_dir(void) { - const char *env; +int get_testdata_dir(const char *suffix, char **ret) { + const char *dir; + char *p; load_testdata_env(); /* if the env var is set, use that */ - env = getenv("SYSTEMD_TEST_DATA"); - if (!env) - env = SYSTEMD_TEST_DATA; - if (access(env, F_OK) < 0) { - fprintf(stderr, "ERROR: $SYSTEMD_TEST_DATA directory [%s] does not exist\n", env); - exit(EXIT_FAILURE); - } + dir = getenv("SYSTEMD_TEST_DATA"); + if (!dir) + dir = SYSTEMD_TEST_DATA; + if (access(dir, F_OK) < 0) + return log_error_errno(errno, "ERROR: $SYSTEMD_TEST_DATA directory [%s] not accesible: %m", dir); - return env; + p = path_join(dir, suffix); + if (!p) + return log_oom(); + + *ret = p; + return 0; } const char* get_catalog_dir(void) { diff --git a/src/shared/tests.h b/src/shared/tests.h index 5a6fd53f36..6817ef4860 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -20,7 +20,7 @@ static inline bool manager_errno_skip_test(int r) { char* setup_fake_runtime_dir(void); int enter_cgroup_subroot(char **ret_cgroup); -const char* get_testdata_dir(void); +int get_testdata_dir(const char *suffix, char **ret); const char* get_catalog_dir(void); bool slow_tests_enabled(void); void test_setup_logging(int level); diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index 918cf20bd0..f2ad23d055 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -51,6 +51,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_LOG_TARGET, ARG_LOG_COLOR, ARG_LOG_LOCATION, + ARG_LOG_TIME, ARG_EXIT_CODE, ARG_TIMEOUT, }; @@ -60,6 +61,7 @@ static int parse_argv(int argc, char *argv[]) { { "log-target", required_argument, NULL, ARG_LOG_TARGET }, { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, + { "log-time", optional_argument, NULL, ARG_LOG_TIME }, { "exit-code", required_argument, NULL, ARG_EXIT_CODE }, { "timeout", required_argument, NULL, ARG_TIMEOUT }, {} @@ -110,6 +112,17 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_LOG_TIME: + + if (optarg) { + r = log_show_time_from_string(optarg); + if (r < 0) + log_error_errno(r, "Failed to parse log time setting %s, ignoring: %m", optarg); + } else + log_show_time(true); + + break; + case ARG_EXIT_CODE: r = safe_atou8(optarg, &arg_exit_code); if (r < 0) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 58b0fd3688..dcd93fce17 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7966,6 +7966,7 @@ static int systemctl_help(void) { " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n" " --failed Shorcut for --state=failed\n" " -p --property=NAME Show only properties by this name\n" + " -P NAME Equivalent to --value --property=NAME\n" " -a --all Show all properties/all units currently in memory,\n" " including dead/empty ones. To list all units installed\n" " on the system, use 'list-unit-files' instead.\n" @@ -8334,7 +8335,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */ arg_ask_password = true; - while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:iTr.::", options, NULL)) >= 0) + while ((c = getopt_long(argc, argv, "ht:p:P:alqfs:H:M:n:o:iTr.::", options, NULL)) >= 0) switch (c) { @@ -8389,6 +8390,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; } + case 'P': + arg_value = true; + _fallthrough_; + case 'p': /* Make sure that if the empty property list was specified, we won't show any properties. */ @@ -8413,9 +8418,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) { } } - /* If the user asked for a particular - * property, show it to him, even if it is - * empty. */ + /* If the user asked for a particular property, show it, even if it is empty. */ arg_all = true; break; diff --git a/src/systemd/meson.build b/src/systemd/meson.build index 05196554ac..63d0829b67 100644 --- a/src/systemd/meson.build +++ b/src/systemd/meson.build @@ -12,6 +12,7 @@ _systemd_headers = ''' sd-journal.h sd-login.h sd-messages.h + sd-path.h '''.split() # https://github.com/mesonbuild/meson/issues/1633 @@ -30,7 +31,6 @@ _not_installed_headers = ''' sd-ndisc.h sd-netlink.h sd-network.h - sd-path.h sd-radv.h sd-resolve.h sd-utf8.h diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index aed214352b..cd307dbd56 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -55,7 +55,7 @@ typedef struct { } sd_bus_error; typedef struct { - const char* name; + const char *name; int code; } sd_bus_error_map; @@ -180,10 +180,10 @@ int sd_bus_start(sd_bus *bus); int sd_bus_try_close(sd_bus *bus) _sd_deprecated_; /* deprecated */ void sd_bus_close(sd_bus *bus); -sd_bus *sd_bus_ref(sd_bus *bus); -sd_bus *sd_bus_unref(sd_bus *bus); -sd_bus *sd_bus_close_unref(sd_bus *bus); -sd_bus *sd_bus_flush_close_unref(sd_bus *bus); +sd_bus* sd_bus_ref(sd_bus *bus); +sd_bus* sd_bus_unref(sd_bus *bus); +sd_bus* sd_bus_close_unref(sd_bus *bus); +sd_bus* sd_bus_flush_close_unref(sd_bus *bus); void sd_bus_default_flush_close(void); @@ -204,7 +204,7 @@ int sd_bus_get_fd(sd_bus *bus); int sd_bus_get_events(sd_bus *bus); int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec); int sd_bus_process(sd_bus *bus, sd_bus_message **r); -int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r); +int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r) _sd_deprecated_; /* deprecated */ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec); int sd_bus_flush(sd_bus *bus); int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m); @@ -216,7 +216,7 @@ void* sd_bus_get_current_userdata(sd_bus *bus); int sd_bus_attach_event(sd_bus *bus, sd_event *e, int priority); int sd_bus_detach_event(sd_bus *bus); -sd_event *sd_bus_get_event(sd_bus *bus); +sd_event* sd_bus_get_event(sd_bus *bus); int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret); int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret); @@ -240,8 +240,8 @@ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot); sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot); sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot); -void *sd_bus_slot_get_userdata(sd_bus_slot *slot); -void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata); +void* sd_bus_slot_get_userdata(sd_bus_slot *slot); +void* sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata); int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description); int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description); int sd_bus_slot_get_floating(sd_bus_slot *slot); @@ -251,7 +251,7 @@ int sd_bus_slot_get_destroy_callback(sd_bus_slot *s, sd_bus_destroy_t *callback) sd_bus_message* sd_bus_slot_get_current_message(sd_bus_slot *slot); sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot); -void *sd_bus_slot_get_current_userdata(sd_bus_slot *slot); +void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot); /* Message object */ @@ -272,27 +272,27 @@ int sd_bus_message_seal(sd_bus_message *m, uint64_t cookie, uint64_t timeout_use int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type); int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie); int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie); -int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority); +int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) _sd_deprecated_; /* deprecated */ int sd_bus_message_get_expect_reply(sd_bus_message *m); int sd_bus_message_get_auto_start(sd_bus_message *m); int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m); -const char *sd_bus_message_get_signature(sd_bus_message *m, int complete); -const char *sd_bus_message_get_path(sd_bus_message *m); -const char *sd_bus_message_get_interface(sd_bus_message *m); -const char *sd_bus_message_get_member(sd_bus_message *m); -const char *sd_bus_message_get_destination(sd_bus_message *m); -const char *sd_bus_message_get_sender(sd_bus_message *m); -const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m); +const char* sd_bus_message_get_signature(sd_bus_message *m, int complete); +const char* sd_bus_message_get_path(sd_bus_message *m); +const char* sd_bus_message_get_interface(sd_bus_message *m); +const char* sd_bus_message_get_member(sd_bus_message *m); +const char* sd_bus_message_get_destination(sd_bus_message *m); +const char* sd_bus_message_get_sender(sd_bus_message *m); +const sd_bus_error* sd_bus_message_get_error(sd_bus_message *m); int sd_bus_message_get_errno(sd_bus_message *m); int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec); int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec); -int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t* seqnum); +int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum); sd_bus* sd_bus_message_get_bus(sd_bus_message *m); -sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m); /* do not unref the result */ +sd_bus_creds* sd_bus_message_get_creds(sd_bus_message *m); /* do not unref the result */ int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member); int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member); @@ -306,7 +306,7 @@ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) int sd_bus_message_set_destination(sd_bus_message *m, const char *destination); int sd_bus_message_set_sender(sd_bus_message *m, const char *sender); -int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority); +int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) _sd_deprecated_; /* deprecated */ int sd_bus_message_append(sd_bus_message *m, const char *types, ...); int sd_bus_message_appendv(sd_bus_message *m, const char *types, va_list ap); @@ -352,20 +352,27 @@ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machin /* Convenience calls */ +int sd_bus_call_methodv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, va_list ap); int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...); +int sd_bus_call_method_asyncv(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, va_list ap); int sd_bus_call_method_async(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...); int sd_bus_get_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *type); int sd_bus_get_property_trivial(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char type, void *ret_ptr); int sd_bus_get_property_string(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char **ret); /* free the result! */ int sd_bus_get_property_strv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char ***ret); /* free the result! */ +int sd_bus_set_propertyv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, const char *type, va_list ap); int sd_bus_set_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, const char *type, ...); +int sd_bus_reply_method_returnv(sd_bus_message *call, const char *types, va_list ap); int sd_bus_reply_method_return(sd_bus_message *call, const char *types, ...); int sd_bus_reply_method_error(sd_bus_message *call, const sd_bus_error *e); +int sd_bus_reply_method_errorfv(sd_bus_message *call, const char *name, const char *format, va_list ap) _sd_printf_(3, 0); int sd_bus_reply_method_errorf(sd_bus_message *call, const char *name, const char *format, ...) _sd_printf_(3, 4); int sd_bus_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *e); +int sd_bus_reply_method_errnofv(sd_bus_message *call, int error, const char *format, va_list ap) _sd_printf_(3, 0); int sd_bus_reply_method_errnof(sd_bus_message *call, int error, const char *format, ...) _sd_printf_(3, 4); +int sd_bus_emit_signalv(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, va_list ap); int sd_bus_emit_signal(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, ...); int sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, const char *interface, char **names); @@ -387,8 +394,8 @@ int sd_bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const char *sender /* Credential handling */ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t creds_mask); -sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c); -sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c); +sd_bus_creds* sd_bus_creds_ref(sd_bus_creds *c); +sd_bus_creds* sd_bus_creds_unref(sd_bus_creds *c); uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c); uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c); @@ -486,8 +493,8 @@ sd_bus_track* sd_bus_track_ref(sd_bus_track *track); sd_bus_track* sd_bus_track_unref(sd_bus_track *track); sd_bus* sd_bus_track_get_bus(sd_bus_track *track); -void *sd_bus_track_get_userdata(sd_bus_track *track); -void *sd_bus_track_set_userdata(sd_bus_track *track, void *userdata); +void* sd_bus_track_get_userdata(sd_bus_track *track); +void* sd_bus_track_set_userdata(sd_bus_track *track, void *userdata); int sd_bus_track_add_sender(sd_bus_track *track, sd_bus_message *m); int sd_bus_track_remove_sender(sd_bus_track *track, sd_bus_message *m); diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 9dd562fa43..da2aa6c73b 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -83,6 +83,8 @@ enum { SD_DHCP_OPTION_REBINDING_T2_TIME = 59, SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61, + SD_DHCP_OPTION_SMTP_SERVER = 69, + SD_DHCP_OPTION_POP3_SERVER = 70, SD_DHCP_OPTION_USER_CLASS = 77, SD_DHCP_OPTION_FQDN = 81, SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100, @@ -90,6 +92,7 @@ enum { SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119, SD_DHCP_OPTION_SIP_SERVER = 120, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121, + SD_DHCP_OPTION_MUD_URL = 161, SD_DHCP_OPTION_PRIVATE_BASE = 224, /* Windows 10 option to send when Anonymize=true */ SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249, @@ -169,6 +172,9 @@ int sd_dhcp_client_set_hostname( int sd_dhcp_client_set_vendor_class_identifier( sd_dhcp_client *client, const char *vci); +int sd_dhcp_client_set_mud_url( + sd_dhcp_client *client, + const char *mudurl); int sd_dhcp_client_set_user_class( sd_dhcp_client *client, const char* const *user_class); diff --git a/src/systemd/sd-dhcp-lease.h b/src/systemd/sd-dhcp-lease.h index b80d607fea..1ed5bf27a3 100644 --- a/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/sd-dhcp-lease.h @@ -45,6 +45,8 @@ int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *ad int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr); +int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr); +int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains); diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index 55272b5164..5f04034b82 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -50,6 +50,8 @@ int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone); int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n); int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n); int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n); +int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n); +int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n); int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled); int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v); diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h index be34d43e74..42d4ec752c 100644 --- a/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/sd-dhcp6-client.h @@ -73,6 +73,7 @@ enum { SD_DHCP6_OPTION_FQDN = 39, /* RFC 4704 */ SD_DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */ + SD_DHCP6_OPTION_MUD_URL = 112, /* RFC 8250 */ /* option codes 89-142 are unassigned */ /* option codes 144-65535 are unassigned */ @@ -120,6 +121,9 @@ int sd_dhcp6_client_get_information_request( int sd_dhcp6_client_set_request_option( sd_dhcp6_client *client, uint16_t option); +int sd_dhcp6_client_set_request_mud_url( + sd_dhcp6_client *client, + char *mudurl); int sd_dhcp6_client_set_prefix_delegation_hint( sd_dhcp6_client *client, uint8_t prefixlen, diff --git a/src/systemd/sd-lldp.h b/src/systemd/sd-lldp.h index bf3afadcec..2dc9f63246 100644 --- a/src/systemd/sd-lldp.h +++ b/src/systemd/sd-lldp.h @@ -96,6 +96,9 @@ enum { #define SD_LLDP_OUI_802_1 (uint8_t[]) { 0x00, 0x80, 0xc2 } #define SD_LLDP_OUI_802_3 (uint8_t[]) { 0x00, 0x12, 0x0f } +#define SD_LLDP_OUI_MUD (uint8_t[]) { 0x00, 0x00, 0x5E } +#define SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION 0x01 + /* IEEE 802.1AB-2009 Annex E */ enum { SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID = 1, @@ -169,6 +172,7 @@ int sd_lldp_neighbor_get_ttl(sd_lldp_neighbor *n, uint16_t *ret_sec); int sd_lldp_neighbor_get_system_name(sd_lldp_neighbor *n, const char **ret); int sd_lldp_neighbor_get_system_description(sd_lldp_neighbor *n, const char **ret); int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret); +int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret); int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret); int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret); diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h index 1e6d354011..c185e2ce30 100644 --- a/src/systemd/sd-network.h +++ b/src/systemd/sd-network.h @@ -167,6 +167,12 @@ int sd_network_link_get_route_domains(int ifindex, char ***domains); /* Get the sip servers for a given link. */ int sd_network_link_get_sip_servers(int ifindex, char ***sip); +/* Get the pop3 servers for a given link. */ +int sd_network_link_get_pop3_servers(int ifindex, char ***pop3); + +/* Get the SMTP servers for a given link. */ +int sd_network_link_get_smtp_servers(int ifindex, char ***smtp); + /* Get whether this link shall be used as 'default route' for DNS queries */ int sd_network_link_get_dns_default_route(int ifindex); diff --git a/src/systemd/sd-path.h b/src/systemd/sd-path.h index 16379876eb..7da7a9f814 100644 --- a/src/systemd/sd-path.h +++ b/src/systemd/sd-path.h @@ -78,11 +78,38 @@ enum { SD_PATH_SEARCH_STATE_FACTORY, SD_PATH_SEARCH_CONFIGURATION, + /* Various systemd paths, generally mirroring systemd.pc */ + SD_PATH_SYSTEMD_UTIL_DIR, + SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR, + SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR, + SD_PATH_SYSTEMD_USER_UNIT_DIR, + SD_PATH_SYSTEMD_USER_PRESET_DIR, + SD_PATH_SYSTEMD_SYSTEM_CONF_DIR, + SD_PATH_SYSTEMD_USER_CONF_DIR, + SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH, + SD_PATH_SYSTEMD_USER_UNIT_PATH, + SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR, + SD_PATH_SYSTEMD_USER_GENERATOR_DIR, + SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH, + SD_PATH_SYSTEMD_USER_GENERATOR_PATH, + SD_PATH_SYSTEMD_SLEEP_DIR, + SD_PATH_SYSTEMD_SHUTDOWN_DIR, + + SD_PATH_TMPFILES_DIR, + SD_PATH_SYSUSERS_DIR, + SD_PATH_SYSCTL_DIR, + SD_PATH_BINFMT_DIR, + SD_PATH_MODULES_LOAD_DIR, + SD_PATH_CATALOG_DIR, + + /* systemd-networkd search paths */ + SD_PATH_SYSTEMD_NETWORK_PATH, + _SD_PATH_MAX, }; -int sd_path_home(uint64_t type, const char *suffix, char **path); -int sd_path_search(uint64_t type, const char *suffix, char ***paths); +int sd_path_lookup(uint64_t type, const char *suffix, char **path); +int sd_path_lookup_strv(uint64_t type, const char *suffix, char ***paths); _SD_END_DECLARATIONS; diff --git a/src/test/meson.build b/src/test/meson.build index 7c55f65be1..a674d6cfe9 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -588,6 +588,10 @@ tests += [ [], []], + [['src/test/test-coredump-util.c'], + [], + []], + [['src/test/test-daemon.c'], [], []], @@ -778,6 +782,10 @@ tests += [ [], []], + [['src/test/test-sd-path.c'], + [], + []], + [['src/test/test-local-addresses.c'], [], []], @@ -1022,10 +1030,7 @@ tests += [ ] -# test-bus-vtable-cc.cc is a symlink and symlinks get lost in containers on FuzzBuzz. -# The issue has been reported to the developers of FuzzBuzz and hopefully will be fixed soon. -# In the meantime, let's just skip the symlink there. -if cxx_cmd != '' and not want_fuzzbuzz +if cxx_cmd != '' tests += [ [['src/libsystemd/sd-bus/test-bus-vtable-cc.cc'], [], diff --git a/src/test/test-bpf-firewall.c b/src/test/test-bpf-firewall.c index fbaa349b45..71aed12558 100644 --- a/src/test/test-bpf-firewall.c +++ b/src/test/test-bpf-firewall.c @@ -48,7 +48,9 @@ int main(int argc, char *argv[]) { if (r == -ENOMEDIUM) return log_tests_skipped("cgroupfs not available"); - assert_se(set_unit_path(get_testdata_dir()) >= 0); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("units", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p); diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c index 02c8549b4b..daafba4ef6 100644 --- a/src/test/test-cgroup-mask.c +++ b/src/test/test-cgroup-mask.c @@ -38,7 +38,9 @@ static int test_cgroup_mask(void) { return log_tests_skipped("cgroupfs not available"); /* Prepare the manager. */ - assert_se(set_unit_path(get_testdata_dir()) >= 0); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("units", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); if (IN_SET(r, -EPERM, -EACCES)) { diff --git a/src/test/test-cgroup-unit-default.c b/src/test/test-cgroup-unit-default.c index 1286f11e4e..372667041c 100644 --- a/src/test/test-cgroup-unit-default.c +++ b/src/test/test-cgroup-unit-default.c @@ -22,7 +22,9 @@ static int test_default_memory_low(void) { if (r == -ENOMEDIUM) return log_tests_skipped("cgroupfs not available"); - assert_se(set_unit_path(get_testdata_dir()) >= 0); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("units", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); if (IN_SET(r, -EPERM, -EACCES)) { diff --git a/src/test/test-coredump-util.c b/src/test/test-coredump-util.c new file mode 100644 index 0000000000..14a78007e3 --- /dev/null +++ b/src/test/test-coredump-util.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "alloc-util.h" +#include "coredump-util.h" +#include "macro.h" +#include "tests.h" + +static void test_coredump_filter_to_from_string(void) { + log_info("/* %s */", __func__); + + for (CoredumpFilter i = 0; i < _COREDUMP_FILTER_MAX; i++) { + const char *n; + + assert_se(n = coredump_filter_to_string(i)); + log_info("0x%x\t%s", 1<<i, n); + assert_se(coredump_filter_from_string(n) == i); + + uint64_t f; + assert_se(coredump_filter_mask_from_string(n, &f) == 0); + assert_se(f == 1u << i); + } +} + +static void test_coredump_filter_mask_from_string(void) { + log_info("/* %s */", __func__); + + uint64_t f; + assert_se(coredump_filter_mask_from_string("default", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); + + assert_se(coredump_filter_mask_from_string(" default\tdefault\tdefault ", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); + + assert_se(coredump_filter_mask_from_string("defaulta", &f) < 0); + assert_se(coredump_filter_mask_from_string("default defaulta default", &f) < 0); + assert_se(coredump_filter_mask_from_string("default default defaulta", &f) < 0); + + assert_se(coredump_filter_mask_from_string("private-anonymous default", &f) == 0); + assert_se(f == COREDUMP_FILTER_MASK_DEFAULT); + + assert_se(coredump_filter_mask_from_string("shared-file-backed shared-dax", &f) == 0); + assert_se(f == (1 << COREDUMP_FILTER_SHARED_FILE_BACKED | + 1 << COREDUMP_FILTER_SHARED_DAX)); + + assert_se(coredump_filter_mask_from_string("private-file-backed private-dax 0xF", &f) == 0); + assert_se(f == (1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED | + 1 << COREDUMP_FILTER_PRIVATE_DAX | + 0xF)); + + assert_se(coredump_filter_mask_from_string("11", &f) == 0); + assert_se(f == 0x11); + + assert_se(coredump_filter_mask_from_string("0x1101", &f) == 0); + assert_se(f == 0x1101); + + assert_se(coredump_filter_mask_from_string("0", &f) == 0); + assert_se(f == 0); + + assert_se(coredump_filter_mask_from_string("all", &f) == 0); + assert_se(FLAGS_SET(f, (1 << COREDUMP_FILTER_PRIVATE_ANONYMOUS | + 1 << COREDUMP_FILTER_SHARED_ANONYMOUS | + 1 << COREDUMP_FILTER_PRIVATE_FILE_BACKED | + 1 << COREDUMP_FILTER_SHARED_FILE_BACKED | + 1 << COREDUMP_FILTER_ELF_HEADERS | + 1 << COREDUMP_FILTER_PRIVATE_HUGE | + 1 << COREDUMP_FILTER_SHARED_HUGE | + 1 << COREDUMP_FILTER_PRIVATE_DAX | + 1 << COREDUMP_FILTER_SHARED_DAX))); +} + +int main(int argc, char **argv) { + test_setup_logging(LOG_INFO); + + test_coredump_filter_to_from_string(); + test_coredump_filter_mask_from_string(); + + return 0; +} diff --git a/src/test/test-engine.c b/src/test/test-engine.c index b8351141fe..6465151b27 100644 --- a/src/test/test-engine.c +++ b/src/test/test-engine.c @@ -26,8 +26,11 @@ int main(int argc, char *argv[]) { return log_tests_skipped("cgroupfs not available"); /* prepare the test */ - assert_se(set_unit_path(get_testdata_dir()) >= 0); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("units", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); if (manager_errno_skip_test(r)) return log_tests_skipped_errno(r, "manager_new"); diff --git a/src/test/test-escape.c b/src/test/test-escape.c index f6aae1eb18..699747fcc3 100644 --- a/src/test/test-escape.c +++ b/src/test/test-escape.c @@ -142,31 +142,42 @@ static void test_shell_maybe_quote_one(const char *s, static void test_shell_maybe_quote(void) { test_shell_maybe_quote_one("", ESCAPE_BACKSLASH, ""); + test_shell_maybe_quote_one("", ESCAPE_BACKSLASH_ONELINE, ""); test_shell_maybe_quote_one("", ESCAPE_POSIX, ""); test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH, "\"\\\\\""); + test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH_ONELINE, "\"\\\\\""); test_shell_maybe_quote_one("\\", ESCAPE_POSIX, "$'\\\\'"); test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH, "\"\\\"\""); + test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH_ONELINE, "\"\\\"\""); test_shell_maybe_quote_one("\"", ESCAPE_POSIX, "$'\"'"); test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH, "foobar"); + test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH_ONELINE, "foobar"); test_shell_maybe_quote_one("foobar", ESCAPE_POSIX, "foobar"); test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH, "\"foo bar\""); + test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH_ONELINE, "\"foo bar\""); test_shell_maybe_quote_one("foo bar", ESCAPE_POSIX, "$'foo bar'"); test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH, "\"foo\tbar\""); + test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH_ONELINE, "\"foo\\tbar\""); test_shell_maybe_quote_one("foo\tbar", ESCAPE_POSIX, "$'foo\\tbar'"); test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH, "\"foo\nbar\""); + test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH_ONELINE, "\"foo\\nbar\""); test_shell_maybe_quote_one("foo\nbar", ESCAPE_POSIX, "$'foo\\nbar'"); test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH, "\"foo \\\"bar\\\" waldo\""); + test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH_ONELINE, "\"foo \\\"bar\\\" waldo\""); test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_POSIX, "$'foo \"bar\" waldo'"); test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH, "\"foo\\$bar\""); + test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH_ONELINE, "\"foo\\$bar\""); test_shell_maybe_quote_one("foo$bar", ESCAPE_POSIX, "$'foo$bar'"); /* Note that current users disallow control characters, so this "test" * is here merely to establish current behaviour. If control characters * were allowed, they should be quoted, i.e. \001 should become \\001. */ test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH, "\"a\nb\001\""); + test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH_ONELINE, "\"a\\nb\001\""); test_shell_maybe_quote_one("a\nb\001", ESCAPE_POSIX, "$'a\\nb\001'"); test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH, "\"foo!bar\""); + test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH_ONELINE, "\"foo!bar\""); test_shell_maybe_quote_one("foo!bar", ESCAPE_POSIX, "$'foo!bar'"); } diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 4e0fd7d5b4..5a96b46a77 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -806,7 +806,6 @@ static int run_tests(UnitFileScope scope, const test_entry tests[], char **patte int main(int argc, char *argv[]) { _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; - _cleanup_free_ char *test_execute_path = NULL; static const test_entry user_tests[] = { entry(test_exec_basic), @@ -878,9 +877,10 @@ int main(int argc, char *argv[]) { if (r == -ENOMEDIUM) return log_tests_skipped("cgroupfs not available"); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); - test_execute_path = path_join(get_testdata_dir(), "test-execute"); - assert_se(set_unit_path(test_execute_path) >= 0); /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test * cases, otherwise (and if they are present in the environment), diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 23c7d370d4..32a00349ac 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -444,20 +444,20 @@ static void test_write_string_file_verify(void) { _cleanup_free_ char *buf = NULL, *buf2 = NULL; int r; - assert_se(read_one_line_file("/proc/cmdline", &buf) >= 0); + assert_se(read_one_line_file("/proc/version", &buf) >= 0); assert_se(buf2 = strjoin(buf, "\n")); - r = write_string_file("/proc/cmdline", buf, 0); + r = write_string_file("/proc/version", buf, 0); assert_se(IN_SET(r, -EACCES, -EIO)); - r = write_string_file("/proc/cmdline", buf2, 0); + r = write_string_file("/proc/version", buf2, 0); assert_se(IN_SET(r, -EACCES, -EIO)); - assert_se(write_string_file("/proc/cmdline", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0); - assert_se(write_string_file("/proc/cmdline", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0); + assert_se(write_string_file("/proc/version", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0); + assert_se(write_string_file("/proc/version", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0); - r = write_string_file("/proc/cmdline", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE); + r = write_string_file("/proc/version", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE); assert_se(IN_SET(r, -EACCES, -EIO)); - assert_se(write_string_file("/proc/cmdline", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE) == 0); + assert_se(write_string_file("/proc/version", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE) == 0); } static void test_load_env_file_pairs(void) { @@ -757,7 +757,7 @@ static void test_read_line3(void) { _cleanup_free_ char *line = NULL; int r; - f = fopen("/proc/cmdline", "re"); + f = fopen("/proc/uptime", "re"); if (!f && IN_SET(errno, ENOENT, EPERM)) return; assert_se(f); diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c index 25498916f1..49faa6a33b 100644 --- a/src/test/test-install-root.c +++ b/src/test/test-install-root.c @@ -55,7 +55,7 @@ static void test_basic_mask_and_enable(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/dev/null")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/a.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); @@ -74,7 +74,7 @@ static void test_basic_mask_and_enable(const char *root) { assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/a.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -83,7 +83,7 @@ static void test_basic_mask_and_enable(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -102,7 +102,7 @@ static void test_basic_mask_and_enable(const char *root) { assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -123,7 +123,7 @@ static void test_basic_mask_and_enable(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -138,7 +138,7 @@ static void test_basic_mask_and_enable(const char *root) { assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); assert_se(streq(changes[0].path, p)); assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/a.service")); @@ -196,7 +196,7 @@ static void test_linked_units(const char *root) { p = strjoina(root, "/usr/lib/systemd/system/linked2.service"); assert_se(symlink("/opt/linked2.service", p) >= 0); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked3.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked3.service"); assert_se(symlink("/opt/linked3.service", p) >= 0); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) == -ENOENT); @@ -208,7 +208,7 @@ static void test_linked_units(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/opt/linked.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -219,7 +219,7 @@ static void test_linked_units(const char *root) { assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -229,8 +229,8 @@ static void test_linked_units(const char *root) { /* Now, let's not just link it, but also enable it */ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service"); - q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked.service"); + q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); for (i = 0 ; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[i].source, "/opt/linked.service")); @@ -251,8 +251,8 @@ static void test_linked_units(const char *root) { /* And let's unlink it again */ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service"); - q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked.service"); + q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); for (i = 0; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_UNLINK); @@ -271,8 +271,8 @@ static void test_linked_units(const char *root) { assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked2.service"); - q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked2.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked2.service"); + q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked2.service"); for (i = 0 ; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[i].source, "/opt/linked2.service")); @@ -325,7 +325,7 @@ static void test_default(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH "/" SPECIAL_DEFAULT_TARGET); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR "/" SPECIAL_DEFAULT_TARGET); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -355,7 +355,7 @@ static void test_add_dependency(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/real-add-dependency-test-service.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -396,7 +396,7 @@ static void test_template_enable(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@def.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@def.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -427,7 +427,7 @@ static void test_template_enable(const char *root) { assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@foo.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@foo.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -460,7 +460,7 @@ static void test_template_enable(const char *root) { assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/template@quux.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@quux.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -506,7 +506,7 @@ static void test_indirect(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/indirectb.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/indirectb.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/indirectb.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -518,7 +518,7 @@ static void test_indirect(const char *root) { assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/indirectb.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/indirectb.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -559,7 +559,7 @@ static void test_preset_and_list(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/preset-yes.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -570,7 +570,7 @@ static void test_preset_and_list(const char *root) { assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -590,7 +590,7 @@ static void test_preset_and_list(const char *root) { assert_se(n_changes > 0); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/preset-yes.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service"); for (i = 0; i < n_changes; i++) { @@ -655,7 +655,7 @@ static void test_revert(const char *root) { unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/xx.service"); assert_se(write_string_file(p, "# Empty override\n", WRITE_STRING_FILE_CREATE) >= 0); /* Revert the override file */ @@ -666,7 +666,7 @@ static void test_revert(const char *root) { unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service.d/dropin.conf"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/xx.service.d/dropin.conf"); assert_se(mkdir_parents(p, 0755) >= 0); assert_se(write_string_file(p, "# Empty dropin\n", WRITE_STRING_FILE_CREATE) >= 0); @@ -676,7 +676,7 @@ static void test_revert(const char *root) { assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/xx.service.d"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/xx.service.d"); assert_se(changes[1].type == UNIT_FILE_UNLINK); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); @@ -715,7 +715,7 @@ static void test_preset_order(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/prefix-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/prefix-1.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -777,7 +777,7 @@ static void test_with_dropin(const char *root) { assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-1.service", &state) >= 0 && state == UNIT_FILE_DISABLED); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); @@ -795,7 +795,7 @@ static void test_with_dropin(const char *root) { "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-3.service.d/dropin.conf"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-3.service.d/dropin.conf"); assert_se(mkdir_parents(p, 0755) >= 0); assert_se(write_string_file(p, "[Install]\n" @@ -808,7 +808,7 @@ static void test_with_dropin(const char *root) { "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-4a.service.d/dropin.conf"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-4a.service.d/dropin.conf"); assert_se(mkdir_parents(p, 0755) >= 0); assert_se(write_string_file(p, "[Install]\n" @@ -829,9 +829,9 @@ static void test_with_dropin(const char *root) { assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-1.service"); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/graphical.target.wants/with-dropin-1.service"); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -841,11 +841,11 @@ static void test_with_dropin(const char *root) { assert_se(n_changes == 2); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type == UNIT_FILE_SYMLINK); - assert_se(streq(changes[0].source, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service")); - assert_se(streq(changes[1].source, SYSTEM_CONFIG_UNIT_PATH"/with-dropin-2.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2.service"); + assert_se(streq(changes[0].source, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service")); + assert_se(streq(changes[1].source, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service")); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2.service"); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-2.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/graphical.target.wants/with-dropin-2.service"); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -857,9 +857,9 @@ static void test_with_dropin(const char *root) { assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-3.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-3.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-3.service"); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-3.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/graphical.target.wants/with-dropin-3.service"); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -871,9 +871,9 @@ static void test_with_dropin(const char *root) { assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-4a.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-4b.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-4a.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-4a.service"); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-4b.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-4b.service"); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -941,9 +941,9 @@ static void test_with_dropin_template(const char *root) { assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1@.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-1@instance-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-1@instance-1.service"); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-1@instance-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/graphical.target.wants/with-dropin-1@instance-1.service"); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -954,9 +954,9 @@ static void test_with_dropin_template(const char *root) { assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-2@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2@instance-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2@instance-1.service"); assert_se(streq(changes[0].path, p)); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/graphical.target.wants/with-dropin-2@instance-1.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/graphical.target.wants/with-dropin-2@instance-1.service"); assert_se(streq(changes[1].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -965,7 +965,7 @@ static void test_with_dropin_template(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-2@instance-2.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2@instance-2.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -974,7 +974,7 @@ static void test_with_dropin_template(const char *root) { assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3@.service")); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/with-dropin-3@instance-2.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-3@instance-2.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -1014,7 +1014,7 @@ static void test_preset_multiple_instances(const char *root) { assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/foo@bar0.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -1022,7 +1022,7 @@ static void test_preset_multiple_instances(const char *root) { assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/foo@bar0.service"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/foo@bar0.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; @@ -1214,7 +1214,7 @@ int main(int argc, char *argv[]) { p = strjoina(root, "/usr/lib/systemd/system/"); assert_se(mkdir_p(p, 0755) >= 0); - p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/"); + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/"); assert_se(mkdir_p(p, 0755) >= 0); p = strjoina(root, "/run/systemd/system/"); diff --git a/src/test/test-journal-importer.c b/src/test/test-journal-importer.c index 7e898735c9..4883356956 100644 --- a/src/test/test-journal-importer.c +++ b/src/test/test-journal-importer.c @@ -25,7 +25,7 @@ static void test_basic_parsing(void) { _cleanup_free_ char *journal_data_path = NULL; int r; - journal_data_path = path_join(get_testdata_dir(), "journal-data/journal-1.txt"); + assert_se(get_testdata_dir("journal-data/journal-1.txt", &journal_data_path) >= 0); imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); assert_se(imp.fd >= 0); @@ -56,7 +56,7 @@ static void test_bad_input(void) { _cleanup_free_ char *journal_data_path = NULL; int r; - journal_data_path = path_join(get_testdata_dir(), "journal-data/journal-2.txt"); + assert_se(get_testdata_dir("journal-data/journal-1.txt", &journal_data_path) >= 0); imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); assert_se(imp.fd >= 0); diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c index d732f402f0..1627bc747d 100644 --- a/src/test/test-parse-util.c +++ b/src/test/test-parse-util.c @@ -561,6 +561,44 @@ static void test_safe_atoi64(void) { assert_se(r == -EINVAL); } +static void test_safe_atoux64(void) { + int r; + uint64_t l; + + r = safe_atoux64("12345", &l); + assert_se(r == 0); + assert_se(l == 0x12345); + + r = safe_atoux64(" 12345", &l); + assert_se(r == 0); + assert_se(l == 0x12345); + + r = safe_atoux64("0x12345", &l); + assert_se(r == 0); + assert_se(l == 0x12345); + + r = safe_atoux64("18446744073709551617", &l); + assert_se(r == -ERANGE); + + r = safe_atoux64("-1", &l); + assert_se(r == -ERANGE); + + r = safe_atoux64(" -1", &l); + assert_se(r == -ERANGE); + + r = safe_atoux64("junk", &l); + assert_se(r == -EINVAL); + + r = safe_atoux64("123x", &l); + assert_se(r == -EINVAL); + + r = safe_atoux64("12.3", &l); + assert_se(r == -EINVAL); + + r = safe_atoux64("", &l); + assert_se(r == -EINVAL); +} + static void test_safe_atod(void) { int r; double d; @@ -838,6 +876,7 @@ int main(int argc, char *argv[]) { test_safe_atoux16(); test_safe_atou64(); test_safe_atoi64(); + test_safe_atoux64(); test_safe_atod(); test_parse_percent(); test_parse_percent_unbounded(); diff --git a/src/test/test-path.c b/src/test/test-path.c index 6ad222b5f9..830d5f261b 100644 --- a/src/test/test-path.c +++ b/src/test/test-path.c @@ -251,7 +251,7 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_INFO); - test_path = path_join(get_testdata_dir(), "test-path"); + assert_se(get_testdata_dir("test-path", &test_path) >= 0); assert_se(set_unit_path(test_path) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index cd45537847..da6d2a21e6 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -25,8 +25,11 @@ int main(int argc, char *argv[]) { return log_tests_skipped("cgroupfs not available"); /* prepare the test */ - assert_se(set_unit_path(get_testdata_dir()) >= 0); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("units", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); if (manager_errno_skip_test(r)) return log_tests_skipped_errno(r, "manager_new"); diff --git a/src/test/test-sd-path.c b/src/test/test-sd-path.c new file mode 100644 index 0000000000..9260db5ace --- /dev/null +++ b/src/test/test-sd-path.c @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "sd-path.h" + +#include "alloc-util.h" +#include "string-util.h" +#include "strv.h" +#include "tests.h" + +static void test_sd_path_lookup(void) { + log_info("/* %s */", __func__); + + for (uint64_t i = 0; i < _SD_PATH_MAX; i++) { + _cleanup_free_ char *t = NULL, *s = NULL; + int r; + + r = sd_path_lookup(i, NULL, &t); + if (i == SD_PATH_USER_RUNTIME && r == -ENXIO) + continue; + assert_se(r == 0); + assert_se(t); + log_info("%02"PRIu64": \"%s\"", i, t); + + assert_se(sd_path_lookup(i, "suffix", &s) == 0); + assert_se(s); + log_info("%02"PRIu64": \"%s\"", i, s); + assert_se(endswith(s, "/suffix")); + } + + char *tt; + assert_se(sd_path_lookup(_SD_PATH_MAX, NULL, &tt) == -EOPNOTSUPP); +} + +static void test_sd_path_lookup_strv(void) { + log_info("/* %s */", __func__); + + for (uint64_t i = 0; i < _SD_PATH_MAX; i++) { + _cleanup_strv_free_ char **t = NULL, **s = NULL; + char **item; + int r; + + r = sd_path_lookup_strv(i, NULL, &t); + if (i == SD_PATH_USER_RUNTIME && r == -ENXIO) + continue; + assert_se(r == 0); + assert_se(t); + log_info("%02"PRIu64":", i); + STRV_FOREACH(item, t) + log_debug(" %s", *item); + + assert_se(sd_path_lookup_strv(i, "suffix", &s) == 0); + assert_se(s); + log_info("%02"PRIu64":", i); + STRV_FOREACH(item, s) { + assert_se(endswith(*item, "/suffix")); + log_debug(" %s", *item); + } + } + + char *tt; + assert_se(sd_path_lookup(_SD_PATH_MAX, NULL, &tt) == -EOPNOTSUPP); +} + +int main(void) { + test_setup_logging(LOG_DEBUG); + + test_sd_path_lookup(); + test_sd_path_lookup_strv(); +} diff --git a/src/test/test-strv.c b/src/test/test-strv.c index dd6233175c..5473e983bd 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -307,6 +307,12 @@ static void test_strv_split(void) { l = strv_split_full(" 'one' \" two\t three \"' four five", NULL, SPLIT_QUOTES | SPLIT_RELAX); assert_se(l); assert_se(strv_equal(l, (char**) input_table_quoted)); + + strv_free_erase(l); + + l = strv_split_full("\\", NULL, SPLIT_QUOTES | SPLIT_RELAX); + assert_se(l); + assert_se(strv_equal(l, STRV_MAKE("\\"))); } static void test_strv_split_empty(void) { @@ -674,7 +680,7 @@ static void test_strv_push_prepend(void) { log_info("/* %s */", __func__); - a = strv_new("foo", "bar", "three"); + assert_se(a = strv_new("foo", "bar", "three")); assert_se(strv_push_prepend(&a, strdup("first")) >= 0); assert_se(streq(a[0], "first")); diff --git a/src/test/test-terminal-util.c b/src/test/test-terminal-util.c index 0e563f5497..52e651faef 100644 --- a/src/test/test-terminal-util.c +++ b/src/test/test-terminal-util.c @@ -88,7 +88,7 @@ static void test_colors(void) { test_one_color("green", ansi_green()); test_one_color("yellow", ansi_yellow()); test_one_color("blue", ansi_blue()); - test_one_color("megenta", ansi_magenta()); + test_one_color("magenta", ansi_magenta()); test_one_color("grey", ansi_grey()); test_one_color("highlight-red", ansi_highlight_red()); test_one_color("highlight-green", ansi_highlight_green()); diff --git a/src/test/test-umount.c b/src/test/test-umount.c index 6ab5758ede..b27b75b352 100644 --- a/src/test/test-umount.c +++ b/src/test/test-umount.c @@ -15,8 +15,10 @@ static void test_mount_points_list(const char *fname) { log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo"); - if (fname) - fname = testdata_fname = path_join(get_testdata_dir(), fname); + if (fname) { + assert_se(get_testdata_dir(fname, &testdata_fname) >= 0); + fname = testdata_fname; + } LIST_HEAD_INIT(mp_list_head); assert_se(mount_points_list_get(fname, &mp_list_head) >= 0); @@ -37,8 +39,10 @@ static void test_swap_list(const char *fname) { log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/swaps"); - if (fname) - fname = testdata_fname = path_join(get_testdata_dir(), fname); + if (fname) { + assert_se(get_testdata_dir(fname, &testdata_fname) >= 0); + fname = testdata_fname; + } LIST_HEAD_INIT(mp_list_head); assert_se(swap_list_get(fname, &mp_list_head) >= 0); diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c index 084a584876..11c01e5189 100644 --- a/src/test/test-user-util.c +++ b/src/test/test-user-util.c @@ -96,7 +96,7 @@ static void test_valid_user_group_name_compat(void) { assert_se(valid_user_group_name_compat("eff.")); assert_se(valid_user_group_name_compat("some5")); - assert_se(!valid_user_group_name_compat("5some")); + assert_se(valid_user_group_name_compat("5some")); assert_se(valid_user_group_name_compat("INNER5NUMBER")); } @@ -166,7 +166,7 @@ static void test_valid_user_group_name_or_id_compat(void) { assert_se(valid_user_group_name_or_id_compat("kk-k")); assert_se(valid_user_group_name_or_id_compat("some5")); - assert_se(!valid_user_group_name_or_id_compat("5some")); + assert_se(valid_user_group_name_or_id_compat("5some")); assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER")); } diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c index bad289767d..28ecffb0c0 100644 --- a/src/test/test-watch-pid.c +++ b/src/test/test-watch-pid.c @@ -20,7 +20,10 @@ int main(int argc, char *argv[]) { if (r == -ENOMEDIUM) return log_tests_skipped("cgroupfs not available"); - assert_se(set_unit_path(get_testdata_dir()) >= 0); + _cleanup_free_ char *unit_dir = NULL; + assert_se(get_testdata_dir("units/", &unit_dir) >= 0); + assert_se(set_unit_path(unit_dir) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index d1ba5841fd..6ab30cdecf 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -244,7 +244,7 @@ static int specifier_directory(char specifier, const void *data, const void *use i = PTR_TO_UINT(data); assert(i < ELEMENTSOF(paths_system)); - return sd_path_home(paths[i].type, paths[i].suffix, ret); + return sd_path_lookup(paths[i].type, paths[i].suffix, ret); } static int log_unresolvable_specifier(const char *filename, unsigned line) { diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 9c82759818..48039511fa 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -20,6 +20,7 @@ #include "netlink-util.h" #include "network-internal.h" #include "parse-util.h" +#include "path-lookup.h" #include "path-util.h" #include "proc-cmdline.h" #include "random-util.h" @@ -497,7 +498,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, if (config->alternative_names_policy) for (NamePolicy *p = config->alternative_names_policy; *p != _NAMEPOLICY_INVALID; p++) { - const char *n; + const char *n = NULL; switch (*p) { case NAMEPOLICY_DATABASE: diff --git a/src/udev/udev.pc.in b/src/udev/udev.pc.in index 5acbb2d01a..7b4f4006b5 100644 --- a/src/udev/udev.pc.in +++ b/src/udev/udev.pc.in @@ -2,4 +2,5 @@ Name: udev Description: udev Version: @PROJECT_VERSION@ -udevdir=@udevlibexecdir@ +udev_dir=@udevlibexecdir@ +udevdir=${udev_dir} diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c index df11b5b984..3bc5ecc1d0 100644 --- a/src/userdb/userwork.c +++ b/src/userdb/userwork.c @@ -763,7 +763,7 @@ static int run(int argc, char *argv[]) { if (parent <= 1) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parent already died?"); - if (kill(parent, SIGUSR1) < 0) + if (kill(parent, SIGUSR2) < 0) return log_error_errno(errno, "Failed to kill our own parent."); } } diff --git a/sysctl.d/50-coredump.conf.in b/sysctl.d/50-coredump.conf.in index 47bf847693..da76fd71d6 100644 --- a/sysctl.d/50-coredump.conf.in +++ b/sysctl.d/50-coredump.conf.in @@ -5,8 +5,23 @@ # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. -# See sysctl.d(5) for the description of the files in this directory, -# and systemd-coredump(8) and core(5) for the explanation of the -# setting below. +# See sysctl.d(5) for the description of the files in this directory. +# Pipe the core file to systemd-coredump. The systemd-coredump process spawned +# by the kernel will start a second copy of itself as the +# systemd-coredump@.service, which will do the actual processing and storing of +# the core dump. +# +# See systemd-coredump(8) and core(5). kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t %c %h + +# Also dump processes executing a set-user-ID/set-group-ID program that is +# owned by a user/group other than the real user/group ID of the process, or +# a program that has file capabilities. ("2" is called "suidsafe" in core(5)). +# +# systemd-coredump will store the core file owned by the effective uid and gid +# of the running process (and not the filesystem-user-ID which the kernel uses +# when saving a core dump). +# +# See proc(5), setuid(2), capabilities(7). +fs.suid_dumpable=2 diff --git a/test/README.testsuite b/test/README.testsuite index 471771acd4..7204fdb00b 100644 --- a/test/README.testsuite +++ b/test/README.testsuite @@ -10,10 +10,10 @@ ninja: no work to do. --x-- Running TEST-01-BASIC --x-- + make -C TEST-01-BASIC BUILD_DIR=/home/zbyszek/src/systemd/build clean setup run make: Entering directory '/home/zbyszek/src/systemd/test/TEST-01-BASIC' -TEST CLEANUP: Basic systemd setup -TEST SETUP: Basic systemd setup +TEST-01-BASIC CLEANUP: Basic systemd setup +TEST-01-BASIC SETUP: Basic systemd setup ... -TEST RUN: Basic systemd setup [OK] +TEST-01-BASIC RUN: Basic systemd setup [OK] make: Leaving directory '/home/zbyszek/src/systemd/test/TEST-01-BASIC' --x-- Result of TEST-01-BASIC: 0 --x-- --x-- Running TEST-02-CRYPTSETUP --x-- diff --git a/test/TEST-01-BASIC/Makefile b/test/TEST-01-BASIC/Makefile index 45e9bfc67c..79fe9688b8 100644 --- a/test/TEST-01-BASIC/Makefile +++ b/test/TEST-01-BASIC/Makefile @@ -1,9 +1,6 @@ BUILD_DIR=$(shell ../../tools/find-build-dir.sh) -all setup run: +all setup run clean clean-again: @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ -clean clean-again: - @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --clean - .PHONY: all setup run clean clean-again diff --git a/test/TEST-01-BASIC/test.sh b/test/TEST-01-BASIC/test.sh index 0eaa8f991a..58f6cd1414 100755 --- a/test/TEST-01-BASIC/test.sh +++ b/test/TEST-01-BASIC/test.sh @@ -1,34 +1,25 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="Basic systemd setup" +IMAGE_NAME="basic" RUN_IN_UNPRIVILEGED_CONTAINER=${RUN_IN_UNPRIVILEGED_CONTAINER:-yes} +TEST_REQUIRE_INSTALL_TESTS=0 . $TEST_BASE_DIR/test-functions -test_setup() { +test_create_image() { create_empty_image_rootdir # Create what will eventually be our root filesystem onto an overlay ( LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - setup_basic_environment - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -After=multi-user.target - -[Service] -ExecStart=/bin/sh -e -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; systemctl daemon-reload ; echo OK > /testok' -Type=oneshot -EOF - - setup_testsuite + # install tests manually so the test is functional even when -Dinstall-tests=false + mkdir -p $initdir/usr/lib/systemd/tests/testdata/units/ + cp -v $(dirname $0)/../units/{testsuite-01,end}.service $initdir/usr/lib/systemd/tests/testdata/units/ ) setup_nspawn_root } -do_test "$@" +do_test "$@" 01 diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh index a859b345d0..157a70021b 100755 --- a/test/TEST-02-CRYPTSETUP/test.sh +++ b/test/TEST-02-CRYPTSETUP/test.sh @@ -1,21 +1,22 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="cryptsetup systemd setup" +IMAGE_NAME="cryptsetup" TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions check_result_qemu() { ret=1 - mkdir -p $initdir - mount ${LOOPDEV}p1 $initdir + mount_initdir [[ -e $initdir/testok ]] && ret=0 [[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile mount /dev/mapper/varcrypt $initdir/var cp -a $initdir/var/log/journal $TESTDIR - umount $initdir/var - umount $initdir + rm -r $initdir/var/log/journal/* + _umount_dir $initdir/var + _umount_dir $initdir cryptsetup luksClose /dev/mapper/varcrypt [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed ls -l $TESTDIR/journal/*/*.journal @@ -23,8 +24,7 @@ check_result_qemu() { return $ret } - -test_setup() { +test_create_image() { create_empty_image_rootdir echo -n test >$TESTDIR/keyfile cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile @@ -42,25 +42,12 @@ test_setup() { setup_basic_environment mask_supporting_services - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -After=multi-user.target - -[Service] -ExecStart=/bin/sh -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok' -Type=oneshot -EOF - - setup_testsuite - install_dmevent generate_module_dependencies cat >$initdir/etc/crypttab <<EOF $DM_NAME UUID=$ID_FS_UUID /etc/varkey EOF - echo -n test > $initdir/etc/varkey + echo -n test >$initdir/etc/varkey cat $initdir/etc/crypttab | ddebug cat >>$initdir/etc/fstab <<EOF @@ -82,8 +69,8 @@ test_cleanup() { } test_setup_cleanup() { - cleanup_root_var - _test_setup_cleanup + cleanup_root_var || : + cleanup_initdir } -do_test "$@" +do_test "$@" 02 diff --git a/test/TEST-03-JOBS/test.sh b/test/TEST-03-JOBS/test.sh index 5299464b81..33a1fb6fd0 100755 --- a/test/TEST-03-JOBS/test.sh +++ b/test/TEST-03-JOBS/test.sh @@ -5,36 +5,4 @@ TEST_NO_QEMU=1 . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -After=multi-user.target - -[Service] -ExecStart=/test-jobs.sh -Type=oneshot -EOF - - # copy the units used by this test - cp $TEST_BASE_DIR/{hello.service,sleep.service,hello-after-sleep.target,unstoppable.service} \ - $initdir/etc/systemd/system - cp test-jobs.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 03 diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh index af96dfd719..f16543c2b4 100755 --- a/test/TEST-04-JOURNAL/test.sh +++ b/test/TEST-04-JOURNAL/test.sh @@ -4,41 +4,4 @@ TEST_DESCRIPTION="Journal-related tests" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-journal.sh -Type=oneshot -EOF - - cat >$initdir/etc/systemd/system/forever-print-hola.service <<EOF -[Unit] -Description=ForeverPrintHola service - -[Service] -Type=simple -ExecStart=/bin/sh -x -c 'while :; do printf "Hola\n" || touch /i-lose-my-logs; sleep 1; done' -EOF - - cp test-journal.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 04 diff --git a/test/TEST-05-RLIMITS/test-rlimits.sh b/test/TEST-05-RLIMITS/test-rlimits.sh deleted file mode 100755 index 86b57601fe..0000000000 --- a/test/TEST-05-RLIMITS/test-rlimits.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -set -x -set -e -set -o pipefail - -[[ "$(systemctl show -p DefaultLimitNOFILESoft)" = "DefaultLimitNOFILESoft=10000" ]] -[[ "$(systemctl show -p DefaultLimitNOFILE)" = "DefaultLimitNOFILE=16384" ]] - -[[ "$(systemctl show -p LimitNOFILESoft testsuite.service)" = "LimitNOFILESoft=10000" ]] -[[ "$(systemctl show -p LimitNOFILE testsuite.service)" = "LimitNOFILE=16384" ]] - -[[ "$(ulimit -n -S)" = "10000" ]] -[[ "$(ulimit -n -H)" = "16384" ]] - -touch /testok diff --git a/test/TEST-05-RLIMITS/test.sh b/test/TEST-05-RLIMITS/test.sh index bda37ef212..463fe42a7c 100755 --- a/test/TEST-05-RLIMITS/test.sh +++ b/test/TEST-05-RLIMITS/test.sh @@ -4,37 +4,4 @@ TEST_DESCRIPTION="Resource limits-related tests" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - cat >$initdir/etc/systemd/system.conf <<EOF -[Manager] -DefaultLimitNOFILE=10000:16384 -EOF - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-rlimits.sh -Type=oneshot -EOF - - cp test-rlimits.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 05 diff --git a/test/TEST-06-SELINUX/test.sh b/test/TEST-06-SELINUX/test.sh index 46dc1cd805..7a836bbc03 100755 --- a/test/TEST-06-SELINUX/test.sh +++ b/test/TEST-06-SELINUX/test.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="SELinux tests" +IMAGE_NAME="selinux" TEST_NO_NSPAWN=1 # Requirements: @@ -15,60 +16,16 @@ test -f /usr/share/selinux/devel/include/system/systemd.if || exit 0 SETUP_SELINUX=yes KERNEL_APPEND="$KERNEL_APPEND selinux=1 security=selinux" -test_setup() { +test_create_image() { create_empty_image_rootdir # Create what will eventually be our root filesystem onto an overlay ( LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) setup_basic_environment mask_supporting_services - # setup the testsuite service - cat <<EOF >$initdir/etc/systemd/system/testsuite.service -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-selinux-checks.sh -Type=oneshot -EOF - - cat <<EOF >$initdir/etc/systemd/system/hola.service -[Service] -Type=oneshot -ExecStart=/bin/echo Start Hola -ExecReload=/bin/echo Reload Hola -ExecStop=/bin/echo Stop Hola -RemainAfterExit=yes -EOF - - setup_testsuite - - cat <<EOF >$initdir/etc/systemd/system/load-systemd-test-module.service -[Unit] -Description=Load systemd-test module -DefaultDependencies=no -Requires=local-fs.target -Conflicts=shutdown.target -After=local-fs.target -Before=sysinit.target shutdown.target autorelabel.service -ConditionSecurity=selinux -ConditionPathExists=|/.load-systemd-test-module - -[Service] -ExecStart=/bin/sh -x -c 'echo 0 >/sys/fs/selinux/enforce && cd /systemd-test-module && make -f /usr/share/selinux/devel/Makefile load && rm /.load-systemd-test-module' -Type=oneshot -TimeoutSec=0 -RemainAfterExit=yes -EOF - - touch $initdir/.load-systemd-test-module - mkdir -p $initdir/etc/systemd/system/basic.target.wants - ln -fs load-systemd-test-module.service $initdir/etc/systemd/system/basic.target.wants/load-systemd-test-module.service - local _modules_dir=/var/lib/selinux rm -rf $initdir/$_modules_dir if ! cp -ar $_modules_dir $initdir/$_modules_dir; then @@ -87,11 +44,10 @@ EOF mkdir $initdir/systemd-test-module cp systemd_test.te $initdir/systemd-test-module cp systemd_test.if $initdir/systemd-test-module - cp test-selinux-checks.sh $initdir dracut_install -o sesearch dracut_install runcon dracut_install checkmodule semodule semodule_package m4 make /usr/libexec/selinux/hll/pp load_policy sefcontext_compile ) } -do_test "$@" +do_test "$@" 06 diff --git a/test/TEST-07-ISSUE-1981/test.sh b/test/TEST-07-ISSUE-1981/test.sh index 7927294a8a..5da24a987c 100755 --- a/test/TEST-07-ISSUE-1981/test.sh +++ b/test/TEST-07-ISSUE-1981/test.sh @@ -7,32 +7,4 @@ TEST_NO_QEMU=1 NSPAWN_TIMEOUT=30 -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-segfault.sh -Type=oneshot -EOF - - cp test-segfault.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 07 diff --git a/test/TEST-08-ISSUE-2730/test.sh b/test/TEST-08-ISSUE-2730/test.sh index 2fedef7b58..e5dedf2f0c 100755 --- a/test/TEST-08-ISSUE-2730/test.sh +++ b/test/TEST-08-ISSUE-2730/test.sh @@ -1,70 +1,22 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730" +IMAGE_NAME="test08" TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=300 FSTYPE=ext4 -test_setup() { +test_create_image() { create_empty_image_rootdir # Create what will eventually be our root filesystem onto an overlay ( LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - setup_basic_environment - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/sh -x -c 'mount -o remount,rw /dev/sda1 && echo OK > /testok; systemctl poweroff' -Type=oneshot -EOF - - rm $initdir/etc/fstab - cat >$initdir/etc/systemd/system/-.mount <<EOF -[Unit] -Before=local-fs.target - -[Mount] -What=/dev/sda1 -Where=/ -Type=ext4 -Options=errors=remount-ro,noatime - -[Install] -WantedBy=local-fs.target -Alias=root.mount -EOF - - cat >$initdir/etc/systemd/system/systemd-remount-fs.service <<EOF -[Unit] -DefaultDependencies=no -Conflicts=shutdown.target -After=systemd-fsck-root.service -Before=local-fs-pre.target local-fs.target shutdown.target -Wants=local-fs-pre.target - -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=/bin/systemctl reload / -EOF - - setup_testsuite ) - - ln -s /etc/systemd/system/-.mount $initdir/etc/systemd/system/root.mount - mkdir -p $initdir/etc/systemd/system/local-fs.target.wants - ln -s /etc/systemd/system/-.mount $initdir/etc/systemd/system/local-fs.target.wants/-.mount - mask_supporting_services } -do_test "$@" +do_test "$@" 08 diff --git a/test/TEST-09-ISSUE-2691/test.sh b/test/TEST-09-ISSUE-2691/test.sh index efe75d140b..a4d155be1d 100755 --- a/test/TEST-09-ISSUE-2691/test.sh +++ b/test/TEST-09-ISSUE-2691/test.sh @@ -6,32 +6,4 @@ TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=300 -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<'EOF' -[Unit] -Description=Testsuite service - -[Service] -Type=oneshot -ExecStart=/bin/sh -c '>/testok' -RemainAfterExit=yes -ExecStop=/bin/sh -c 'kill -SEGV $$$$' -TimeoutStopSec=270s -EOF - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 09 diff --git a/test/TEST-10-ISSUE-2467/test.sh b/test/TEST-10-ISSUE-2467/test.sh index 1761ad1e43..14ded56ba1 100755 --- a/test/TEST-10-ISSUE-2467/test.sh +++ b/test/TEST-10-ISSUE-2467/test.sh @@ -4,45 +4,4 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - dracut_install true rm socat - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<'EOF' -[Unit] -Description=Testsuite service - -[Service] -Type=oneshot -ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; printf x > test.file; socat -t20 OPEN:test.file UNIX-CONNECT:/run/test.ctl; >/testok' -EOF - - cat >$initdir/etc/systemd/system/test.socket <<'EOF' -[Socket] -ListenStream=/run/test.ctl -EOF - - cat > $initdir/etc/systemd/system/test.service <<'EOF' -[Unit] -Requires=test.socket -ConditionPathExistsGlob=/tmp/nonexistent - -[Service] -ExecStart=/bin/true -EOF - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 10 diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh index e444414a90..da003c90d5 100755 --- a/test/TEST-11-ISSUE-3166/test.sh +++ b/test/TEST-11-ISSUE-3166/test.sh @@ -5,58 +5,4 @@ TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - dracut_install false touch - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-fail-on-restart.sh -Type=oneshot -EOF - - cat >$initdir/etc/systemd/system/fail-on-restart.service <<EOF -[Unit] -Description=Fail on restart -StartLimitIntervalSec=1m -StartLimitBurst=3 - -[Service] -Type=simple -ExecStart=/bin/false -Restart=always -EOF - - - cat >$initdir/test-fail-on-restart.sh <<'EOF' -#!/usr/bin/env bash -set -x - -systemctl start fail-on-restart.service -active_state=$(systemctl show --property ActiveState fail-on-restart.service) -while [[ "$active_state" == "ActiveState=activating" || "$active_state" == "ActiveState=active" ]]; do - sleep 1 - active_state=$(systemctl show --property ActiveState fail-on-restart.service) -done -systemctl is-failed fail-on-restart.service || exit 1 -touch /testok -EOF - - chmod 0755 $initdir/test-fail-on-restart.sh - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 11 diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh index e30c36ed86..c8abefbd86 100755 --- a/test/TEST-12-ISSUE-3171/test.sh +++ b/test/TEST-12-ISSUE-3171/test.sh @@ -5,85 +5,4 @@ TEST_NO_QEMU=1 . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - dracut_install cat mv stat nc - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -After=multi-user.target - -[Service] -ExecStart=/test-socket-group.sh -Type=oneshot -EOF - - cat >$initdir/test-socket-group.sh <<'EOF' -#!/usr/bin/env bash -set -x -set -e -set -o pipefail - -U=/run/systemd/system/test.socket -cat <<'EOL' >$U -[Unit] -Description=Test socket -[Socket] -Accept=yes -ListenStream=/run/test.socket -SocketGroup=adm -SocketMode=0660 -EOL - -cat <<'EOL' > /run/systemd/system/test@.service -[Unit] -Description=Test service -[Service] -StandardInput=socket -ExecStart=/bin/sh -x -c cat -EOL - -systemctl start test.socket -systemctl is-active test.socket -[[ "$(stat --format='%G' /run/test.socket)" == adm ]] -echo A | nc -w1 -U /run/test.socket - -mv $U ${U}.disabled -systemctl daemon-reload -systemctl is-active test.socket -[[ "$(stat --format='%G' /run/test.socket)" == adm ]] -echo B | nc -w1 -U /run/test.socket && exit 1 - -mv ${U}.disabled $U -systemctl daemon-reload -systemctl is-active test.socket -echo C | nc -w1 -U /run/test.socket && exit 1 -[[ "$(stat --format='%G' /run/test.socket)" == adm ]] - -systemctl restart test.socket -systemctl is-active test.socket -echo D | nc -w1 -U /run/test.socket -[[ "$(stat --format='%G' /run/test.socket)" == adm ]] - - -touch /testok -EOF - - chmod 0755 $initdir/test-socket-group.sh - setup_testsuite - ) - - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 12 diff --git a/test/TEST-13-NSPAWN-SMOKE/Makefile b/test/TEST-13-NSPAWN-SMOKE/Makefile index e5e3350211..e9f93b1104 100644..120000 --- a/test/TEST-13-NSPAWN-SMOKE/Makefile +++ b/test/TEST-13-NSPAWN-SMOKE/Makefile @@ -1,10 +1 @@ -BUILD_DIR=$(shell ../../tools/find-build-dir.sh) - -all setup run: - @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ - -clean clean-again: - @basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean - @rm -f has-overflow - -.PHONY: all setup run clean clean-again +../TEST-01-BASIC/Makefile
\ No newline at end of file diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh index 974b239d80..c777c166f7 100755 --- a/test/TEST-13-NSPAWN-SMOKE/test.sh +++ b/test/TEST-13-NSPAWN-SMOKE/test.sh @@ -1,193 +1,23 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="systemd-nspawn smoke test" +IMAGE_NAME=nspawn TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions -test_setup() { +test_create_image() { create_empty_image_rootdir # Create what will eventually be our root filesystem onto an overlay ( LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - setup_basic_environment mask_supporting_services - dracut_install busybox chmod rmdir unshare ip sysctl - - cp create-busybox-container $initdir/ - ./create-busybox-container $initdir/nc-container + ../create-busybox-container $initdir/nc-container initdir="$initdir/nc-container" dracut_install nc ip - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-nspawn.sh -Type=oneshot -EOF - - cat >$initdir/test-nspawn.sh <<'EOF' -#!/usr/bin/env bash -set -x -set -e -set -u -set -o pipefail - -export SYSTEMD_LOG_LEVEL=debug - -# check cgroup-v2 -is_v2_supported=no -mkdir -p /tmp/cgroup2 -if mount -t cgroup2 cgroup2 /tmp/cgroup2; then - is_v2_supported=yes - umount /tmp/cgroup2 -fi -rmdir /tmp/cgroup2 - -# check cgroup namespaces -is_cgns_supported=no -if [[ -f /proc/1/ns/cgroup ]]; then - is_cgns_supported=yes -fi - -is_user_ns_supported=no -# On some systems (e.g. CentOS 7) the default limit for user namespaces -# is set to 0, which causes the following unshare syscall to fail, even -# with enabled user namespaces support. By setting this value explicitly -# we can ensure the user namespaces support to be detected correctly. -sysctl -w user.max_user_namespaces=10000 -if unshare -U sh -c :; then - is_user_ns_supported=yes -fi - -function check_bind_tmp_path { - # https://github.com/systemd/systemd/issues/4789 - local _root="/var/lib/machines/bind-tmp-path" - /create-busybox-container "$_root" - >/tmp/bind - systemd-nspawn --register=no -D "$_root" --bind=/tmp/bind /bin/sh -c 'test -e /tmp/bind' -} - -function check_norbind { - # https://github.com/systemd/systemd/issues/13170 - local _root="/var/lib/machines/norbind-path" - mkdir -p /tmp/binddir/subdir - echo -n "outer" > /tmp/binddir/subdir/file - mount -t tmpfs tmpfs /tmp/binddir/subdir - echo -n "inner" > /tmp/binddir/subdir/file - /create-busybox-container "$_root" - systemd-nspawn --register=no -D "$_root" --bind=/tmp/binddir:/mnt:norbind /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi' -} - -function check_notification_socket { - # https://github.com/systemd/systemd/issues/4944 - local _cmd='echo a | $(busybox which nc) -U -u -w 1 /run/systemd/nspawn/notify' - systemd-nspawn --register=no -D /nc-container /bin/sh -x -c "$_cmd" - systemd-nspawn --register=no -D /nc-container -U /bin/sh -x -c "$_cmd" -} - -function run { - if [[ "$1" = "yes" && "$is_v2_supported" = "no" ]]; then - printf "Unified cgroup hierarchy is not supported. Skipping.\n" >&2 - return 0 - fi - if [[ "$2" = "yes" && "$is_cgns_supported" = "no" ]]; then - printf "CGroup namespaces are not supported. Skipping.\n" >&2 - return 0 - fi - - local _root="/var/lib/machines/unified-$1-cgns-$2-api-vfs-writable-$3" - /create-busybox-container "$_root" - SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -b - SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -b - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -U -b; then - [[ "$is_user_ns_supported" = "yes" && "$3" = "network" ]] && return 1 - else - [[ "$is_user_ns_supported" = "no" && "$3" = "network" ]] && return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -U -b; then - [[ "$is_user_ns_supported" = "yes" && "$3" = "yes" ]] && return 1 - else - [[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1 - fi - - local _netns_opt="--network-namespace-path=/proc/self/ns/net" - - # --network-namespace-path and network-related options cannot be used together - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-interface=lo -b; then - return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-macvlan=lo -b; then - return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-ipvlan=lo -b; then - return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth -b; then - return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth-extra=lo -b; then - return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-bridge=lo -b; then - return 1 - fi - - if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-zone=zone -b; then - return 1 - fi - - # allow combination of --network-namespace-path and --private-network - if ! SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --private-network -b; then - return 1 - fi - - # test --network-namespace-path works with a network namespace created by "ip netns" - ip netns add nspawn_test - _netns_opt="--network-namespace-path=/run/netns/nspawn_test" - SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" /bin/ip a | grep -v -E '^1: lo.*UP' - local r=$? - ip netns del nspawn_test - - if [ $r -ne 0 ]; then - return 1 - fi - - return 0 -} - -check_bind_tmp_path - -check_norbind - -check_notification_socket - -for api_vfs_writable in yes no network; do - run no no $api_vfs_writable - run yes no $api_vfs_writable - run no yes $api_vfs_writable - run yes yes $api_vfs_writable -done - -touch /testok -EOF - - chmod 0755 $initdir/test-nspawn.sh - setup_testsuite ) } -do_test "$@" +do_test "$@" 13 diff --git a/test/TEST-14-MACHINE-ID/test.sh b/test/TEST-14-MACHINE-ID/test.sh index 74cabf86aa..d1486f0aae 100755 --- a/test/TEST-14-MACHINE-ID/test.sh +++ b/test/TEST-14-MACHINE-ID/test.sh @@ -1,78 +1,21 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="/etc/machine-id testing" +IMAGE_NAME=badid TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions -test_setup() { +test_create_image() { create_empty_image_rootdir # Create what will eventually be our root filesystem onto an overlay ( LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - setup_basic_environment mask_supporting_services printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >$initdir/etc/machine-id - dracut_install mount cmp - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/sh -e -x -c '/test-machine-id-setup.sh; systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok' -Type=oneshot -EOF - -cat >$initdir/test-machine-id-setup.sh <<'EOF' -#!/usr/bin/env bash - -set -e -set -x - -function setup_root { - local _root="$1" - mkdir -p "$_root" - mount -t tmpfs tmpfs "$_root" - mkdir -p "$_root/etc" "$_root/run" -} - -function check { - printf "Expected\n" - cat "$1" - printf "\nGot\n" - cat "$2" - cmp "$1" "$2" -} - -r="$(pwd)/overwrite-broken-machine-id" -setup_root "$r" -systemd-machine-id-setup --print --root "$r" -echo abc >>"$r/etc/machine-id" -id=$(systemd-machine-id-setup --print --root "$r") -echo $id >expected -check expected "$r/etc/machine-id" - -r="$(pwd)/transient-machine-id" -setup_root "$r" -systemd-machine-id-setup --print --root "$r" -echo abc >>"$r/etc/machine-id" -mount -o remount,ro "$r" -mount -t tmpfs tmpfs "$r/run" -transient_id=$(systemd-machine-id-setup --print --root "$r") -mount -o remount,rw "$r" -commited_id=$(systemd-machine-id-setup --print --commit --root "$r") -[[ "$transient_id" = "$commited_id" ]] -check "$r/etc/machine-id" "$r/run/machine-id" -EOF -chmod +x $initdir/test-machine-id-setup.sh - - setup_testsuite ) } -do_test "$@" +do_test "$@" 14 diff --git a/test/TEST-15-DROPIN/test.sh b/test/TEST-15-DROPIN/test.sh index 63bbd35051..1540e2e1f1 100755 --- a/test/TEST-15-DROPIN/test.sh +++ b/test/TEST-15-DROPIN/test.sh @@ -5,18 +5,4 @@ TEST_NO_QEMU=1 . $TEST_BASE_DIR/test-functions -test_setup() { - # create the basic filesystem layout - setup_basic_environment - mask_supporting_services - - # import the test scripts in the rootfs and plug them in systemd - cp testsuite.service $initdir/etc/systemd/system/ - cp test-dropin.sh $initdir/ - setup_testsuite - - # create dedicated rootfs for nspawn (located in $TESTDIR/nspawn-root) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 15 diff --git a/test/TEST-15-DROPIN/testsuite.service b/test/TEST-15-DROPIN/testsuite.service deleted file mode 100644 index 4c9f65e2b1..0000000000 --- a/test/TEST-15-DROPIN/testsuite.service +++ /dev/null @@ -1,6 +0,0 @@ -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/test-dropin.sh -Type=oneshot diff --git a/test/TEST-16-EXTEND-TIMEOUT/test.sh b/test/TEST-16-EXTEND-TIMEOUT/test.sh index 43d9f1278b..e1e2a68fa9 100755 --- a/test/TEST-16-EXTEND-TIMEOUT/test.sh +++ b/test/TEST-16-EXTEND-TIMEOUT/test.sh @@ -6,30 +6,4 @@ TEST_NO_QEMU=1 . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image - - # Create what will eventually be our root filesystem onto an overlay - ( - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - for s in success-all success-start success-stop success-runtime \ - fail-start fail-stop fail-runtime - do - cp testsuite-${s}.service ${initdir}/etc/systemd/system - done - cp testsuite.service ${initdir}/etc/systemd/system - - cp extend_timeout_test_service.sh ${initdir}/ - cp assess.sh ${initdir}/ - - setup_testsuite - ) - - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 16 diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite.service b/test/TEST-16-EXTEND-TIMEOUT/testsuite.service deleted file mode 100644 index 7512ba9e12..0000000000 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite.service +++ /dev/null @@ -1,18 +0,0 @@ - -[Unit] -Description=Testsuite: Assess all other testsuite-*.services worked as expected - -Wants=testsuite-success-all.service -Wants=testsuite-success-start.service -Wants=testsuite-success-runtime.service -Wants=testsuite-success-stop.service -Wants=testsuite-fail-start.service -Wants=testsuite-fail-stop.service -Wants=testsuite-fail-runtime.service -StopWhenUnneeded=yes - -[Service] -Type=simple -TimeoutStartSec=infinity -ExecStartPre=/assess.sh -ExecStart=/bin/true diff --git a/test/TEST-17-UDEV-WANTS/test.sh b/test/TEST-17-UDEV-WANTS/test.sh index e196003e80..5b8f22cbaa 100755 --- a/test/TEST-17-UDEV-WANTS/test.sh +++ b/test/TEST-17-UDEV-WANTS/test.sh @@ -6,29 +6,4 @@ TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=300 -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 17 diff --git a/test/TEST-18-FAILUREACTION/test.sh b/test/TEST-18-FAILUREACTION/test.sh index b6231e6f5a..5c386b8ea2 100755 --- a/test/TEST-18-FAILUREACTION/test.sh +++ b/test/TEST-18-FAILUREACTION/test.sh @@ -5,31 +5,4 @@ TEST_DESCRIPTION="FailureAction= operation" . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=600 -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 18 diff --git a/test/TEST-19-DELEGATE/test.sh b/test/TEST-19-DELEGATE/test.sh index 2fbfef3062..03c7760bfd 100755 --- a/test/TEST-19-DELEGATE/test.sh +++ b/test/TEST-19-DELEGATE/test.sh @@ -7,29 +7,4 @@ TEST_NO_NSPAWN=1 QEMU_TIMEOUT=600 UNIFIED_CGROUP_HIERARCHY=yes -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 19 diff --git a/test/TEST-20-MAINPIDGAMES/test.sh b/test/TEST-20-MAINPIDGAMES/test.sh index 4cf1b79f9a..50724b3f3c 100755 --- a/test/TEST-20-MAINPIDGAMES/test.sh +++ b/test/TEST-20-MAINPIDGAMES/test.sh @@ -4,34 +4,4 @@ TEST_DESCRIPTION="test changing main PID" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -Before=getty-pre.target -Wants=getty-pre.target - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -NotifyAccess=all -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 20 diff --git a/test/TEST-21-SYSUSERS/test.sh b/test/TEST-21-SYSUSERS/test.sh index c4b221af8a..f7dbbbf47b 100755 --- a/test/TEST-21-SYSUSERS/test.sh +++ b/test/TEST-21-SYSUSERS/test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="Sysuser-related tests" - +IMAGE_NAME=sysusers . $TEST_BASE_DIR/test-functions test_setup() { diff --git a/test/TEST-22-TMPFILES/test.sh b/test/TEST-22-TMPFILES/test.sh index aa6efcfb48..317e4a88f7 100755 --- a/test/TEST-22-TMPFILES/test.sh +++ b/test/TEST-22-TMPFILES/test.sh @@ -2,30 +2,6 @@ set -e TEST_DESCRIPTION="Tmpfiles related tests" TEST_NO_QEMU=1 - . $TEST_BASE_DIR/test-functions -test_setup() { - # create the basic filesystem layout - setup_basic_environment - mask_supporting_services - inst_binary mv - inst_binary stat - inst_binary seq - inst_binary xargs - inst_binary mkfifo - inst_binary readlink - - # setup the testsuite service - cp testsuite.service $initdir/etc/systemd/system/ - setup_testsuite - - mkdir -p $initdir/testsuite - cp run-tmpfiles-tests.sh $initdir/testsuite/ - cp test-*.sh $initdir/testsuite/ - - # create dedicated rootfs for nspawn (located in $TESTDIR/nspawn-root) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 22 diff --git a/test/TEST-23-TYPE-EXEC/test.sh b/test/TEST-23-TYPE-EXEC/test.sh index ebc9fe4c85..1b0d25a721 100755 --- a/test/TEST-23-TYPE-EXEC/test.sh +++ b/test/TEST-23-TYPE-EXEC/test.sh @@ -1,33 +1,6 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="test Type=exec" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 23 diff --git a/test/TEST-24-UNIT-TESTS/test.sh b/test/TEST-24-UNIT-TESTS/test.sh index c9198fb6c7..a3a911c1b2 100755 --- a/test/TEST-24-UNIT-TESTS/test.sh +++ b/test/TEST-24-UNIT-TESTS/test.sh @@ -3,34 +3,43 @@ set -e TEST_DESCRIPTION="Run unit tests under containers" RUN_IN_UNPRIVILEGED_CONTAINER=yes +# embed some newlines in the kernel command line to stress our test suite +KERNEL_APPEND=" + +frobnicate! + +$KERNEL_APPEND +" + . $TEST_BASE_DIR/test-functions check_result_nspawn() { local _ret=1 - [[ -e $TESTDIR/$1/testok ]] && _ret=0 - if [[ -s $TESTDIR/$1/failed ]]; then + [[ -e $1/testok ]] && _ret=0 + if [[ -s $1/failed ]]; then _ret=$(($_ret+1)) echo "=== Failed test log ===" - cat $TESTDIR/$1/failed + cat $1/failed else - if [[ -s $TESTDIR/$1/skipped ]]; then + if [[ -s $1/skipped ]]; then echo "=== Skipped test log ==" - cat $TESTDIR/$1/skipped + cat $1/skipped fi - if [[ -s $TESTDIR/$1/testok ]]; then + if [[ -s $1/testok ]]; then echo "=== Passed tests ===" - cat $TESTDIR/$1/testok + cat $1/testok fi fi - cp -a $TESTDIR/$1/var/log/journal $TESTDIR + cp -a $1/var/log/journal $TESTDIR + rm -r $1/var/log/journal/* + _umount_dir $initdir [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) return $_ret } check_result_qemu() { local _ret=1 - mkdir -p $initdir - mount ${LOOPDEV}p1 $initdir + mount_initdir [[ -e $initdir/testok ]] && _ret=0 if [[ -s $initdir/failed ]]; then _ret=$(($_ret+1)) @@ -47,55 +56,10 @@ check_result_qemu() { fi fi cp -a $initdir/var/log/journal $TESTDIR - umount $initdir + rm -r $initdir/var/log/journal/* + _umount_dir $initdir [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) return $_ret } -test_setup() { - if type -P meson && [[ "$(meson configure $BUILD_DIR | grep install-tests | awk '{ print $2 }')" != "true" ]]; then - dfatal "Needs to be built with -Dinstall-tests=true" - exit 1 - fi - - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - for i in getfacl dirname basename capsh cut rev stat mktemp rmdir ionice unshare uname tr awk getent diff xzcat lz4cat; do - inst_binary $i - done - - inst /etc/hosts - - setup_basic_environment - install_keymaps yes - install_zoneinfo - # Install nproc to determine # of CPUs for correct parallelization - inst_binary nproc - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root - - # mask some services that we do not want to run in these tests - ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service - ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket - ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service -} - -do_test "$@" +do_test "$@" 24 diff --git a/test/TEST-25-IMPORT/test.sh b/test/TEST-25-IMPORT/test.sh index 14265cdfc5..034b94ca79 100755 --- a/test/TEST-25-IMPORT/test.sh +++ b/test/TEST-25-IMPORT/test.sh @@ -4,30 +4,4 @@ TEST_DESCRIPTION="test importd" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - dracut_install dd gunzip mv tar diff - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 25 diff --git a/test/TEST-26-SETENV/test.sh b/test/TEST-26-SETENV/test.sh index ee0f562277..158fa6fdc0 100755 --- a/test/TEST-26-SETENV/test.sh +++ b/test/TEST-26-SETENV/test.sh @@ -4,29 +4,4 @@ TEST_DESCRIPTION="test setenv" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 26 diff --git a/test/TEST-27-STDOUTFILE/test.sh b/test/TEST-27-STDOUTFILE/test.sh index 66c98e5675..23aadf314e 100755 --- a/test/TEST-27-STDOUTFILE/test.sh +++ b/test/TEST-27-STDOUTFILE/test.sh @@ -4,31 +4,4 @@ TEST_DESCRIPTION="test StandardOutput=file:" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - inst_binary cmp - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 27 diff --git a/test/TEST-28-PERCENTJ-WANTEDBY/test.sh b/test/TEST-28-PERCENTJ-WANTEDBY/test.sh index 934e1bc70c..09baf22776 100755 --- a/test/TEST-28-PERCENTJ-WANTEDBY/test.sh +++ b/test/TEST-28-PERCENTJ-WANTEDBY/test.sh @@ -5,52 +5,4 @@ RUN_IN_UNPRIVILEGED_CONTAINER=yes . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # Set up the services. - cat >$initdir/etc/systemd/system/specifier-j-wants.service << EOF -[Unit] -Description=Wants with percent-j specifier -Wants=specifier-j-depends-%j.service -After=specifier-j-depends-%j.service - -[Service] -Type=oneshot -ExecStart=test -f /tmp/test-specifier-j-%j -ExecStart=/bin/sh -c 'echo OK > /testok' -EOF - cat >$initdir/etc/systemd/system/specifier-j-depends-wants.service << EOF -[Unit] -Description=Dependent service for percent-j specifier - -[Service] -Type=oneshot -ExecStart=touch /tmp/test-specifier-j-wants -EOF - cat >$initdir/etc/systemd/system/testsuite.service << EOF -[Unit] -Description=Testsuite: Ensure %j Wants directives work -Wants=specifier-j-wants.service -After=specifier-j-wants.service - -[Service] -Type=oneshot -ExecStart=/bin/true -EOF - - setup_testsuite - ) - - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 28 diff --git a/test/TEST-29-UDEV-ID_RENAMING/test.sh b/test/TEST-29-UDEV-ID_RENAMING/test.sh index fb570b0347..4feafc04d7 100755 --- a/test/TEST-29-UDEV-ID_RENAMING/test.sh +++ b/test/TEST-29-UDEV-ID_RENAMING/test.sh @@ -6,29 +6,4 @@ TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=300 -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 29 diff --git a/test/TEST-30-ONCLOCKCHANGE/test.sh b/test/TEST-30-ONCLOCKCHANGE/test.sh index 9e2c11238c..4723e7b0be 100755 --- a/test/TEST-30-ONCLOCKCHANGE/test.sh +++ b/test/TEST-30-ONCLOCKCHANGE/test.sh @@ -2,42 +2,6 @@ set -e TEST_DESCRIPTION="test OnClockChange= + OnTimezoneChange=" TEST_NO_NSPAWN=1 - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - inst_any /usr/share/zoneinfo/Europe/Kiev - inst_any /usr/share/zoneinfo/Europe/Berlin - - setup_basic_environment - mask_supporting_services - - # extend the watchdog - mkdir -p $initdir/etc/systemd/system/systemd-timedated.service.d - cat >$initdir/etc/systemd/system/systemd-timedated.service.d/watchdog.conf <<EOF -[Service] -WatchdogSec=10min -EOF - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 30 diff --git a/test/TEST-31-DEVICE-ENUMERATION/test.sh b/test/TEST-31-DEVICE-ENUMERATION/test.sh index 7bc9298dc1..4fbd38d2d0 100755 --- a/test/TEST-31-DEVICE-ENUMERATION/test.sh +++ b/test/TEST-31-DEVICE-ENUMERATION/test.sh @@ -6,29 +6,4 @@ TEST_NO_NSPAWN=1 . $TEST_BASE_DIR/test-functions QEMU_TIMEOUT=300 -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 31 diff --git a/test/TEST-32-OOMPOLICY/test.sh b/test/TEST-32-OOMPOLICY/test.sh index 36aad419ea..6f2955cf62 100755 --- a/test/TEST-32-OOMPOLICY/test.sh +++ b/test/TEST-32-OOMPOLICY/test.sh @@ -2,35 +2,8 @@ set -e TEST_DESCRIPTION="test OOM killer logic" TEST_NO_NSPAWN=1 - . $TEST_BASE_DIR/test-functions UNIFIED_CGROUP_HIERARCHY=yes -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -MemoryAccounting=yes -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) -} - -do_test "$@" +do_test "$@" 32 diff --git a/test/TEST-33-CLEAN-UNIT/test.sh b/test/TEST-33-CLEAN-UNIT/test.sh index 310cf7b145..64cb6aee59 100755 --- a/test/TEST-33-CLEAN-UNIT/test.sh +++ b/test/TEST-33-CLEAN-UNIT/test.sh @@ -3,33 +3,6 @@ # ex: ts=8 sw=4 sts=4 et filetype=sh set -e TEST_DESCRIPTION="test CleanUnit" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) || return 1 - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 33 diff --git a/test/TEST-34-DYNAMICUSERMIGRATE/test.sh b/test/TEST-34-DYNAMICUSERMIGRATE/test.sh index ad299df420..0b2174a894 100755 --- a/test/TEST-34-DYNAMICUSERMIGRATE/test.sh +++ b/test/TEST-34-DYNAMICUSERMIGRATE/test.sh @@ -1,33 +1,6 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="test migrating state directory from DynamicUser=1 to DynamicUser=0 and back" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 34 diff --git a/test/TEST-35-NETWORK-GENERATOR/Makefile b/test/TEST-35-NETWORK-GENERATOR/Makefile deleted file mode 120000 index e9f93b1104..0000000000 --- a/test/TEST-35-NETWORK-GENERATOR/Makefile +++ /dev/null @@ -1 +0,0 @@ -../TEST-01-BASIC/Makefile
\ No newline at end of file diff --git a/test/TEST-35-NETWORK-GENERATOR/test.sh b/test/TEST-35-NETWORK-GENERATOR/test.sh deleted file mode 100755 index 7853281850..0000000000 --- a/test/TEST-35-NETWORK-GENERATOR/test.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -e -TEST_DESCRIPTION="network-generator tests" - -. $TEST_BASE_DIR/test-functions - -test_setup() { - mkdir -p $TESTDIR/run/systemd/network -} - -test_run() { - local generator - - if [[ -x $BUILD_DIR/systemd-network-generator ]]; then - generator=$BUILD_DIR/systemd-network-generator - elif [[ -x /usr/lib/systemd/systemd-network-generator ]]; then - generator=/usr/lib/systemd/systemd-network-generator - elif [[ -x /lib/systemd/systemd-network-generator ]]; then - generator=/lib/systemd/systemd-network-generator - else - exit 1 - fi - - for f in test-*.input; do - echo "*** Running $f" - rm -f $TESTDIR/run/systemd/network/* - $generator --root $TESTDIR -- $(cat $f) - - if ! diff -u $TESTDIR/run/systemd/network ${f%.input}.expected; then - echo "**** Unexpected output for $f" - exit 1 - fi - done -} - -do_test "$@" diff --git a/test/TEST-36-NUMAPOLICY/test.sh b/test/TEST-36-NUMAPOLICY/test.sh index 29addc958b..02f013568c 100755 --- a/test/TEST-36-NUMAPOLICY/test.sh +++ b/test/TEST-36-NUMAPOLICY/test.sh @@ -4,34 +4,6 @@ set -e TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options" TEST_NO_NSPAWN=1 QEMU_OPTIONS="-numa node,nodeid=0" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - dracut_install mktemp - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 36 diff --git a/test/TEST-37-RUNTIMEDIRECTORYPRESERVE/test.sh b/test/TEST-37-RUNTIMEDIRECTORYPRESERVE/test.sh index 2c5ad430b5..b5806c429f 100755 --- a/test/TEST-37-RUNTIMEDIRECTORYPRESERVE/test.sh +++ b/test/TEST-37-RUNTIMEDIRECTORYPRESERVE/test.sh @@ -3,33 +3,6 @@ # ex: ts=8 sw=4 sts=4 et filetype=sh set -e TEST_DESCRIPTION="test RuntimeDirectoryPreserve=yes" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) || return 1 - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 37 diff --git a/test/TEST-39-EXECRELOAD/test.sh b/test/TEST-39-EXECRELOAD/test.sh index ac1d0c9cf6..e38a9902ce 100755 --- a/test/TEST-39-EXECRELOAD/test.sh +++ b/test/TEST-39-EXECRELOAD/test.sh @@ -1,35 +1,6 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="Test ExecReload= (PR #13098)" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - # Create what will eventually be our root filesystem onto an overlay - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - dracut_install mktemp - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 39 diff --git a/test/TEST-40-EXEC-COMMAND-EX/test.sh b/test/TEST-40-EXEC-COMMAND-EX/test.sh index a7933b0070..4ee84d4d35 100755 --- a/test/TEST-40-EXEC-COMMAND-EX/test.sh +++ b/test/TEST-40-EXEC-COMMAND-EX/test.sh @@ -1,33 +1,6 @@ #!/usr/bin/env bash set -e TEST_DESCRIPTION="test ExecXYZEx= service unit dbus hookups" - . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 40 diff --git a/test/TEST-41-ONESHOT-RESTART/test.sh b/test/TEST-41-ONESHOT-RESTART/test.sh index 54292c0ca2..d3f96ae107 100755 --- a/test/TEST-41-ONESHOT-RESTART/test.sh +++ b/test/TEST-41-ONESHOT-RESTART/test.sh @@ -3,30 +3,4 @@ set -e TEST_DESCRIPTION="Test oneshot unit restart on failure" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 41 diff --git a/test/TEST-42-EXECSTOPPOST/test.sh b/test/TEST-42-EXECSTOPPOST/test.sh index 0c393597c7..53e6fa3dd0 100755 --- a/test/TEST-42-EXECSTOPPOST/test.sh +++ b/test/TEST-42-EXECSTOPPOST/test.sh @@ -4,46 +4,4 @@ TEST_DESCRIPTION="test that ExecStopPost= is always run" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - - mask_supporting_services - - # setup policy for Type=dbus test - mkdir -p $initdir/etc/dbus-1/system.d - cat > $initdir/etc/dbus-1/system.d/systemd.test.ExecStopPost.conf <<EOF -<?xml version="1.0"?> -<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> -<busconfig> - <policy user="root"> - <allow own="systemd.test.ExecStopPost"/> - </policy> -</busconfig> -EOF - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -Before=getty-pre.target -Wants=getty-pre.target - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 42 diff --git a/test/TEST-43-PRIVATEUSER-UNPRIV/test.sh b/test/TEST-43-PRIVATEUSER-UNPRIV/test.sh index 3b40bf7d8b..4749150ff1 100755 --- a/test/TEST-43-PRIVATEUSER-UNPRIV/test.sh +++ b/test/TEST-43-PRIVATEUSER-UNPRIV/test.sh @@ -3,47 +3,6 @@ set -e TEST_DESCRIPTION="Test PrivateUsers=yes on user manager" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - inst_binary stat - - mask_supporting_services - - # Allocate user for running test case under - mkdir -p $initdir/etc/sysusers.d - cat >$initdir/etc/sysusers.d/testuser.conf <<EOF -u testuser 4711 "Test User" /home/testuser -EOF - - mkdir -p $initdir/home/testuser -m 0700 - chown 4711:4711 $initdir/home/testuser - - enable_user_manager testuser - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -After=systemd-logind.service user@4711.service -Wants=user@4711.service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - has_user_dbus_socket || exit 0 -do_test "$@" +do_test "$@" 43 diff --git a/test/TEST-44-LOG-NAMESPACE/test.sh b/test/TEST-44-LOG-NAMESPACE/test.sh index c2070f2b61..26d863708e 100755 --- a/test/TEST-44-LOG-NAMESPACE/test.sh +++ b/test/TEST-44-LOG-NAMESPACE/test.sh @@ -4,36 +4,4 @@ TEST_DESCRIPTION="test log namespaces" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -Before=getty-pre.target -Wants=getty-pre.target -Wants=systemd-journald@foobar.socket systemd-journald-varlink@foobar.socket -After=systemd-journald@foobar.socket systemd-journald-varlink@foobar.socket - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -LogTarget=foobar -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 44 diff --git a/test/TEST-45-REPART/Makefile b/test/TEST-45-REPART/Makefile deleted file mode 120000 index e9f93b1104..0000000000 --- a/test/TEST-45-REPART/Makefile +++ /dev/null @@ -1 +0,0 @@ -../TEST-01-BASIC/Makefile
\ No newline at end of file diff --git a/test/TEST-45-REPART/test.sh b/test/TEST-45-REPART/test.sh deleted file mode 100755 index e7015d57e0..0000000000 --- a/test/TEST-45-REPART/test.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash -set -e -TEST_DESCRIPTION="test systemd-repart" - -. $TEST_BASE_DIR/test-functions - -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - - mask_supporting_services - dracut_install truncate sfdisk grep - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -Before=getty-pre.target -Wants=getty-pre.target - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" diff --git a/test/TEST-45-REPART/testsuite.sh b/test/TEST-45-REPART/testsuite.sh deleted file mode 100755 index 804faefe78..0000000000 --- a/test/TEST-45-REPART/testsuite.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env bash -set -ex - -# Check if repart is installed, and if it isn't bail out early instead of failing -if ! test -x /usr/bin/systemd-repart ; then - echo OK > /testok - exit 0 -fi - -systemd-analyze log-level debug - -truncate -s 1G /tmp/zzz - -SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8 - -systemd-repart /tmp/zzz --empty=force --dry-run=no --seed=$SEED - -sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/empty - -cmp /tmp/empty - <<EOF -label: gpt -label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D -device: /tmp/zzz -unit: sectors -first-lba: 2048 -last-lba: 2097118 -EOF - -mkdir /tmp/definitions - -cat > /tmp/definitions/root.conf <<EOF -[Partition] -Type=root -EOF - -ln -s root.conf /tmp/definitions/root2.conf - -cat > /tmp/definitions/home.conf <<EOF -[Partition] -Type=home -EOF - -cat > /tmp/definitions/swap.conf <<EOF -[Partition] -Type=swap -SizeMaxBytes=64M -PaddingMinBytes=92M -EOF - -systemd-repart /tmp/zzz --dry-run=no --seed=$SEED --definitions=/tmp/definitions - -sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/populated - -cmp /tmp/populated - <<EOF -label: gpt -label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D -device: /tmp/zzz -unit: sectors -first-lba: 2048 -last-lba: 2097118 -/tmp/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home" -/tmp/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -/tmp/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" -/tmp/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" -EOF - -cat > /tmp/definitions/swap.conf <<EOF -[Partition] -Type=swap -SizeMaxBytes=64M -EOF - -cat > /tmp/definitions/extra.conf <<EOF -[Partition] -Type=linux-generic -EOF - -systemd-repart /tmp/zzz --dry-run=no --seed=$SEED --definitions=/tmp/definitions - -sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/populated2 - -cmp /tmp/populated2 - <<EOF -label: gpt -label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D -device: /tmp/zzz -unit: sectors -first-lba: 2048 -last-lba: 2097118 -/tmp/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home" -/tmp/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -/tmp/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" -/tmp/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" -/tmp/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic" -EOF - -truncate -s 2G /tmp/zzz - -systemd-repart /tmp/zzz --dry-run=no --seed=$SEED --definitions=/tmp/definitions - -sfdisk -d /tmp/zzz | grep -v -e 'sector-size' -e '^$' > /tmp/populated3 - -cmp /tmp/populated3 - <<EOF -label: gpt -label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D -device: /tmp/zzz -unit: sectors -first-lba: 2048 -last-lba: 4194270 -/tmp/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home" -/tmp/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -/tmp/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" -/tmp/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" -/tmp/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic" -EOF - -systemd-analyze log-level info - -echo OK > /testok - -exit 0 diff --git a/test/TEST-46-HOMED/test.sh b/test/TEST-46-HOMED/test.sh index 99fd5b85b8..877cbfefd0 100755 --- a/test/TEST-46-HOMED/test.sh +++ b/test/TEST-46-HOMED/test.sh @@ -5,38 +5,4 @@ TEST_NO_QEMU=1 . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image - mkdir -p $TESTDIR/root - mount ${LOOPDEV}p1 $TESTDIR/root - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service -Before=getty-pre.target -Wants=getty-pre.target - -[Service] -ExecStart=/bin/bash -x /testsuite.sh -Type=oneshot -NotifyAccess=all -EOF - cp testsuite.sh $initdir/ - - setup_testsuite - ) || return 1 - setup_nspawn_root - - ddebug "umount $TESTDIR/root" - umount $TESTDIR/root -} - -do_test "$@" +do_test "$@" 46 diff --git a/test/TEST-47-ISSUE-14566/test.sh b/test/TEST-47-ISSUE-14566/test.sh index 35f862331c..11ae3d2524 100755 --- a/test/TEST-47-ISSUE-14566/test.sh +++ b/test/TEST-47-ISSUE-14566/test.sh @@ -1,43 +1,6 @@ -#!/bin/bash +#!/usr/bin/env bash set -e TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over proccesses with ExecStopPost=" . $TEST_BASE_DIR/test-functions -test_setup() { - create_empty_image_rootdir - - ( - LOG_LEVEL=5 - eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) - - setup_basic_environment - mask_supporting_services - - # setup the testsuite service - cat >$initdir/etc/systemd/system/testsuite.service <<EOF -[Unit] -Description=Testsuite service - -[Service] -ExecStart=/testsuite.sh -Type=oneshot -EOF - cat > $initdir/etc/systemd/system/issue_14566_test.service << EOF -[Unit] -Description=Issue 14566 Repro - -[Service] -ExecStart=/repro.sh -ExecStopPost=/bin/true -KillMode=mixed -EOF - - cp testsuite.sh $initdir/ - cp repro.sh $initdir/ - - setup_testsuite - ) - setup_nspawn_root -} - -do_test "$@" +do_test "$@" 47 diff --git a/test/basic.target b/test/basic.target deleted file mode 120000 index 0612934682..0000000000 --- a/test/basic.target +++ /dev/null @@ -1 +0,0 @@ -../units/basic.target
\ No newline at end of file diff --git a/test/TEST-13-NSPAWN-SMOKE/create-busybox-container b/test/create-busybox-container index 08fb5d4aa6..08fb5d4aa6 100755 --- a/test/TEST-13-NSPAWN-SMOKE/create-busybox-container +++ b/test/create-busybox-container diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 4418fc0149..147ea1b639 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -102,6 +102,7 @@ IPServiceType= SendOption= SendVendorOption= SendDecline= +MUDURL= RouteMTUBytes= [DHCPv6] UseNTP= @@ -110,6 +111,7 @@ RapidCommit= ForceDHCPv6PDOtherInformation= PrefixDelegationHint= WithoutRA= +MUDURL= [Route] Destination= Protocol= @@ -197,9 +199,15 @@ LifetimeSec= EgressUntagged= VLAN= PVID= +[LLDP] +MUDURL= [CAN] SamplePoint= BitRate= +DataSamplePoint= +DataBitRate= +FDMode= +FDNonISO= RestartSec= TripleSampling= Termination= @@ -268,6 +276,8 @@ EmitDNS= NTP= EmitSIP= SIP= +POP3Servers= +SMTPServers= EmitRouter= MaxLeaseTimeSec= DefaultLeaseTimeSec= diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 45f8751971..98cddad349 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -44,6 +44,7 @@ BlockIOWeight= BlockIOWriteBandwidth= Broadcast= BusName= +CoredumpFilter= CPUAccounting= CPUQuota= CPUShares= diff --git a/test/loopy2.service b/test/loopy2.service deleted file mode 120000 index 961b1fe9bc..0000000000 --- a/test/loopy2.service +++ /dev/null @@ -1 +0,0 @@ -loopy.service
\ No newline at end of file diff --git a/test/loopy4.service b/test/loopy4.service deleted file mode 120000 index 43e5658bcd..0000000000 --- a/test/loopy4.service +++ /dev/null @@ -1 +0,0 @@ -loopy3.service
\ No newline at end of file diff --git a/test/meson.build b/test/meson.build index 2fbea31ccd..404b923467 100644 --- a/test/meson.build +++ b/test/meson.build @@ -1,236 +1,56 @@ # SPDX-License-Identifier: LGPL-2.1+ -test_data_files = ''' - a.service - a-conj.service - b.service - basic.target - c.service - d.service - daughter.service - dml.slice - dml-passthrough.slice - dml-passthrough-empty.service - dml-passthrough-set-dml.service - dml-passthrough-set-ml.service - dml-override.slice - dml-override-empty.service - dml-discard.slice - dml-discard-empty.service - dml-discard-set-ml.service - e.service - end.service - f.service - g.service - grandchild.service - h.service - hello-after-sleep.target - hello.service - hwdb.d/10-bad.hwdb - i.service - journal-data/journal-1.txt - journal-data/journal-2.txt - nomem.slice - nomemleaf.service - parent-deep.slice - parent.slice - sched_idle_bad.service - sched_idle_ok.service - sched_rr_bad.service - sched_rr_change.service - sched_rr_ok.service - shutdown.target - sleep.service - sockets.target - son.service - sysinit.target - test-execute/exec-basic.service - test-execute/exec-ambientcapabilities-merge-nfsnobody.service - test-execute/exec-ambientcapabilities-merge-nobody.service - test-execute/exec-ambientcapabilities-merge.service - test-execute/exec-ambientcapabilities-nfsnobody.service - test-execute/exec-ambientcapabilities-nobody.service - test-execute/exec-ambientcapabilities.service - test-execute/exec-bindpaths.service - test-execute/exec-capabilityboundingset-invert.service - test-execute/exec-capabilityboundingset-merge.service - test-execute/exec-capabilityboundingset-reset.service - test-execute/exec-capabilityboundingset-simple.service - test-execute/exec-condition-failed.service - test-execute/exec-condition-skip.service - test-execute/exec-cpuaffinity1.service - test-execute/exec-cpuaffinity2.service - test-execute/exec-cpuaffinity3.service - test-execute/exec-dynamicuser-fixeduser-adm.service - test-execute/exec-dynamicuser-fixeduser-games.service - test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service - test-execute/exec-dynamicuser-fixeduser.service - test-execute/exec-dynamicuser-statedir-migrate-step1.service - test-execute/exec-dynamicuser-statedir-migrate-step2.service - test-execute/exec-dynamicuser-statedir.service - test-execute/exec-dynamicuser-supplementarygroups.service - test-execute/exec-environment-no-substitute.service - test-execute/exec-environment-empty.service - test-execute/exec-environment-multiple.service - test-execute/exec-environment.service - test-execute/exec-environmentfile.service - test-execute/exec-group-nfsnobody.service - test-execute/exec-group-nobody.service - test-execute/exec-group-nogroup.service - test-execute/exec-group.service - test-execute/exec-ignoresigpipe-no.service - test-execute/exec-ignoresigpipe-yes.service - test-execute/exec-inaccessiblepaths-mount-propagation.service - test-execute/exec-inaccessiblepaths-sys.service - test-execute/exec-ioschedulingclass-best-effort.service - test-execute/exec-ioschedulingclass-idle.service - test-execute/exec-ioschedulingclass-none.service - test-execute/exec-ioschedulingclass-realtime.service - test-execute/exec-oomscoreadjust-negative.service - test-execute/exec-oomscoreadjust-positive.service - test-execute/exec-passenvironment-absent.service - test-execute/exec-passenvironment-empty.service - test-execute/exec-passenvironment-repeated.service - test-execute/exec-passenvironment.service - test-execute/exec-personality-aarch64.service - test-execute/exec-personality-ppc64.service - test-execute/exec-personality-ppc64le.service - test-execute/exec-personality-s390.service - test-execute/exec-personality-x86-64.service - test-execute/exec-personality-x86.service - test-execute/exec-privatedevices-disabled-by-prefix.service - test-execute/exec-privatedevices-no-capability-mknod.service - test-execute/exec-privatedevices-no-capability-sys-rawio.service - test-execute/exec-privatedevices-no.service - test-execute/exec-privatedevices-yes-with-group.service - test-execute/exec-privatedevices-yes-capability-mknod.service - test-execute/exec-privatedevices-yes-capability-sys-rawio.service - test-execute/exec-privatedevices-yes.service - test-execute/exec-privatenetwork-yes.service - test-execute/exec-privatetmp-no.service - test-execute/exec-privatetmp-yes.service - test-execute/exec-privatetmp-disabled-by-prefix.service - test-execute/exec-protecthome-tmpfs-vs-protectsystem-strict.service - test-execute/exec-protectkernellogs-yes-capabilities.service - test-execute/exec-protectkernellogs-no-capabilities.service - test-execute/exec-protectkernelmodules-no-capabilities.service - test-execute/exec-protectkernelmodules-yes-capabilities.service - test-execute/exec-protectkernelmodules-yes-mount-propagation.service - test-execute/exec-readonlypaths-mount-propagation.service - test-execute/exec-readonlypaths-simple.service - test-execute/exec-readonlypaths-with-bindpaths.service - test-execute/exec-readonlypaths.service - test-execute/exec-readwritepaths-mount-propagation.service - test-execute/exec-restrictnamespaces-merge-all.service - test-execute/exec-restrictnamespaces-merge-and.service - test-execute/exec-restrictnamespaces-merge-or.service - test-execute/exec-restrictnamespaces-mnt-blacklist.service - test-execute/exec-restrictnamespaces-mnt.service - test-execute/exec-restrictnamespaces-no.service - test-execute/exec-restrictnamespaces-yes.service - test-execute/exec-runtimedirectory-mode.service - test-execute/exec-runtimedirectory-owner-nfsnobody.service - test-execute/exec-runtimedirectory-owner-nobody.service - test-execute/exec-runtimedirectory-owner-nogroup.service - test-execute/exec-runtimedirectory-owner.service - test-execute/exec-runtimedirectory.service - test-execute/exec-specifier-interpolation.service - test-execute/exec-specifier.service - test-execute/exec-specifier@.service - test-execute/exec-standardinput-data.service - test-execute/exec-standardinput-file.service - test-execute/exec-standardinput-file-cat.service - test-execute/exec-standardoutput-file.service - test-execute/exec-standardoutput-append.service - test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service - test-execute/exec-supplementarygroups-multiple-groups-withgid.service - test-execute/exec-supplementarygroups-multiple-groups-withuid.service - test-execute/exec-supplementarygroups-single-group-user.service - test-execute/exec-supplementarygroups-single-group.service - test-execute/exec-supplementarygroups.service - test-execute/exec-systemcallerrornumber-name.service - test-execute/exec-systemcallerrornumber-number.service - test-execute/exec-systemcallfilter-failing.service - test-execute/exec-systemcallfilter-failing2.service - test-execute/exec-systemcallfilter-not-failing.service - test-execute/exec-systemcallfilter-not-failing2.service - test-execute/exec-systemcallfilter-system-user-nfsnobody.service - test-execute/exec-systemcallfilter-system-user-nobody.service - test-execute/exec-systemcallfilter-system-user.service - test-execute/exec-systemcallfilter-with-errno-multi.service - test-execute/exec-systemcallfilter-with-errno-name.service - test-execute/exec-systemcallfilter-with-errno-number.service - test-execute/exec-temporaryfilesystem-options.service - test-execute/exec-temporaryfilesystem-ro.service - test-execute/exec-temporaryfilesystem-rw.service - test-execute/exec-temporaryfilesystem-usr.service - test-execute/exec-umask-0177.service - test-execute/exec-umask-default.service - test-execute/exec-unsetenvironment.service - test-execute/exec-user-nfsnobody.service - test-execute/exec-user-nobody.service - test-execute/exec-user.service - test-execute/exec-workingdirectory.service - test-execute/exec-workingdirectory-trailing-dot.service - test-path/basic.target - test-path/path-changed.path - test-path/path-changed.service - test-path/path-directorynotempty.path - test-path/path-directorynotempty.service - test-path/path-exists.path - test-path/path-exists.service - test-path/path-existsglob.path - test-path/path-existsglob.service - test-path/path-makedirectory.path - test-path/path-makedirectory.service - test-path/path-modified.path - test-path/path-modified.service - test-path/path-mycustomunit.service - test-path/path-service.service - test-path/path-unit.path - test-path/paths.target - test-path/sysinit.target - test-umount/empty.mountinfo - test-umount/example.swaps - test-umount/garbled.mountinfo - test-umount/rhbug-1554943.mountinfo - testsuite.target - timers.target - unit-with-.service.d/20-override.conf - unit-with-multiple-.service.d/20-override.conf - unit-with-multiple-.service.d/30-override.conf - unit-with-multiple-dashes.service - unit-with-multiple-dashes.service.d/10-override.conf - unstoppable.service -'''.split() +testdata_dir = testsdir + '/testdata/' + +install_subdir('journal-data', + install_dir : testdata_dir) +install_subdir('units', + install_dir : testdata_dir) +install_subdir('test-execute', + install_dir : testdata_dir) +install_subdir('test-path', + install_dir : testdata_dir) +install_subdir('test-umount', + install_dir : testdata_dir) +install_subdir('test-network-generator-conversion', + install_dir : testdata_dir) +install_subdir('testsuite-04.units', + install_dir : testdata_dir) +install_subdir('testsuite-06.units', + install_dir : testdata_dir) +install_subdir('testsuite-10.units', + install_dir : testdata_dir) +install_subdir('testsuite-11.units', + install_dir : testdata_dir) +install_subdir('testsuite-16.units', + install_dir : testdata_dir) +install_subdir('testsuite-28.units', + install_dir : testdata_dir) +install_subdir('testsuite-30.units', + install_dir : testdata_dir) + +testsuite08_dir = testdata_dir + '/testsuite-08.units' +install_data('testsuite-08.units/-.mount', + install_dir : testsuite08_dir) +install_data('testsuite-08.units/systemd-remount-fs.service', + install_dir : testsuite08_dir) +meson.add_install_script(meson_make_symlink, + './-.mount', + testsuite08_dir + '/root.mount') +meson.add_install_script(meson_make_symlink, + '../-.mount', + testsuite08_dir + '/local-fs.target.wants/-.mount') if conf.get('ENABLE_RESOLVE') == 1 - test_data_files += ''' - test-resolve/_openpgpkey.fedoraproject.org.pkts - test-resolve/fedoraproject.org.pkts - test-resolve/gandi.net.pkts - test-resolve/google.com.pkts - test-resolve/root.pkts - test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts - test-resolve/teamits.com.pkts - test-resolve/zbyszek@fedoraproject.org.pkts - test-resolve/_443._tcp.fedoraproject.org.pkts - test-resolve/kyhwana.org.pkts - test-resolve/fake-caa.pkts - '''.split() + install_subdir('test-resolve', + install_dir : testdata_dir) endif -if install_tests - foreach file : test_data_files - subdir = file.split('/')[0] - if subdir == file - subdir = '' - endif +install_data('create-busybox-container', + install_mode : 'rwxr-xr-x', + install_dir : testdata_dir) - install_data(file, - install_dir : testsdir + '/testdata/' + subdir) - endforeach -endif +test_network_generator_conversion_sh = find_program('test-network-generator-conversion.sh') ############################################################ @@ -257,6 +77,9 @@ if install_tests install_data('run-unit-tests.py', install_mode : 'rwxr-xr-x', install_dir : testsdir) + install_data('test-network-generator-conversion.sh', + install_mode : 'rwxr-xr-x', + install_dir : testsdir) endif ############################################################ diff --git a/test/run-integration-tests.sh b/test/run-integration-tests.sh index c0a8448a88..bcbbb8b7ed 100755 --- a/test/run-integration-tests.sh +++ b/test/run-integration-tests.sh @@ -4,8 +4,10 @@ set -e BUILD_DIR="$($(dirname "$0")/../tools/find-build-dir.sh)" if [ $# -gt 0 ]; then args="$@" + do_clean=0 else - args="clean setup run clean-again" + args="setup run clean-again" + do_clean=1 fi ninja -C "$BUILD_DIR" @@ -16,6 +18,13 @@ COUNT=0 FAILURES=0 cd "$(dirname "$0")" + +if [ $do_clean = 1 ]; then + for TEST in TEST-??-* ; do + ( set -x ; make -C "$TEST" "BUILD_DIR=$BUILD_DIR" clean ) + done +fi + for TEST in TEST-??-* ; do COUNT=$(($COUNT+1)) @@ -31,6 +40,12 @@ for TEST in TEST-??-* ; do [ "$RESULT" -ne "0" ] && FAILURES=$(($FAILURES+1)) done +if [ $FAILURES -eq 0 -a $do_clean = 1 ]; then + for TEST in TEST-??-* ; do + ( set -x ; make -C "$TEST" "BUILD_DIR=$BUILD_DIR" clean-again ) + done +fi + echo "" for TEST in ${!results[@]}; do diff --git a/test/shutdown.target b/test/shutdown.target deleted file mode 120000 index 1a3c2eec84..0000000000 --- a/test/shutdown.target +++ /dev/null @@ -1 +0,0 @@ -../units/shutdown.target
\ No newline at end of file diff --git a/test/sockets.target b/test/sockets.target deleted file mode 120000 index 8ff86a0775..0000000000 --- a/test/sockets.target +++ /dev/null @@ -1 +0,0 @@ -../units/sockets.target
\ No newline at end of file diff --git a/test/sysinit.target b/test/sysinit.target deleted file mode 120000 index 3301338185..0000000000 --- a/test/sysinit.target +++ /dev/null @@ -1 +0,0 @@ -../units/sysinit.target
\ No newline at end of file diff --git a/test/test-functions b/test/test-functions index 66cd60b559..fbdc92c96e 100644 --- a/test/test-functions +++ b/test/test-functions @@ -14,8 +14,11 @@ NSPAWN_TIMEOUT="${NSPAWN_TIMEOUT:-infinity}" TIMED_OUT= # will be 1 after run_* if *_TIMEOUT is set and test timed out [[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext4}" UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}" -EFI_MOUNT="$(bootctl -x 2>/dev/null || echo /boot)" +EFI_MOUNT="${EFI_MOUNT:-$(bootctl -x 2>/dev/null || echo /boot)}" QEMU_MEM="${QEMU_MEM:-512M}" +IMAGE_NAME=${IMAGE_NAME:-default} +TEST_REQUIRE_INSTALL_TESTS="${TEST_REQUIRE_INSTALL_TESTS:-1}" +LOOPDEV= # Decide if we can (and want to) run QEMU with KVM acceleration. # Check if nested KVM is explicitly enabled (TEST_NESTED_KVM). If not, @@ -39,11 +42,104 @@ PATH_TO_INIT=$ROOTLIBDIR/systemd [ "$SYSTEMD_NSPAWN" ] || SYSTEMD_NSPAWN=$(which -a $BUILD_DIR/systemd-nspawn systemd-nspawn 2>/dev/null | grep '^/' -m1) [ "$JOURNALCTL" ] || JOURNALCTL=$(which -a $BUILD_DIR/journalctl journalctl 2>/dev/null | grep '^/' -m1) -BASICTOOLS="test env sh bash setsid loadkeys setfont login sulogin gzip sleep echo head tail cat mount umount cryptsetup date dmsetup modprobe sed cmp tee rm true false chmod chown ln xargs" -DEBUGTOOLS="df free ls stty ps ln ip route dmesg dhclient mkdir cp ping dhclient strace less grep id tty touch du sort hostname find vi mv" +BASICTOOLS=( + awk + basename + bash + busybox + capsh + cat + chmod + chown + cmp + cryptsetup + cut + date + dd + diff + dirname + dmsetup + echo + env + false + getent + getfacl + grep + gunzip + gzip + head + ionice + ip + ln + loadkeys + login + lz4cat + mkfifo + mktemp + modprobe + mount + mv + nc + nproc + readlink + rev + rm + rmdir + sed + seq + setfont + setsid + sfdisk + sh + sleep + socat + stat + su + sulogin + sysctl + tail + tar + tee + test + touch + tr + true + truncate + umount + uname + unshare + xargs + xzcat +) + +DEBUGTOOLS=( + cp + df + dhclient + dmesg + du + find + free + grep + hostname + id + less + ln + ls + mkdir + ping + ps + route + sort + strace + stty + tty + vi +) STATEDIR="${BUILD_DIR:-.}/test/$(basename $(dirname $(realpath $0)))" STATEFILE="$STATEDIR/.testdir" +IMAGESTATEDIR="$STATEDIR/.." TESTLOG="$STATEDIR/test.log" is_built_with_asan() { @@ -138,6 +234,10 @@ run_qemu() { CONSOLE=ttyS0 + # make sure the initdir is not mounted to avoid concurrent access + cleanup_initdir + umount_loopback + if [[ ! "$KERNEL_BIN" ]]; then if [[ "$LOOKS_LIKE_ARCH" ]]; then KERNEL_BIN=/boot/vmlinuz-linux @@ -184,6 +284,9 @@ run_qemu() { find_qemu_bin || return 1 + # Umount initdir to avoid concurrent access to the filesystem + _umount_dir $initdir + local _cgroup_args if [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" ]]; then _cgroup_args="systemd.unified_cgroup_hierarchy=yes" @@ -198,14 +301,18 @@ run_qemu() { if [[ "$LOOKS_LIKE_SUSE" ]]; then PARAMS+="rd.hostonly=0" - elif [[ "$LOOKS_LIKE_ARCH" ]]; then - PARAMS+="rw" + fi + + local _end + if [[ ! "$INTERACTIVE_DEBUG" ]]; then + _end="systemd.wants=end.service" else - PARAMS+="ro" + _end="" fi KERNEL_APPEND="$PARAMS \ root=/dev/sda1 \ +rw \ raid=noautodetect \ rd.luks=0 \ loglevel=2 \ @@ -213,6 +320,9 @@ init=$PATH_TO_INIT \ console=$CONSOLE \ selinux=0 \ $_cgroup_args \ +SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/testsuite-$1.units:/usr/lib/systemd/tests/testdata/units: \ +systemd.unit=testsuite.target \ +systemd.wants=testsuite-$1.service ${_end} \ $KERNEL_APPEND \ " @@ -221,7 +331,7 @@ $KERNEL_APPEND \ -m $QEMU_MEM \ -nographic \ -kernel $KERNEL_BIN \ --drive format=raw,cache=unsafe,file=${TESTDIR}/rootdisk.img \ +-drive format=raw,cache=unsafe,file=${IMAGESTATEDIR}/${IMAGE_NAME}.img \ $QEMU_OPTIONS \ " @@ -253,24 +363,41 @@ $QEMU_OPTIONS \ run_nspawn() { [[ -d /run/systemd/system ]] || return 1 - local _nspawn_cmd="$SYSTEMD_NSPAWN $NSPAWN_ARGUMENTS --register=no --kill-signal=SIGKILL --directory=$TESTDIR/$1 $PATH_TO_INIT $KERNEL_APPEND" + local _nspawn_cmd=( + --register=no + --kill-signal=SIGKILL + --directory=$1 + --setenv=SYSTEMD_UNIT_PATH=/usr/lib/systemd/tests/testdata/testsuite-$2.units:/usr/lib/systemd/tests/testdata/units: + $PATH_TO_INIT + $KERNEL_APPEND + systemd.unit=testsuite.target + systemd.wants=testsuite-$2.service + ) + + if [[ ! "$INTERACTIVE_DEBUG" ]]; then + _nspawn_cmd+=( systemd.wants=end.service ) + fi + + local _nspawn_pre if [[ "$NSPAWN_TIMEOUT" != "infinity" ]]; then - _nspawn_cmd="timeout --foreground $NSPAWN_TIMEOUT $_nspawn_cmd" + _nspawn_pre=(timeout --foreground $NSPAWN_TIMEOUT) + else + _nspawn_pre=() fi if [[ "$UNIFIED_CGROUP_HIERARCHY" = "hybrid" ]]; then dwarn "nspawn doesn't support SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=hybrid, skipping" exit elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" || "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then - _nspawn_cmd="env SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY $_nspawn_cmd" + _nspawn_pre=("${nspawn_pre[@]}" env SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY) elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "default" ]]; then - _nspawn_cmd="env --unset=UNIFIED_CGROUP_HIERARCHY --unset=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY $_nspawn_cmd" + _nspawn_pre=("${nspawn_pre[@]}" env --unset=UNIFIED_CGROUP_HIERARCHY --unset=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY) else dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]" exit 1 fi - (set -x; $_nspawn_cmd) + (set -x; "${_nspawn_pre[@]}" "$SYSTEMD_NSPAWN" $NSPAWN_ARGUMENTS "${_nspawn_cmd[@]}") rc=$? if [ "$rc" = 124 ] && [ "$NSPAWN_TIMEOUT" != "infinity" ]; then derror "test timed out after $NSPAWN_TIMEOUT s" @@ -288,6 +415,7 @@ setup_basic_environment() { install_systemd install_missing_libraries install_config_files + install_zoneinfo create_rc_local install_basic_tools install_libnss @@ -301,6 +429,8 @@ setup_basic_environment() { install_plymouth install_debug_tools install_ld_so_conf + install_testuser + has_user_dbus_socket && install_user_dbus setup_selinux strip_binaries install_depmod_files @@ -326,27 +456,9 @@ setup_selinux() { exit 1 fi - cat <<EOF >$initdir/etc/systemd/system/autorelabel.service -[Unit] -Description=Relabel all filesystems -DefaultDependencies=no -Requires=local-fs.target -Conflicts=shutdown.target -After=local-fs.target -Before=sysinit.target shutdown.target -ConditionSecurity=selinux -ConditionPathExists=|/.autorelabel - -[Service] -ExecStart=/bin/sh -x -c 'echo 0 >/sys/fs/selinux/enforce && fixfiles -f -F relabel && rm /.autorelabel && systemctl --force reboot' -Type=oneshot -TimeoutSec=0 -RemainAfterExit=yes -EOF - touch $initdir/.autorelabel - mkdir -p $initdir/etc/systemd/system/basic.target.wants - ln -fs autorelabel.service $initdir/etc/systemd/system/basic.target.wants/autorelabel.service + mkdir -p $initdir/usr/lib/systemd/tests/testdata/units/basic.target.wants + ln -sf ../autorelabel.service $initdir/usr/lib/systemd/tests/testdata/units/basic.target.wants/ dracut_install $_fixfiles_tools dracut_install fixfiles @@ -475,7 +587,7 @@ unset_ld_preload() { } unset_ld_preload systemd-remount-fs -unset_ld_preload testsuite +unset_ld_preload testsuite- export ASAN_OPTIONS=\$DEFAULT_ASAN_OPTIONS:log_path=/systemd.asan.log UBSAN_OPTIONS=\$DEFAULT_UBSAN_OPTIONS exec $ROOTLIBDIR/systemd "\$@" @@ -530,7 +642,7 @@ install_systemd() { # and it could fill the available space strip_binaries - [[ "$LOOKS_LIKE_SUSE" ]] && setup_suse + [[ "$LOOKS_LIKE_SUSE" ]] && setup_suse # enable debug logging in PID1 echo LogLevel=debug >> $initdir/etc/systemd/system.conf @@ -556,17 +668,37 @@ install_missing_libraries() { done } +cleanup_loopdev() { + if [ -n "${LOOPDEV}" ]; then + ddebug "losetup -d $LOOPDEV" + losetup -d "${LOOPDEV}" + fi +} + +trap cleanup_loopdev EXIT + create_empty_image() { + if [ -z "$IMAGE_NAME" ]; then + echo "create_empty_image: \$IMAGE_NAME not set" + exit 1 + fi + local _size=500 if [[ "$STRIP_BINARIES" = "no" ]]; then _size=$((4*_size)) fi - rm -f "$TESTDIR/rootdisk.img" + + image="${TESTDIR}/${IMAGE_NAME}.img" + public="$IMAGESTATEDIR/${IMAGE_NAME}.img" + echo "Setting up $public (${_size} MB)" + rm -f "$image" "$public" + # Create the blank file to use as a root filesystem - truncate -s "${_size}M" "$TESTDIR/rootdisk.img" - LOOPDEV=$(losetup --show -P -f $TESTDIR/rootdisk.img) + truncate -s "${_size}M" "$image" + ln -vs "$(realpath $image)" "$public" + + LOOPDEV=$(losetup --show -P -f "$public") [ -b "$LOOPDEV" ] || return 1 - echo "LOOPDEV=$LOOPDEV" >> $STATEFILE sfdisk "$LOOPDEV" <<EOF ,$((_size-50))M , @@ -574,20 +706,50 @@ EOF udevadm settle - local _label="-L systemd" + local _label="-L systemd.${name}" # mkfs.reiserfs doesn't know -L. so, use --label instead - [[ "$FSTYPE" == "reiserfs" ]] && _label="--label systemd" - if ! mkfs -t "${FSTYPE}" ${_label} "${LOOPDEV}p1" -q; then + [[ "$FSTYPE" == "reiserfs" ]] && _label="--label systemd.${name}" + mkfs -t "${FSTYPE}" ${_label} "${LOOPDEV}p1" -q; ret=$? + if [ $ret -ne 0 ] ; then dfatal "Failed to mkfs -t ${FSTYPE}" exit 1 fi } +mount_initdir() { + if [ -z "${LOOPDEV}" ]; then + image="${IMAGESTATEDIR}/${IMAGE_NAME}.img" + LOOPDEV=$(losetup --show -P -f "$image") + [ -b "$LOOPDEV" ] || return 1 + + udevadm settle + fi + + if ! mountpoint -q $initdir; then + mkdir -p $initdir + mount ${LOOPDEV}p1 $initdir + TEST_SETUP_CLEANUP_ROOTDIR=1 + fi +} + +cleanup_initdir() { + # only umount if create_empty_image_rootdir() was called to mount it + [[ -z $TEST_SETUP_CLEANUP_ROOTDIR ]] || _umount_dir $initdir +} + +umount_loopback() { + # unmount the loopback device from all places. Otherwise we risk file + # system corruption. + image="${IMAGESTATEDIR}/${IMAGE_NAME}.img" + for device in $(losetup -l | awk '$6=="'"$image"'" {print $1}'); do + ddebug "Unmounting all uses of $device" + mount | awk '/^'"${device}"'p/{print $1}' | xargs --no-run-if-empty umount -v + done +} + create_empty_image_rootdir() { create_empty_image - mkdir -p $initdir - mount ${LOOPDEV}p1 $initdir - TEST_SETUP_CLEANUP_ROOTDIR=1 + mount_initdir } check_asan_reports() { @@ -632,27 +794,29 @@ check_result_nspawn() { local ret=1 local journald_report="" local pids="" - [[ -e $TESTDIR/$1/testok ]] && ret=0 - [[ -f $TESTDIR/$1/failed ]] && cp -a $TESTDIR/$1/failed $TESTDIR - cp -a $TESTDIR/$1/var/log/journal $TESTDIR + [[ -e $1/testok ]] && ret=0 + [[ -f $1/failed ]] && cp -a $1/failed $TESTDIR + cp -a $1/var/log/journal $TESTDIR + rm -r $1/var/log/journal/* [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed ls -l $TESTDIR/journal/*/*.journal test -s $TESTDIR/failed && ret=$(($ret+1)) [ -n "$TIMED_OUT" ] && ret=$(($ret+1)) - check_asan_reports "$TESTDIR/$1" || ret=$(($ret+1)) + check_asan_reports "$1" || ret=$(($ret+1)) + _umount_dir $initdir return $ret } # can be overridden in specific test check_result_qemu() { local ret=1 - mkdir -p $initdir - mount ${LOOPDEV}p1 $initdir + mount_initdir [[ -e $initdir/testok ]] && ret=0 [[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR cp -a $initdir/var/log/journal $TESTDIR + rm -r $initdir/var/log/journal/* check_asan_reports "$initdir" || ret=$(($ret+1)) - umount $initdir + _umount_dir $initdir [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed ls -l $TESTDIR/journal/*/*.journal test -s $TESTDIR/failed && ret=$(($ret+1)) @@ -727,6 +891,17 @@ install_ld_so_conf() { ldconfig -r "$initdir" } +install_testuser() { + # create unprivileged user for user manager tests + mkdir -p $initdir/etc/sysusers.d + cat >$initdir/etc/sysusers.d/testuser.conf <<EOF +u testuser 4711 "Test User" /home/testuser +EOF + + mkdir -p $initdir/home/testuser -m 0700 + chown 4711:4711 $initdir/home/testuser +} + install_config_files() { inst /etc/sysconfig/init || : inst /etc/passwd @@ -741,29 +916,20 @@ install_config_files() { # we want an empty environment > $initdir/etc/environment > $initdir/etc/machine-id + # set the hostname echo systemd-testsuite > $initdir/etc/hostname - # fstab - if [[ "$LOOKS_LIKE_SUSE" ]]; then - ROOTMOUNT="/dev/sda1 / ${FSTYPE} rw 0 1" - else - ROOTMOUNT="LABEL=systemd / ${FSTYPE} rw 0 1" - fi - - cat >$initdir/etc/fstab <<EOF -$ROOTMOUNT -EOF } install_basic_tools() { - [[ $BASICTOOLS ]] && dracut_install $BASICTOOLS + dracut_install "${BASICTOOLS[@]}" dracut_install -o sushell # in Debian ldconfig is just a shell script wrapper around ldconfig.real dracut_install -o ldconfig.real } install_debug_tools() { - [[ $DEBUGTOOLS ]] && dracut_install $DEBUGTOOLS + dracut_install "${DEBUGTOOLS[@]}" if [[ $INTERACTIVE_DEBUG ]]; then # Set default TERM from vt220 to linux, so at least basic key shortcuts work @@ -810,6 +976,19 @@ install_dbus() { | while read file; do inst $file done + + # setup policy for Type=dbus test + mkdir -p $initdir/etc/dbus-1/system.d + cat > $initdir/etc/dbus-1/system.d/systemd.test.ExecStopPost.conf <<EOF +<?xml version="1.0"?> +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <policy user="root"> + <allow own="systemd.test.ExecStopPost"/> + </policy> +</busconfig> +EOF } install_user_dbus() { @@ -885,10 +1064,16 @@ install_keymaps() { } install_zoneinfo() { - for i in /usr/share/zoneinfo/{,*/,*/*/}*; do - [[ -f $i ]] || continue - inst $i - done + inst_any /usr/share/zoneinfo/Asia/Seoul + inst_any /usr/share/zoneinfo/Asia/Vladivostok + inst_any /usr/share/zoneinfo/Australia/Sydney + inst_any /usr/share/zoneinfo/Europe/Berlin + inst_any /usr/share/zoneinfo/Europe/Kiev + inst_any /usr/share/zoneinfo/Pacific/Auckland + inst_any /usr/share/zoneinfo/Pacific/Honolulu + inst_any /usr/share/zoneinfo/CET + inst_any /usr/share/zoneinfo/EET + inst_any /usr/share/zoneinfo/UTC } install_fonts() { @@ -916,40 +1101,17 @@ has_user_dbus_socket() { fi } -enable_user_manager() { - has_user_dbus_socket || return 0 - - local _userid - [[ $# -gt 0 ]] || set -- nobody - mkdir -p "$initdir/var/lib/systemd/linger" - for _userid; do - touch "$initdir/var/lib/systemd/linger/$_userid" - done - dracut_install su - install_user_dbus -} - -setup_testsuite() { - cp $TEST_BASE_DIR/testsuite.target $initdir/etc/systemd/system/ - cp $TEST_BASE_DIR/end.service $initdir/etc/systemd/system/ +setup_nspawn_root() { + if [ -z "${initdir}" ]; then + dfatal "\$initdir not defined" + exit 1 + fi - mkdir -p $initdir/etc/systemd/system/testsuite.target.wants - ln -fs $TEST_BASE_DIR/testsuite.service $initdir/etc/systemd/system/testsuite.target.wants/testsuite.service - # Don't shutdown the machine after running the test when INTERACTIVE_DEBUG is set - [[ -z $INTERACTIVE_DEBUG ]] && ln -fs $TEST_BASE_DIR/end.service $initdir/etc/systemd/system/testsuite.target.wants/end.service + rm -rf "$TESTDIR/unprivileged-nspawn-root" - # make the testsuite the default target - ln -fs testsuite.target $initdir/etc/systemd/system/default.target -} - -setup_nspawn_root() { - rm -fr $TESTDIR/nspawn-root - ddebug "cp -ar $initdir $TESTDIR/nspawn-root" - cp -ar $initdir $TESTDIR/nspawn-root - # we don't mount in the nspawn root - rm -f $TESTDIR/nspawn-root/etc/fstab if [[ "$RUN_IN_UNPRIVILEGED_CONTAINER" = "yes" ]]; then - cp -ar $TESTDIR/nspawn-root $TESTDIR/unprivileged-nspawn-root + ddebug "cp -ar $initdir $TESTDIR/unprivileged-nspawn-root" + cp -ar $initdir $TESTDIR/unprivileged-nspawn-root fi } @@ -1005,7 +1167,10 @@ inst_libs() { } import_testdir() { + # make sure we don't get a stale LOOPDEV value from old times + __LOOPDEV=$LOOPDEV [[ -e $STATEFILE ]] && . $STATEFILE + LOOPDEV=$__LOOPDEV if [[ ! -d "$TESTDIR" ]]; then if [[ -z "$TESTDIR" ]]; then TESTDIR=$(mktemp --tmpdir=/var/tmp -d -t systemd-test.XXXXXX) @@ -1013,7 +1178,9 @@ import_testdir() { mkdir -p "$TESTDIR" fi - echo "TESTDIR=\"$TESTDIR\"" > $STATEFILE + cat >$STATEFILE<<EOF +TESTDIR="$TESTDIR" +EOF export TESTDIR fi } @@ -1755,14 +1922,9 @@ _umount_dir() { fi } -_test_setup_cleanup() { - # only umount if create_empty_image_rootdir() was called to mount it - [[ -z $TEST_SETUP_CLEANUP_ROOTDIR ]] || _umount_dir $initdir -} - # can be overridden in specific test test_setup_cleanup() { - _test_setup_cleanup + cleanup_initdir } _test_cleanup() { @@ -1770,12 +1932,9 @@ _test_cleanup() { ( set +e _umount_dir $initdir - if [[ $LOOPDEV && -b $LOOPDEV ]]; then - ddebug "losetup -d $LOOPDEV" - losetup -d $LOOPDEV - fi - rm -fr "$TESTDIR" - rm -f "$STATEFILE" + rm -vf "${IMAGESTATEDIR}/${IMAGE_NAME}.img" + rm -vfr "$TESTDIR" + rm -vf "$STATEFILE" ) || : } @@ -1784,24 +1943,70 @@ test_cleanup() { _test_cleanup } +test_cleanup_again() { + [ -n "$TESTDIR" ] || return + rm -rf "$TESTDIR/unprivileged-nspawn-root" + _umount_dir $initdir +} + +test_create_image() { + create_empty_image_rootdir + + # Create what will eventually be our root filesystem onto an overlay + ( + LOG_LEVEL=5 + setup_basic_environment + mask_supporting_services + ) +} + +test_setup() { + if [ ${TEST_REQUIRE_INSTALL_TESTS} -ne 0 ] && \ + type -P meson >/dev/null && \ + [[ "$(meson configure $BUILD_DIR | grep install-tests | awk '{ print $2 }')" != "true" ]]; then + dfatal "$BUILD_DIR needs to be built with -Dinstall-tests=true" + exit 1 + fi + + image="${TESTDIR}/${IMAGE_NAME}.img" + public="${IMAGESTATEDIR}/${IMAGE_NAME}.img" + if [ -e "$image" ]; then + echo "Reusing existing image $PWD/$image → $(realpath $image)" + mount_initdir + elif [ -e "$public" ]; then + echo "Reusing existing cached image $PWD/$public → $(realpath $public)" + ln -s "$(realpath $public)" "$image" + mount_initdir + else + test_create_image + fi + + setup_nspawn_root +} + test_run() { + mount_initdir + rm -f "$initdir"/{testok,failed,skipped} + if [ -z "$TEST_NO_QEMU" ]; then - if run_qemu; then - check_result_qemu || return 1 + if run_qemu "$1"; then + check_result_qemu || { echo "QEMU test failed"; return 1; } else dwarn "can't run QEMU, skipping" fi fi if [ -z "$TEST_NO_NSPAWN" ]; then - if run_nspawn "nspawn-root"; then - check_result_nspawn "nspawn-root" || return 1 + mount_initdir + if run_nspawn "$initdir" "$1"; then + check_result_nspawn "$initdir" || { echo "nspawn-root test failed"; return 1; } else dwarn "can't run systemd-nspawn, skipping" fi if [[ "$RUN_IN_UNPRIVILEGED_CONTAINER" = "yes" ]]; then - if NSPAWN_ARGUMENTS="-U --private-network $NSPAWN_ARGUMENTS" run_nspawn "unprivileged-nspawn-root"; then - check_result_nspawn "unprivileged-nspawn-root" || return 1 + dir="$TESTDIR/unprivileged-nspawn-root" + if NSPAWN_ARGUMENTS="-U --private-network $NSPAWN_ARGUMENTS" run_nspawn "$dir" "$1"; then + check_result_nspawn "$dir" || { echo "unprivileged-nspawn-root test failed"; return 1; } else dwarn "can't run systemd-nspawn, skipping" fi @@ -1830,34 +2035,40 @@ do_test() { import_testdir import_initdir + testname="$(basename $PWD)" + while (($# > 0)); do case $1 in --run) - echo "TEST RUN: $TEST_DESCRIPTION" - test_run + echo "${testname} RUN: $TEST_DESCRIPTION" + test_run "$2" ret=$? if (( $ret == 0 )); then - echo "TEST RUN: $TEST_DESCRIPTION [OK]" + echo "${testname} RUN: $TEST_DESCRIPTION [OK]" else - echo "TEST RUN: $TEST_DESCRIPTION [FAILED]" + echo "${testname} RUN: $TEST_DESCRIPTION [FAILED]" fi exit $ret;; --setup) - echo "TEST SETUP: $TEST_DESCRIPTION" + echo "${testname} SETUP: $TEST_DESCRIPTION" test_setup test_setup_cleanup ;; --clean) - echo "TEST CLEANUP: $TEST_DESCRIPTION" + echo "${testname} CLEANUP: $TEST_DESCRIPTION" test_cleanup ;; + --clean-again) + echo "${testname} CLEANUP AGAIN: $TEST_DESCRIPTION" + test_cleanup_again + ;; --all) ret=0 - echo -n "TEST: $TEST_DESCRIPTION " + echo -n "${testname}: $TEST_DESCRIPTION " ( test_setup test_setup_cleanup - test_run + test_run "$2" ) </dev/null >"$TESTLOG" 2>&1 || ret=$? test_cleanup if [ $ret -eq 0 ]; then diff --git a/test/test-network-generator-conversion.sh b/test/test-network-generator-conversion.sh new file mode 100755 index 0000000000..d0d0834518 --- /dev/null +++ b/test/test-network-generator-conversion.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -ex + +if [[ -n "$1" ]]; then + generator=$1 +elif [[ -x /usr/lib/systemd/systemd-network-generator ]]; then + generator=/usr/lib/systemd/systemd-network-generator +elif [[ -x /lib/systemd/systemd-network-generator ]]; then + generator=/lib/systemd/systemd-network-generator +else + exit 1 +fi + +src="$(dirname "$0")/testdata/test-network-generator-conversion" + +for f in "$src"/test-*.input; do + echo "*** Running $f" + + ( + out=$(mktemp --directory) + trap "rm -rf '$out'" EXIT INT QUIT PIPE + + $generator --root "$out" -- $(cat $f) + + if ! diff -u "$out"/run/systemd/network ${f%.input}.expected; then + echo "**** Unexpected output for $f" + exit 1 + fi + ) || exit 1 +done diff --git a/test/TEST-35-NETWORK-GENERATOR/test-01-dhcp.expected/91-default.network b/test/test-network-generator-conversion/test-01-dhcp.expected/91-default.network index e42ce1e311..e42ce1e311 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-01-dhcp.expected/91-default.network +++ b/test/test-network-generator-conversion/test-01-dhcp.expected/91-default.network diff --git a/test/TEST-35-NETWORK-GENERATOR/test-01-dhcp.input b/test/test-network-generator-conversion/test-01-dhcp.input index e55893e756..e55893e756 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-01-dhcp.input +++ b/test/test-network-generator-conversion/test-01-dhcp.input diff --git a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-bridge99.netdev b/test/test-network-generator-conversion/test-02-bridge.expected/90-bridge99.netdev index 97c22485b7..97c22485b7 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-bridge99.netdev +++ b/test/test-network-generator-conversion/test-02-bridge.expected/90-bridge99.netdev diff --git a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-bridge99.network b/test/test-network-generator-conversion/test-02-bridge.expected/90-bridge99.network index f8d19baaea..f8d19baaea 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-bridge99.network +++ b/test/test-network-generator-conversion/test-02-bridge.expected/90-bridge99.network diff --git a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-eth0.network b/test/test-network-generator-conversion/test-02-bridge.expected/90-eth0.network index 8842b57921..8842b57921 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-eth0.network +++ b/test/test-network-generator-conversion/test-02-bridge.expected/90-eth0.network diff --git a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-eth1.network b/test/test-network-generator-conversion/test-02-bridge.expected/90-eth1.network index feff4f5ba8..feff4f5ba8 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.expected/90-eth1.network +++ b/test/test-network-generator-conversion/test-02-bridge.expected/90-eth1.network diff --git a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.input b/test/test-network-generator-conversion/test-02-bridge.input index 0c863fc356..0c863fc356 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-02-bridge.input +++ b/test/test-network-generator-conversion/test-02-bridge.input diff --git a/test/TEST-35-NETWORK-GENERATOR/test-03-issue-14319.expected/90-enp3s0.network b/test/test-network-generator-conversion/test-03-issue-14319.expected/90-enp3s0.network index 28ccfdd9b0..28ccfdd9b0 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-03-issue-14319.expected/90-enp3s0.network +++ b/test/test-network-generator-conversion/test-03-issue-14319.expected/90-enp3s0.network diff --git a/test/TEST-35-NETWORK-GENERATOR/test-03-issue-14319.input b/test/test-network-generator-conversion/test-03-issue-14319.input index 3be752067b..3be752067b 100644 --- a/test/TEST-35-NETWORK-GENERATOR/test-03-issue-14319.input +++ b/test/test-network-generator-conversion/test-03-issue-14319.input diff --git a/test/test-path/basic.target b/test/test-path/basic.target index a882b72cc9..4f44292249 120000..100644 --- a/test/test-path/basic.target +++ b/test/test-path/basic.target @@ -1 +1,22 @@ -../../units/basic.target
\ No newline at end of file +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Basic System +Documentation=man:systemd.special(7) +Requires=sysinit.target +Wants=sockets.target timers.target paths.target slices.target +After=sysinit.target sockets.target paths.target slices.target tmp.mount + +# We support /var, /tmp, /var/tmp, being on NFS, but we don't pull in +# remote-fs.target by default, hence pull them in explicitly here. Note that we +# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as +# we support that unit being masked, and this should not be considered an error. +RequiresMountsFor=/var /var/tmp +Wants=tmp.mount diff --git a/test/test-path/path-changed.service b/test/test-path/path-changed.service index 8bdf178830..f8499ec619 120000..100644 --- a/test/test-path/path-changed.service +++ b/test/test-path/path-changed.service @@ -1 +1,6 @@ -path-service.service
\ No newline at end of file +[Unit] +Description=Service Test for Path units + +[Service] +ExecStart=/bin/true +Type=oneshot diff --git a/test/test-path/path-directorynotempty.service b/test/test-path/path-directorynotempty.service index 8bdf178830..f8499ec619 120000..100644 --- a/test/test-path/path-directorynotempty.service +++ b/test/test-path/path-directorynotempty.service @@ -1 +1,6 @@ -path-service.service
\ No newline at end of file +[Unit] +Description=Service Test for Path units + +[Service] +ExecStart=/bin/true +Type=oneshot diff --git a/test/test-path/path-exists.service b/test/test-path/path-exists.service index 8bdf178830..f8499ec619 120000..100644 --- a/test/test-path/path-exists.service +++ b/test/test-path/path-exists.service @@ -1 +1,6 @@ -path-service.service
\ No newline at end of file +[Unit] +Description=Service Test for Path units + +[Service] +ExecStart=/bin/true +Type=oneshot diff --git a/test/test-path/path-existsglob.service b/test/test-path/path-existsglob.service index 8bdf178830..f8499ec619 120000..100644 --- a/test/test-path/path-existsglob.service +++ b/test/test-path/path-existsglob.service @@ -1 +1,6 @@ -path-service.service
\ No newline at end of file +[Unit] +Description=Service Test for Path units + +[Service] +ExecStart=/bin/true +Type=oneshot diff --git a/test/test-path/path-makedirectory.service b/test/test-path/path-makedirectory.service index 8bdf178830..f8499ec619 120000..100644 --- a/test/test-path/path-makedirectory.service +++ b/test/test-path/path-makedirectory.service @@ -1 +1,6 @@ -path-service.service
\ No newline at end of file +[Unit] +Description=Service Test for Path units + +[Service] +ExecStart=/bin/true +Type=oneshot diff --git a/test/test-path/path-modified.service b/test/test-path/path-modified.service index 8bdf178830..f8499ec619 120000..100644 --- a/test/test-path/path-modified.service +++ b/test/test-path/path-modified.service @@ -1 +1,6 @@ -path-service.service
\ No newline at end of file +[Unit] +Description=Service Test for Path units + +[Service] +ExecStart=/bin/true +Type=oneshot diff --git a/test/test-path/paths.target b/test/test-path/paths.target index b402796cb9..9b6ed1c13f 120000..100644 --- a/test/test-path/paths.target +++ b/test/test-path/paths.target @@ -1 +1,12 @@ -../../units/paths.target
\ No newline at end of file +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Paths +Documentation=man:systemd.special(7) diff --git a/test/test-path/sysinit.target b/test/test-path/sysinit.target index 9d10e5b2e2..b6c16a1412 120000..100644 --- a/test/test-path/sysinit.target +++ b/test/test-path/sysinit.target @@ -1 +1,15 @@ -../../units/sysinit.target
\ No newline at end of file +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=System Initialization +Documentation=man:systemd.special(7) +Conflicts=emergency.service emergency.target +Wants=local-fs.target swap.target +After=local-fs.target swap.target emergency.service emergency.target diff --git a/test/testdata b/test/testdata new file mode 120000 index 0000000000..945c9b46d6 --- /dev/null +++ b/test/testdata @@ -0,0 +1 @@ +.
\ No newline at end of file diff --git a/test/testsuite-04.units/forever-print-hola.service b/test/testsuite-04.units/forever-print-hola.service new file mode 100644 index 0000000000..a0dc095688 --- /dev/null +++ b/test/testsuite-04.units/forever-print-hola.service @@ -0,0 +1,6 @@ +[Unit] +Description=ForeverPrintHola service + +[Service] +Type=simple +ExecStart=sh -x -c 'while :; do printf "Hola\n" || touch /i-lose-my-logs; sleep 1; done' diff --git a/test/testsuite-06.units/hola.service b/test/testsuite-06.units/hola.service new file mode 100644 index 0000000000..5dc633206a --- /dev/null +++ b/test/testsuite-06.units/hola.service @@ -0,0 +1,6 @@ +[Service] +Type=oneshot +ExecStart=/bin/echo Start Hola +ExecReload=/bin/echo Reload Hola +ExecStop=/bin/echo Stop Hola +RemainAfterExit=yes diff --git a/test/testsuite-06.units/load-systemd-test-module.service b/test/testsuite-06.units/load-systemd-test-module.service new file mode 100644 index 0000000000..323a76c68d --- /dev/null +++ b/test/testsuite-06.units/load-systemd-test-module.service @@ -0,0 +1,14 @@ +[Unit] +Description=Load systemd-test module +DefaultDependencies=no +Requires=local-fs.target +Conflicts=shutdown.target +After=local-fs.target +Before=sysinit.target shutdown.target autorelabel.service +ConditionSecurity=selinux + +[Service] +ExecStart=sh -x -c 'echo 0 >/sys/fs/selinux/enforce && cd /systemd-test-module && make -f /usr/share/selinux/devel/Makefile load' +Type=oneshot +TimeoutSec=0 +RemainAfterExit=yes diff --git a/test/testsuite-08.units/-.mount b/test/testsuite-08.units/-.mount new file mode 100644 index 0000000000..af4e219759 --- /dev/null +++ b/test/testsuite-08.units/-.mount @@ -0,0 +1,12 @@ +[Unit] +Before=local-fs.target + +[Mount] +What=/dev/sda1 +Where=/ +Type=ext4 +Options=errors=remount-ro,noatime + +[Install] +WantedBy=local-fs.target +Alias=root.mount diff --git a/test/testsuite-08.units/local-fs.target.wants/-.mount b/test/testsuite-08.units/local-fs.target.wants/-.mount new file mode 120000 index 0000000000..5566fceaa3 --- /dev/null +++ b/test/testsuite-08.units/local-fs.target.wants/-.mount @@ -0,0 +1 @@ +../-.mount
\ No newline at end of file diff --git a/test/testsuite-08.units/root.mount b/test/testsuite-08.units/root.mount new file mode 120000 index 0000000000..fd8c47d1b0 --- /dev/null +++ b/test/testsuite-08.units/root.mount @@ -0,0 +1 @@ +-.mount
\ No newline at end of file diff --git a/test/testsuite-08.units/systemd-remount-fs.service b/test/testsuite-08.units/systemd-remount-fs.service new file mode 100644 index 0000000000..398d612749 --- /dev/null +++ b/test/testsuite-08.units/systemd-remount-fs.service @@ -0,0 +1,11 @@ +[Unit] +DefaultDependencies=no +Conflicts=shutdown.target +After=systemd-fsck-root.service +Before=local-fs-pre.target local-fs.target shutdown.target +Wants=local-fs-pre.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/systemctl reload / diff --git a/test/testsuite-10.units/test10.service b/test/testsuite-10.units/test10.service new file mode 100644 index 0000000000..d0be786b01 --- /dev/null +++ b/test/testsuite-10.units/test10.service @@ -0,0 +1,6 @@ +[Unit] +Requires=test10.socket +ConditionPathExistsGlob=/tmp/nonexistent + +[Service] +ExecStart=true diff --git a/test/testsuite-10.units/test10.socket b/test/testsuite-10.units/test10.socket new file mode 100644 index 0000000000..9cceebbb8e --- /dev/null +++ b/test/testsuite-10.units/test10.socket @@ -0,0 +1,2 @@ +[Socket] +ListenStream=/run/test.ctl diff --git a/test/testsuite-11.units/fail-on-restart.service b/test/testsuite-11.units/fail-on-restart.service new file mode 100644 index 0000000000..9264f151f3 --- /dev/null +++ b/test/testsuite-11.units/fail-on-restart.service @@ -0,0 +1,9 @@ +[Unit] +Description=Fail on restart +StartLimitIntervalSec=1m +StartLimitBurst=3 + +[Service] +Type=simple +ExecStart=false +Restart=always diff --git a/test/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh b/test/testsuite-16.units/extend-timeout.sh index 40bf046dcd..ed1af8afeb 100755 --- a/test/TEST-16-EXTEND-TIMEOUT/extend_timeout_test_service.sh +++ b/test/testsuite-16.units/extend-timeout.sh @@ -4,23 +4,15 @@ set -e set -o pipefail # sleep interval (seconds) -sleep_interval=1 +: ${sleep_interval:=1} # extend_timeout_interval second(s) -extend_timeout_interval=1 +: ${extend_timeout_interval:=1} # number of sleep_intervals before READY=1 -start_intervals=10 +: ${start_intervals:=10} # number of sleep_intervals before exiting -stop_intervals=10 +: ${stop_intervals:=10} # run intervals, number of sleep_intervals to run -run_intervals=7 -# service name -SERVICE=unknown - -while [ $# -gt 0 ]; -do - eval ${1%=*}=${1#*=} - shift -done +: ${run_intervals:=7} # We convert to usec extend_timeout_interval=$(( $extend_timeout_interval * 1000000 )) diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service b/test/testsuite-16.units/fail-runtime.service index e0b9f6a70b..baa655f2f1 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-runtime.service +++ b/test/testsuite-16.units/fail-runtime.service @@ -1,13 +1,12 @@ - [Unit] Description=Testsuite: Fail Runtime (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after RuntimeSecMax.) [Service] - # EXTEND_TIMEOUT_USEC on runtime start (0) and 7 seconds after. Systemd will expect one at 7+5 (extend_timeout_interval) # seconds this won't happen until 7 + 7 (sleep interval) seconds. Therefore timeout at 12 seconds. Type=notify TimeoutStartSec=4 TimeoutStopSec=4 RuntimeMaxSec=10 -ExecStart=/extend_timeout_test_service.sh SERVICE=fail_runtime extend_timeout_interval=5 sleep_interval=7 start_intervals=0 run_intervals=2 stop_intervals=0 +Environment=SERVICE=fail_runtime extend_timeout_interval=5 sleep_interval=7 start_intervals=0 run_intervals=2 stop_intervals=0 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service b/test/testsuite-16.units/fail-start.service index c3fcf23dc0..882900440f 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-start.service +++ b/test/testsuite-16.units/fail-start.service @@ -1,4 +1,3 @@ - [Unit] Description=Testsuite: Fail Start (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after TimeoutStartSec.) @@ -10,4 +9,5 @@ Type=notify TimeoutStartSec=10 TimeoutStopSec=4 RuntimeMaxSec=4 -ExecStart=/extend_timeout_test_service.sh SERVICE=fail_start extend_timeout_interval=5 sleep_interval=7 start_intervals=2 run_intervals=0 stop_intervals=0 +Environment=SERVICE=fail_start extend_timeout_interval=5 sleep_interval=7 start_intervals=2 run_intervals=0 stop_intervals=0 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service b/test/testsuite-16.units/fail-stop.service index ce76d10db7..cdea2a9a2d 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-fail-stop.service +++ b/test/testsuite-16.units/fail-stop.service @@ -1,16 +1,15 @@ - [Unit] Description=Testsuite: Fail Stop (EXTEND_TIMEOUT_USEC Didn't occur in sufficient time after TimeoutStopSec.) [Service] - # EXTEND_TIMEOUT_USEC on stop (0) and 7 seconds after. Systemd will expect one at 7+5 (extend_timeout_interval) # seconds this won't happen until 7 + 7 (sleep interval) seconds. Therefore timeout at 12 seconds. Type=notify TimeoutStartSec=4 TimeoutStopSec=10 RuntimeMaxSec=4 -ExecStart=/extend_timeout_test_service.sh SERVICE=fail_stop extend_timeout_interval=5 sleep_interval=7 start_intervals=0 run_intervals=0 stop_intervals=2 +Environment=SERVICE=fail_stop extend_timeout_interval=5 sleep_interval=7 start_intervals=0 run_intervals=0 stop_intervals=2 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh # Due to 6041a7ee2c1bbff6301082f192fc1b0882400d42 SIGTERM isn't sent as the service shuts down with STOPPING=1 # This file makes the test assess.sh quicker by notifing it that this test has finished. ExecStopPost=/bin/bash -c '[[ $SERVICE_RESULT == timeout && $EXIT_CODE == killed ]] && touch /fail_runtime.terminated' diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service b/test/testsuite-16.units/success-all.service index 666f4229bf..e2d7e607ba 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-all.service +++ b/test/testsuite-16.units/success-all.service @@ -1,4 +1,3 @@ - [Unit] Description=Testsuite: EXTEND_TIMEOUT_USEC Success - extend timeout on all services @@ -11,4 +10,5 @@ Type=notify TimeoutStartSec=4 TimeoutStopSec=4 RuntimeMaxSec=4 -ExecStart=/extend_timeout_test_service.sh SERVICE=success_all extend_timeout_interval=4 sleep_interval=2 start_intervals=3 run_intervals=3 stop_intervals=3 +Environment=SERVICE=success_all extend_timeout_interval=4 sleep_interval=2 start_intervals=3 run_intervals=3 stop_intervals=3 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service b/test/testsuite-16.units/success-runtime.service index dc226f5054..15283b73a8 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-runtime.service +++ b/test/testsuite-16.units/success-runtime.service @@ -1,4 +1,3 @@ - [Unit] Description=Testsuite: Success Runtime (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < RuntimeMaxSec) @@ -10,4 +9,5 @@ Type=notify TimeoutStartSec=4 TimeoutStopSec=4 RuntimeMaxSec=8 -ExecStart=/extend_timeout_test_service.sh SERVICE=success_runtime extend_timeout_interval=4 sleep_interval=6 start_intervals=0 run_intervals=1 stop_intervals=0 +Environment=SERVICE=success_runtime extend_timeout_interval=4 sleep_interval=6 start_intervals=0 run_intervals=1 stop_intervals=0 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service b/test/testsuite-16.units/success-start.service index 228eece73e..cfdcc33cc8 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-start.service +++ b/test/testsuite-16.units/success-start.service @@ -1,13 +1,12 @@ - [Unit] Description=Testsuite: Success Start (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < TimeoutStartSec) [Service] - # EXTEND_TIMEOUT_USEC=4 second interval once at startup, but sleep 6 seconds. # Therefore startup is 6 seconds and < TimeoutStartSec so still successful. Type=notify TimeoutStartSec=8 TimeoutStopSec=4 RuntimeMaxSec=4 -ExecStart=/extend_timeout_test_service.sh SERVICE=success_start extend_timeout_interval=4 sleep_interval=6 start_intervals=1 run_intervals=0 stop_intervals=0 +Environment=SERVICE=success_start extend_timeout_interval=4 sleep_interval=6 start_intervals=1 run_intervals=0 stop_intervals=0 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh diff --git a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service b/test/testsuite-16.units/success-stop.service index b809397bf3..c4600ace41 100644 --- a/test/TEST-16-EXTEND-TIMEOUT/testsuite-success-stop.service +++ b/test/testsuite-16.units/success-stop.service @@ -1,13 +1,12 @@ - [Unit] Description=Testsuite: Success Stop (EXTEND_TIMEOUT_USEC > WATCHDOG_USEC however < TimeoutStopSec) [Service] - # EXTEND_TIMEOUT_USEC=4 seconds once during shutdown, but sleep for 6 seconds. # Therefore stop time is 6 seconds and < TimeoutStopSec so still successful. Type=notify TimeoutStartSec=4 TimeoutStopSec=8 RuntimeMaxSec=4 -ExecStart=/extend_timeout_test_service.sh SERVICE=success_stop extend_timeout_interval=4 sleep_interval=6 start_intervals=0 run_intervals=0 stop_intervals=1 +Environment=SERVICE=success_stop extend_timeout_interval=4 sleep_interval=6 start_intervals=0 run_intervals=0 stop_intervals=1 +ExecStart=/usr/lib/systemd/tests/testdata/testsuite-16.units/extend-timeout.sh diff --git a/test/testsuite-28.units/specifier-j-depends-wants.service b/test/testsuite-28.units/specifier-j-depends-wants.service new file mode 100644 index 0000000000..f9c6abb493 --- /dev/null +++ b/test/testsuite-28.units/specifier-j-depends-wants.service @@ -0,0 +1,7 @@ +[Unit] +Description=Dependent service for percent-j specifier +After=testsuite-28-pre.service + +[Service] +Type=oneshot +ExecStart=touch /tmp/test-specifier-j-wants diff --git a/test/testsuite-28.units/specifier-j-wants.service b/test/testsuite-28.units/specifier-j-wants.service new file mode 100644 index 0000000000..facf5577be --- /dev/null +++ b/test/testsuite-28.units/specifier-j-wants.service @@ -0,0 +1,10 @@ +[Unit] +Description=Wants with percent-j specifier +Wants=specifier-j-depends-%j.service +After=specifier-j-depends-%j.service +After=testsuite-28-pre.service + +[Service] +Type=oneshot +ExecStart=test -f /tmp/test-specifier-j-%j +ExecStart=sh -c 'echo OK > /testok' diff --git a/test/testsuite-28.units/testsuite-28-pre.service b/test/testsuite-28.units/testsuite-28-pre.service new file mode 100644 index 0000000000..2b8ef98911 --- /dev/null +++ b/test/testsuite-28.units/testsuite-28-pre.service @@ -0,0 +1,3 @@ +[Service] +ExecStart=rm -f /failed /testok +Type=oneshot diff --git a/test/testsuite-30.units/systemd-timedated.service.d/watchdog.conf b/test/testsuite-30.units/systemd-timedated.service.d/watchdog.conf new file mode 100644 index 0000000000..d5ed27cf6b --- /dev/null +++ b/test/testsuite-30.units/systemd-timedated.service.d/watchdog.conf @@ -0,0 +1,2 @@ +[Service] +WatchdogSec=10min diff --git a/test/timers.target b/test/timers.target deleted file mode 120000 index 576d47fed7..0000000000 --- a/test/timers.target +++ /dev/null @@ -1 +0,0 @@ -../units/timers.target
\ No newline at end of file diff --git a/test/a-conj.service b/test/units/a-conj.service index db37ae71d4..db37ae71d4 100644 --- a/test/a-conj.service +++ b/test/units/a-conj.service diff --git a/test/a.service b/test/units/a.service index 4168d2d051..4168d2d051 100644 --- a/test/a.service +++ b/test/units/a.service diff --git a/test/units/autorelabel.service b/test/units/autorelabel.service new file mode 100644 index 0000000000..cb38849373 --- /dev/null +++ b/test/units/autorelabel.service @@ -0,0 +1,18 @@ +[Unit] +Description=Relabel all filesystems +DefaultDependencies=no +Requires=local-fs.target +Conflicts=shutdown.target +After=local-fs.target +Before=sysinit.target shutdown.target +ConditionSecurity=selinux +ConditionPathExists=|/.autorelabel + +[Service] +ExecStart=sh -x -c 'echo 0 >/sys/fs/selinux/enforce && fixfiles -f -F relabel && rm /.autorelabel && systemctl --force reboot' +Type=oneshot +TimeoutSec=0 +RemainAfterExit=yes + +[Install] +WantedBy=basic.target diff --git a/test/b.service b/test/units/b.service index e03bae36be..e03bae36be 100644 --- a/test/b.service +++ b/test/units/b.service diff --git a/test/units/basic.target b/test/units/basic.target new file mode 100644 index 0000000000..4f44292249 --- /dev/null +++ b/test/units/basic.target @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Basic System +Documentation=man:systemd.special(7) +Requires=sysinit.target +Wants=sockets.target timers.target paths.target slices.target +After=sysinit.target sockets.target paths.target slices.target tmp.mount + +# We support /var, /tmp, /var/tmp, being on NFS, but we don't pull in +# remote-fs.target by default, hence pull them in explicitly here. Note that we +# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as +# we support that unit being masked, and this should not be considered an error. +RequiresMountsFor=/var /var/tmp +Wants=tmp.mount diff --git a/test/c.service b/test/units/c.service index e2f60a8fbf..e2f60a8fbf 100644 --- a/test/c.service +++ b/test/units/c.service diff --git a/test/d.service b/test/units/d.service index 921fd2ee1b..921fd2ee1b 100644 --- a/test/d.service +++ b/test/units/d.service diff --git a/test/daughter.service b/test/units/daughter.service index c790b9d04b..c790b9d04b 100644 --- a/test/daughter.service +++ b/test/units/daughter.service diff --git a/test/dml-discard-empty.service b/test/units/dml-discard-empty.service index 75228f6470..75228f6470 100644 --- a/test/dml-discard-empty.service +++ b/test/units/dml-discard-empty.service diff --git a/test/dml-discard-set-ml.service b/test/units/dml-discard-set-ml.service index 591c99270c..591c99270c 100644 --- a/test/dml-discard-set-ml.service +++ b/test/units/dml-discard-set-ml.service diff --git a/test/dml-discard.slice b/test/units/dml-discard.slice index e26d86846c..e26d86846c 100644 --- a/test/dml-discard.slice +++ b/test/units/dml-discard.slice diff --git a/test/dml-override-empty.service b/test/units/dml-override-empty.service index 142c98720c..142c98720c 100644 --- a/test/dml-override-empty.service +++ b/test/units/dml-override-empty.service diff --git a/test/dml-override.slice b/test/units/dml-override.slice index feb6773e39..feb6773e39 100644 --- a/test/dml-override.slice +++ b/test/units/dml-override.slice diff --git a/test/dml-passthrough-empty.service b/test/units/dml-passthrough-empty.service index 34832de491..34832de491 100644 --- a/test/dml-passthrough-empty.service +++ b/test/units/dml-passthrough-empty.service diff --git a/test/dml-passthrough-set-dml.service b/test/units/dml-passthrough-set-dml.service index 5bdf4ed4b7..5bdf4ed4b7 100644 --- a/test/dml-passthrough-set-dml.service +++ b/test/units/dml-passthrough-set-dml.service diff --git a/test/dml-passthrough-set-ml.service b/test/units/dml-passthrough-set-ml.service index 2e568b5deb..2e568b5deb 100644 --- a/test/dml-passthrough-set-ml.service +++ b/test/units/dml-passthrough-set-ml.service diff --git a/test/dml-passthrough.slice b/test/units/dml-passthrough.slice index 1b1a848edb..1b1a848edb 100644 --- a/test/dml-passthrough.slice +++ b/test/units/dml-passthrough.slice diff --git a/test/dml.slice b/test/units/dml.slice index 84e333ef04..84e333ef04 100644 --- a/test/dml.slice +++ b/test/units/dml.slice diff --git a/test/e.service b/test/units/e.service index 5ba98c7c43..5ba98c7c43 100644 --- a/test/e.service +++ b/test/units/e.service diff --git a/test/end.service b/test/units/end.service index 6e1996fd02..e7ed75ef05 100644 --- a/test/end.service +++ b/test/units/end.service @@ -1,6 +1,6 @@ [Unit] Description=End the test -After=testsuite.service +After=testsuite.target OnFailure=poweroff.target OnFailureJobMode=replace-irreversibly diff --git a/test/f.service b/test/units/f.service index 7dde681c17..7dde681c17 100644 --- a/test/f.service +++ b/test/units/f.service diff --git a/test/g.service b/test/units/g.service index cbfa82a454..cbfa82a454 100644 --- a/test/g.service +++ b/test/units/g.service diff --git a/test/grandchild.service b/test/units/grandchild.service index ab641300e4..ab641300e4 100644 --- a/test/grandchild.service +++ b/test/units/grandchild.service diff --git a/test/h.service b/test/units/h.service index 74a7751cad..74a7751cad 100644 --- a/test/h.service +++ b/test/units/h.service diff --git a/test/hello-after-sleep.target b/test/units/hello-after-sleep.target index 526fbd2a12..526fbd2a12 100644 --- a/test/hello-after-sleep.target +++ b/test/units/hello-after-sleep.target diff --git a/test/hello.service b/test/units/hello.service index 82907b64e1..82907b64e1 100644 --- a/test/hello.service +++ b/test/units/hello.service diff --git a/test/i.service b/test/units/i.service index 938ea77bdf..938ea77bdf 100644 --- a/test/i.service +++ b/test/units/i.service diff --git a/test/loopy.service b/test/units/loopy.service index 9eb645748e..9eb645748e 100644 --- a/test/loopy.service +++ b/test/units/loopy.service diff --git a/test/loopy.service.d/compat.conf b/test/units/loopy.service.d/compat.conf index 51b84b89ed..51b84b89ed 100644 --- a/test/loopy.service.d/compat.conf +++ b/test/units/loopy.service.d/compat.conf diff --git a/test/units/loopy2.service b/test/units/loopy2.service new file mode 100644 index 0000000000..9eb645748e --- /dev/null +++ b/test/units/loopy2.service @@ -0,0 +1,2 @@ +[Service] +ExecStart=/bin/true diff --git a/test/loopy3.service b/test/units/loopy3.service index 606e26b5da..606e26b5da 100644 --- a/test/loopy3.service +++ b/test/units/loopy3.service diff --git a/test/units/loopy4.service b/test/units/loopy4.service new file mode 100644 index 0000000000..606e26b5da --- /dev/null +++ b/test/units/loopy4.service @@ -0,0 +1,5 @@ +[Service] +ExecStart=/bin/true + +[Unit] +Conflicts=loopy4.service diff --git a/test/nomem.slice b/test/units/nomem.slice index 9c5d208cb4..9c5d208cb4 100644 --- a/test/nomem.slice +++ b/test/units/nomem.slice diff --git a/test/nomemleaf.service b/test/units/nomemleaf.service index 3cbaccb82f..3cbaccb82f 100644 --- a/test/nomemleaf.service +++ b/test/units/nomemleaf.service diff --git a/test/parent-deep.slice b/test/units/parent-deep.slice index 79b302f38d..79b302f38d 100644 --- a/test/parent-deep.slice +++ b/test/units/parent-deep.slice diff --git a/test/parent.slice b/test/units/parent.slice index a95f90392d..a95f90392d 100644 --- a/test/parent.slice +++ b/test/units/parent.slice diff --git a/test/sched_idle_bad.service b/test/units/sched_idle_bad.service index 589a87ccfd..589a87ccfd 100644 --- a/test/sched_idle_bad.service +++ b/test/units/sched_idle_bad.service diff --git a/test/sched_idle_ok.service b/test/units/sched_idle_ok.service index 262ef3e319..262ef3e319 100644 --- a/test/sched_idle_ok.service +++ b/test/units/sched_idle_ok.service diff --git a/test/sched_rr_bad.service b/test/units/sched_rr_bad.service index 0be534a546..0be534a546 100644 --- a/test/sched_rr_bad.service +++ b/test/units/sched_rr_bad.service diff --git a/test/sched_rr_change.service b/test/units/sched_rr_change.service index b3e3a000f8..b3e3a000f8 100644 --- a/test/sched_rr_change.service +++ b/test/units/sched_rr_change.service diff --git a/test/sched_rr_ok.service b/test/units/sched_rr_ok.service index b88adc5434..b88adc5434 100644 --- a/test/sched_rr_ok.service +++ b/test/units/sched_rr_ok.service diff --git a/test/units/shutdown.target b/test/units/shutdown.target new file mode 100644 index 0000000000..d48e6d6494 --- /dev/null +++ b/test/units/shutdown.target @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Shutdown +Documentation=man:systemd.special(7) +DefaultDependencies=no +RefuseManualStart=yes diff --git a/test/sleep.service b/test/units/sleep.service index 946c44b621..946c44b621 100644 --- a/test/sleep.service +++ b/test/units/sleep.service diff --git a/test/units/sockets.target b/test/units/sockets.target new file mode 100644 index 0000000000..9af67fdb1f --- /dev/null +++ b/test/units/sockets.target @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Sockets +Documentation=man:systemd.special(7) diff --git a/test/son.service b/test/units/son.service index 50bb96a941..50bb96a941 100644 --- a/test/son.service +++ b/test/units/son.service diff --git a/test/units/sysinit.target b/test/units/sysinit.target new file mode 100644 index 0000000000..b6c16a1412 --- /dev/null +++ b/test/units/sysinit.target @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=System Initialization +Documentation=man:systemd.special(7) +Conflicts=emergency.service emergency.target +Wants=local-fs.target swap.target +After=local-fs.target swap.target emergency.service emergency.target diff --git a/test/units/testsuite-01.service b/test/units/testsuite-01.service new file mode 100644 index 0000000000..85b9cf5a96 --- /dev/null +++ b/test/units/testsuite-01.service @@ -0,0 +1,8 @@ +[Unit] +Description=TEST-01-BASIC +After=multi-user.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=sh -e -x -c 'systemctl --state=failed --no-legend --no-pager >/failed ; systemctl daemon-reload ; echo OK >/testok' +Type=oneshot diff --git a/test/units/testsuite-02.service b/test/units/testsuite-02.service new file mode 100644 index 0000000000..701610b790 --- /dev/null +++ b/test/units/testsuite-02.service @@ -0,0 +1,8 @@ +[Unit] +Description=TEST-02-CRYPTSETUP +After=multi-user.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=sh -x -c 'systemctl --state=failed --no-legend --no-pager >/failed ; echo OK > /testok' +Type=oneshot diff --git a/test/units/testsuite-03.service b/test/units/testsuite-03.service new file mode 100644 index 0000000000..fe18fdc7d7 --- /dev/null +++ b/test/units/testsuite-03.service @@ -0,0 +1,8 @@ +[Unit] +Description=TEST-03-JOBS +After=multi-user.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-03-JOBS/test-jobs.sh b/test/units/testsuite-03.sh index 85efeeb741..85efeeb741 100755 --- a/test/TEST-03-JOBS/test-jobs.sh +++ b/test/units/testsuite-03.sh diff --git a/test/units/testsuite-04.service b/test/units/testsuite-04.service new file mode 100644 index 0000000000..3d2b4a8bc2 --- /dev/null +++ b/test/units/testsuite-04.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-04-JOURNAL + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/units/testsuite-04.sh index 1431dad862..1431dad862 100755 --- a/test/TEST-04-JOURNAL/test-journal.sh +++ b/test/units/testsuite-04.sh diff --git a/test/units/testsuite-05.service b/test/units/testsuite-05.service new file mode 100644 index 0000000000..66356fd16f --- /dev/null +++ b/test/units/testsuite-05.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-05-RLIMITS + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-05.sh b/test/units/testsuite-05.sh new file mode 100755 index 0000000000..9168e72799 --- /dev/null +++ b/test/units/testsuite-05.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -x +set -e +set -o pipefail + +P=/run/systemd/system.conf.d +mkdir $P + +cat >$P/rlimits.conf <<EOF +[Manager] +DefaultLimitNOFILE=10000:16384 +EOF + +systemctl daemon-reload + +[[ "$(systemctl show -P DefaultLimitNOFILESoft)" = "10000" ]] +[[ "$(systemctl show -P DefaultLimitNOFILE)" = "16384" ]] + +[[ "$(systemctl show -P LimitNOFILESoft testsuite-05.service)" = "10000" ]] +[[ "$(systemctl show -P LimitNOFILE testsuite-05.service)" = "16384" ]] + +systemd-run --wait -t bash -c '[[ "$(ulimit -n -S)" = "10000" ]]' +systemd-run --wait -t bash -c '[[ "$(ulimit -n -H)" = "16384" ]]' + +touch /testok diff --git a/test/units/testsuite-06.service b/test/units/testsuite-06.service new file mode 100644 index 0000000000..3f8dad36dc --- /dev/null +++ b/test/units/testsuite-06.service @@ -0,0 +1,10 @@ +[Unit] +Description=TEST-06-SELINUX + +Requires=load-systemd-test-module.service +After=load-systemd-test-module.service + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-06-SELINUX/test-selinux-checks.sh b/test/units/testsuite-06.sh index 9e722e362e..f9b106da7b 100755 --- a/test/TEST-06-SELINUX/test-selinux-checks.sh +++ b/test/units/testsuite-06.sh @@ -3,7 +3,12 @@ set -x set -e set -o pipefail -echo 1 >/sys/fs/selinux/enforce +echo 1 >/sys/fs/selinux/enforce || { + echo "Can't make selinux enforcing, skipping test" + touch /testok + exit +} + runcon -t systemd_test_start_t systemctl start hola runcon -t systemd_test_reload_t systemctl reload hola runcon -t systemd_test_stop_t systemctl stop hola diff --git a/test/units/testsuite-07.service b/test/units/testsuite-07.service new file mode 100644 index 0000000000..2506c211c2 --- /dev/null +++ b/test/units/testsuite-07.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-07-ISSUE-1981 + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-07-ISSUE-1981/test-segfault.sh b/test/units/testsuite-07.sh index fbb2d1d30a..fbb2d1d30a 100755 --- a/test/TEST-07-ISSUE-1981/test-segfault.sh +++ b/test/units/testsuite-07.sh diff --git a/test/units/testsuite-08.service b/test/units/testsuite-08.service new file mode 100644 index 0000000000..d961dc7ae2 --- /dev/null +++ b/test/units/testsuite-08.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-08-ISSUE-2730 + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=sh -x -c 'mount -o remount,rw /dev/sda1 && echo OK >/testok; systemctl poweroff' +Type=oneshot diff --git a/test/units/testsuite-09.service b/test/units/testsuite-09.service new file mode 100644 index 0000000000..fc59e80889 --- /dev/null +++ b/test/units/testsuite-09.service @@ -0,0 +1,10 @@ +[Unit] +Description=TEST-09-ISSUE-2691 + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=sh -c '>/testok' +ExecStop=sh -c 'kill -SEGV $$$$' +Type=oneshot +RemainAfterExit=yes +TimeoutStopSec=270s diff --git a/test/units/testsuite-10.service b/test/units/testsuite-10.service new file mode 100644 index 0000000000..24f0da35ab --- /dev/null +++ b/test/units/testsuite-10.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-10-ISSUE-2467 + +[Service] +ExecStartPre=rm -f /failed /testok +Type=oneshot +ExecStart=sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test10.socket; printf x >test.file; socat -t20 OPEN:test.file UNIX-CONNECT:/run/test.ctl; >/testok' diff --git a/test/units/testsuite-11.service b/test/units/testsuite-11.service new file mode 100644 index 0000000000..1544fd6819 --- /dev/null +++ b/test/units/testsuite-11.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-11-ISSUE-3166 + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-11.sh b/test/units/testsuite-11.sh new file mode 100755 index 0000000000..708c7cebb7 --- /dev/null +++ b/test/units/testsuite-11.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -x + +systemctl start fail-on-restart.service +active_state=$(systemctl show --value --property ActiveState fail-on-restart.service) +while [[ "$active_state" == "activating" || "$active_state" == "active" ]]; do + sleep 1 + active_state=$(systemctl show --value --property ActiveState fail-on-restart.service) +done +systemctl is-failed fail-on-restart.service || exit 1 +touch /testok diff --git a/test/units/testsuite-12.service b/test/units/testsuite-12.service new file mode 100644 index 0000000000..72894eff92 --- /dev/null +++ b/test/units/testsuite-12.service @@ -0,0 +1,8 @@ +[Unit] +Description=TEST-12-ISSUE-3171 +After=multi-user.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-12.sh b/test/units/testsuite-12.sh new file mode 100755 index 0000000000..b5888a255b --- /dev/null +++ b/test/units/testsuite-12.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +set -x +set -e +set -o pipefail + +U=/run/systemd/system/test12.socket +cat <<'EOF' >$U +[Unit] +Description=Test 12 socket +[Socket] +Accept=yes +ListenStream=/run/test12.socket +SocketGroup=adm +SocketMode=0660 +EOF + +cat <<'EOF' > /run/systemd/system/test12@.service +[Unit] +Description=Test service +[Service] +StandardInput=socket +ExecStart=/bin/sh -x -c cat +EOF + +systemctl start test12.socket +systemctl is-active test12.socket +[[ "$(stat --format='%G' /run/test12.socket)" == adm ]] +echo A | nc -w1 -U /run/test12.socket + +mv $U ${U}.disabled +systemctl daemon-reload +systemctl is-active test12.socket +[[ "$(stat --format='%G' /run/test12.socket)" == adm ]] +echo B | nc -w1 -U /run/test12.socket && exit 1 + +mv ${U}.disabled $U +systemctl daemon-reload +systemctl is-active test12.socket +echo C | nc -w1 -U /run/test12.socket && exit 1 +[[ "$(stat --format='%G' /run/test12.socket)" == adm ]] + +systemctl restart test12.socket +systemctl is-active test12.socket +echo D | nc -w1 -U /run/test12.socket +[[ "$(stat --format='%G' /run/test12.socket)" == adm ]] + +touch /testok diff --git a/test/units/testsuite-13.service b/test/units/testsuite-13.service new file mode 100644 index 0000000000..5086793a90 --- /dev/null +++ b/test/units/testsuite-13.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-13-NSPAWN-SMOKE + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-13.sh b/test/units/testsuite-13.sh new file mode 100755 index 0000000000..0ab684732c --- /dev/null +++ b/test/units/testsuite-13.sh @@ -0,0 +1,150 @@ +#!/usr/bin/env bash +set -x +set -e +set -u +set -o pipefail + +export SYSTEMD_LOG_LEVEL=debug + +# check cgroup-v2 +is_v2_supported=no +mkdir -p /tmp/cgroup2 +if mount -t cgroup2 cgroup2 /tmp/cgroup2; then + is_v2_supported=yes + umount /tmp/cgroup2 +fi +rmdir /tmp/cgroup2 + +# check cgroup namespaces +is_cgns_supported=no +if [[ -f /proc/1/ns/cgroup ]]; then + is_cgns_supported=yes +fi + +is_user_ns_supported=no +# On some systems (e.g. CentOS 7) the default limit for user namespaces +# is set to 0, which causes the following unshare syscall to fail, even +# with enabled user namespaces support. By setting this value explicitly +# we can ensure the user namespaces support to be detected correctly. +sysctl -w user.max_user_namespaces=10000 +if unshare -U sh -c :; then + is_user_ns_supported=yes +fi + +function check_bind_tmp_path { + # https://github.com/systemd/systemd/issues/4789 + local _root="/var/lib/machines/bind-tmp-path" + /usr/lib/systemd/tests/testdata/create-busybox-container "$_root" + >/tmp/bind + systemd-nspawn --register=no -D "$_root" --bind=/tmp/bind /bin/sh -c 'test -e /tmp/bind' +} + +function check_norbind { + # https://github.com/systemd/systemd/issues/13170 + local _root="/var/lib/machines/norbind-path" + mkdir -p /tmp/binddir/subdir + echo -n "outer" > /tmp/binddir/subdir/file + mount -t tmpfs tmpfs /tmp/binddir/subdir + echo -n "inner" > /tmp/binddir/subdir/file + /usr/lib/systemd/tests/testdata/create-busybox-container "$_root" + systemd-nspawn --register=no -D "$_root" --bind=/tmp/binddir:/mnt:norbind /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi' +} + +function check_notification_socket { + # https://github.com/systemd/systemd/issues/4944 + local _cmd='echo a | $(busybox which nc) -U -u -w 1 /run/systemd/nspawn/notify' + systemd-nspawn --register=no -D /nc-container /bin/sh -x -c "$_cmd" + systemd-nspawn --register=no -D /nc-container -U /bin/sh -x -c "$_cmd" +} + +function run { + if [[ "$1" = "yes" && "$is_v2_supported" = "no" ]]; then + printf "Unified cgroup hierarchy is not supported. Skipping.\n" >&2 + return 0 + fi + if [[ "$2" = "yes" && "$is_cgns_supported" = "no" ]]; then + printf "CGroup namespaces are not supported. Skipping.\n" >&2 + return 0 + fi + + local _root="/var/lib/machines/unified-$1-cgns-$2-api-vfs-writable-$3" + /usr/lib/systemd/tests/testdata/create-busybox-container "$_root" + SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -b + SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -b + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -U -b; then + [[ "$is_user_ns_supported" = "yes" && "$3" = "network" ]] && return 1 + else + [[ "$is_user_ns_supported" = "no" && "$3" = "network" ]] && return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -U -b; then + [[ "$is_user_ns_supported" = "yes" && "$3" = "yes" ]] && return 1 + else + [[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1 + fi + + local _netns_opt="--network-namespace-path=/proc/self/ns/net" + + # --network-namespace-path and network-related options cannot be used together + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-interface=lo -b; then + return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-macvlan=lo -b; then + return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-ipvlan=lo -b; then + return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth -b; then + return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth-extra=lo -b; then + return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-bridge=lo -b; then + return 1 + fi + + if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-zone=zone -b; then + return 1 + fi + + # allow combination of --network-namespace-path and --private-network + if ! SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --private-network -b; then + return 1 + fi + + # test --network-namespace-path works with a network namespace created by "ip netns" + ip netns add nspawn_test + _netns_opt="--network-namespace-path=/run/netns/nspawn_test" + SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" /bin/ip a | grep -v -E '^1: lo.*UP' + local r=$? + ip netns del nspawn_test + + if [ $r -ne 0 ]; then + return 1 + fi + + return 0 +} + +check_bind_tmp_path + +check_norbind + +check_notification_socket + +for api_vfs_writable in yes no network; do + run no no $api_vfs_writable + run yes no $api_vfs_writable + run no yes $api_vfs_writable + run yes yes $api_vfs_writable +done + +touch /testok diff --git a/test/units/testsuite-14.service b/test/units/testsuite-14.service new file mode 100644 index 0000000000..1606c68fb1 --- /dev/null +++ b/test/units/testsuite-14.service @@ -0,0 +1,8 @@ +[Unit] +Description=TEST-14-MACHINE-ID + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +ExecStart=/bin/sh -e -x -c 'systemctl --state=failed --no-legend --no-pager >/failed ; echo OK >/testok' +Type=oneshot diff --git a/test/units/testsuite-14.sh b/test/units/testsuite-14.sh new file mode 100755 index 0000000000..95ac9b65ae --- /dev/null +++ b/test/units/testsuite-14.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +set -e +set -x + +function setup_root { + local _root="$1" + mkdir -p "$_root" + mount -t tmpfs tmpfs "$_root" + mkdir -p "$_root/etc" "$_root/run" +} + +function check { + printf "Expected\n" + cat "$1" + printf "\nGot\n" + cat "$2" + cmp "$1" "$2" +} + +r="$(pwd)/overwrite-broken-machine-id" +setup_root "$r" +systemd-machine-id-setup --print --root "$r" +echo abc >>"$r/etc/machine-id" +id=$(systemd-machine-id-setup --print --root "$r") +echo $id >expected +check expected "$r/etc/machine-id" + +r="$(pwd)/transient-machine-id" +setup_root "$r" +systemd-machine-id-setup --print --root "$r" +echo abc >>"$r/etc/machine-id" +mount -o remount,ro "$r" +mount -t tmpfs tmpfs "$r/run" +transient_id=$(systemd-machine-id-setup --print --root "$r") +mount -o remount,rw "$r" +commited_id=$(systemd-machine-id-setup --print --commit --root "$r") +[[ "$transient_id" = "$commited_id" ]] +check "$r/etc/machine-id" "$r/run/machine-id" diff --git a/test/units/testsuite-15.service b/test/units/testsuite-15.service new file mode 100644 index 0000000000..09571ed1ab --- /dev/null +++ b/test/units/testsuite-15.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-15-DROPIN + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/units/testsuite-15.sh index f80c9df107..b872a24c20 100755 --- a/test/TEST-15-DROPIN/test-dropin.sh +++ b/test/units/testsuite-15.sh @@ -7,6 +7,12 @@ _clear_service () { rm -f /{etc,run,usr/lib}/systemd/system/$1.service rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} + if [[ $1 == *@ ]]; then + systemctl stop $1*.service 2>/dev/null || : + rm -f /{etc,run,usr/lib}/systemd/system/$1*.service + rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d + rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} + fi } clear_services () { @@ -56,65 +62,66 @@ test_basic_dropins () { echo "Testing basic dropins..." echo "*** test a wants b wants c" - create_services a b c - ln -s ../b.service /etc/systemd/system/a.service.wants/ - ln -s ../c.service /etc/systemd/system/b.service.wants/ - check_ok a Wants b.service - check_ok b Wants c.service + create_services test15-a test15-b test15-c + ln -s ../test15-b.service /etc/systemd/system/test15-a.service.wants/ + ln -s ../test15-c.service /etc/systemd/system/test15-b.service.wants/ + check_ok test15-a Wants test15-b.service + check_ok test15-b Wants test15-c.service echo "*** test a wants,requires b" - create_services a b c - ln -s ../b.service /etc/systemd/system/a.service.wants/ - ln -s ../b.service /etc/systemd/system/a.service.requires/ - check_ok a Wants b.service - check_ok a Requires b.service + create_services test15-a test15-b test15-c + ln -s ../test15-b.service /etc/systemd/system/test15-a.service.wants/ + ln -s ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + check_ok test15-a Wants test15-b.service + check_ok test15-a Requires test15-b.service echo "*** test a wants nonexistent" - create_service a - ln -s ../nonexistent.service /etc/systemd/system/a.service.wants/ - check_ok a Wants nonexistent.service - systemctl start a - systemctl stop a + create_service test15-a + ln -s ../nonexistent.service /etc/systemd/system/test15-a.service.wants/ + check_ok test15-a Wants nonexistent.service + systemctl start test15-a + systemctl stop test15-a echo "*** test a requires nonexistent" - ln -sf ../nonexistent.service /etc/systemd/system/a.service.requires/ + ln -sf ../nonexistent.service /etc/systemd/system/test15-a.service.requires/ systemctl daemon-reload - check_ok a Requires nonexistent.service + check_ok test15-a Requires nonexistent.service # 'b' is already loaded when 'c' pulls it in via a dropin. echo "*** test a,c require b" - create_services a b c - ln -sf ../b.service /etc/systemd/system/a.service.requires/ - ln -sf ../b.service /etc/systemd/system/c.service.requires/ - systemctl start a - check_ok c Requires b.service - systemctl stop a b + create_services test15-a test15-b test15-c + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b.service /etc/systemd/system/test15-c.service.requires/ + systemctl start test15-a + check_ok test15-c Requires test15-b.service + systemctl stop test15-a test15-b # 'b' is already loaded when 'c' pulls it in via an alias dropin. echo "*** test a wants alias" - create_services a b c - ln -sf c.service /etc/systemd/system/c1.service - ln -sf ../c.service /etc/systemd/system/a.service.wants/ - ln -sf ../c1.service /etc/systemd/system/b.service.wants/ - systemctl start a - check_ok a Wants c.service - check_ok b Wants c.service - systemctl stop a c + create_services test15-a test15-b test15-c + ln -sf test15-c.service /etc/systemd/system/test15-c1.service + ln -sf ../test15-c.service /etc/systemd/system/test15-a.service.wants/ + ln -sf ../test15-c1.service /etc/systemd/system/test15-b.service.wants/ + systemctl start test15-a + check_ok test15-a Wants test15-c.service + check_ok test15-b Wants test15-c.service + systemctl stop test15-a test15-c echo "*** test service.d/ top level drop-in" - create_services a b - check_ko a ExecCondition "/bin/echo a" - check_ko b ExecCondition "/bin/echo b" + create_services test15-a test15-b + check_ko test15-a ExecCondition "/bin/echo a" + check_ko test15-b ExecCondition "/bin/echo b" mkdir -p /usr/lib/systemd/system/service.d cat >/usr/lib/systemd/system/service.d/override.conf <<EOF [Service] ExecCondition=/bin/echo %n EOF - check_ok a ExecCondition "/bin/echo a" - check_ok b ExecCondition "/bin/echo b" + systemctl daemon-reload + check_ok test15-a ExecCondition "/bin/echo test15-a" + check_ok test15-b ExecCondition "/bin/echo test15-b" rm -rf /usr/lib/systemd/system/service.d - clear_services a b c + clear_services test15-a test15-b test15-c } test_hierarchical_dropins () { @@ -132,6 +139,7 @@ test_hierarchical_dropins () { [Service] ExecCondition=/bin/echo $dropin " > /usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload check_ok a-b-c ExecCondition "/bin/echo $dropin" done for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do @@ -294,153 +302,153 @@ test_alias_dropins () { echo "Testing alias dropins..." echo "*** test a wants b1 alias of b" - create_services a b - ln -sf b.service /etc/systemd/system/b1.service - ln -sf ../b1.service /etc/systemd/system/a.service.wants/ - check_ok a Wants b.service - systemctl start a - systemctl --quiet is-active b - systemctl stop a b - rm /etc/systemd/system/b1.service - clear_services a b + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf ../test15-b1.service /etc/systemd/system/test15-a.service.wants/ + check_ok test15-a Wants test15-b.service + systemctl start test15-a + systemctl --quiet is-active test15-b + systemctl stop test15-a test15-b + rm /etc/systemd/system/test15-b1.service + clear_services test15-a test15-b # Check that dependencies don't vary. echo "*** test 2" - create_services a x y - mkdir -p /etc/systemd/system/a1.service.wants/ - ln -sf a.service /etc/systemd/system/a1.service - ln -sf ../x.service /etc/systemd/system/a.service.wants/ - ln -sf ../y.service /etc/systemd/system/a1.service.wants/ - check_ok a1 Wants x.service # see [1] - check_ok a1 Wants y.service - systemctl start a - check_ok a1 Wants x.service # see [2] - check_ok a1 Wants y.service - systemctl stop a x y - rm /etc/systemd/system/a1.service - - clear_services a x y + create_services test15-a test15-x test15-y + mkdir -p /etc/systemd/system/test15-a1.service.wants/ + ln -sf test15-a.service /etc/systemd/system/test15-a1.service + ln -sf ../test15-x.service /etc/systemd/system/test15-a.service.wants/ + ln -sf ../test15-y.service /etc/systemd/system/test15-a1.service.wants/ + check_ok test15-a1 Wants test15-x.service # see [1] + check_ok test15-a1 Wants test15-y.service + systemctl start test15-a + check_ok test15-a1 Wants test15-x.service # see [2] + check_ok test15-a1 Wants test15-y.service + systemctl stop test15-a test15-x test15-y + rm /etc/systemd/system/test15-a1.service + + clear_services test15-a test15-x test15-y } test_masked_dropins () { echo "Testing masked dropins..." - create_services a b + create_services test15-a test15-b # 'b' is masked for both deps echo "*** test a wants,requires b is masked" - ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service - ln -sf /dev/null /etc/systemd/system/a.service.requires/b.service - check_ko a Wants b.service - check_ko a Requires b.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b.service + check_ko test15-a Wants test15-b.service + check_ko test15-a Requires test15-b.service # 'a' wants 'b' and 'b' is masked at a lower level echo "*** test a wants b, mask override" - ln -sf ../b.service /etc/systemd/system/a.service.wants/b.service - ln -sf /dev/null /usr/lib/systemd/system/a.service.wants/b.service - check_ok a Wants b.service + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf /dev/null /usr/lib/systemd/system/test15-a.service.wants/test15-b.service + check_ok test15-a Wants test15-b.service # 'a' wants 'b' and 'b' is masked at a higher level echo "*** test a wants b, mask" - ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service - ln -sf ../b.service /usr/lib/systemd/system/a.service.wants/b.service - check_ko a Wants b.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf ../test15-b.service /usr/lib/systemd/system/test15-a.service.wants/test15-b.service + check_ko test15-a Wants test15-b.service # 'a' is masked but has an override config file echo "*** test a is masked but has an override" - create_services a b - ln -sf /dev/null /etc/systemd/system/a.service - cat >/usr/lib/systemd/system/a.service.d/override.conf <<EOF + create_services test15-a test15-b + ln -sf /dev/null /etc/systemd/system/test15-a.service + cat >/usr/lib/systemd/system/test15-a.service.d/override.conf <<EOF [Unit] -After=b.service +After=test15-b.service EOF - check_ok a UnitFileState masked + check_ok test15-a UnitFileState masked # 'b1' is an alias for 'b': masking 'b' dep should not influence 'b1' dep echo "*** test a wants b, b1, and one is masked" - create_services a b - ln -sf b.service /etc/systemd/system/b1.service - ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service - ln -sf ../b1.service /usr/lib/systemd/system/a.service.wants/b1.service - systemctl cat a - systemctl show -p Wants,Requires a - systemctl cat b1 - systemctl show -p Wants,Requires b1 - check_ok a Wants b.service - check_ko a Wants b1.service # the alias does not show up in the list of units - rm /etc/systemd/system/b1.service + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + ln -sf ../test15-b1.service /usr/lib/systemd/system/test15-a.service.wants/test15-b1.service + systemctl cat test15-a + systemctl show -p Wants,Requires test15-a + systemctl cat test15-b1 + systemctl show -p Wants,Requires test15-b1 + check_ok test15-a Wants test15-b.service + check_ko test15-a Wants test15-b1.service # the alias does not show up in the list of units + rm /etc/systemd/system/test15-b1.service # 'b1' is an alias for 'b': masking 'b1' should not influence 'b' dep echo "*** test a wants b, alias dep is masked" - create_services a b - ln -sf b.service /etc/systemd/system/b1.service - ln -sf /dev/null /etc/systemd/system/a.service.wants/b1.service - ln -sf ../b.service /usr/lib/systemd/system/a.service.wants/b.service - check_ok a Wants b.service - check_ko a Wants b1.service # the alias does not show up in the list of units - rm /etc/systemd/system/b1.service + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b1.service + ln -sf ../test15-b.service /usr/lib/systemd/system/test15-a.service.wants/test15-b.service + check_ok test15-a Wants test15-b.service + check_ko test15-a Wants test15-b1.service # the alias does not show up in the list of units + rm /etc/systemd/system/test15-b1.service # 'a' has Wants=b.service but also has a masking # dropin 'b': 'b' should still be pulled in. echo "*** test a wants b both ways" - create_services a b - ln -sf /dev/null /etc/systemd/system/a.service.wants/b.service - cat >/usr/lib/systemd/system/a.service.d/wants-b.conf<<EOF + create_services test15-a test15-b + ln -sf /dev/null /etc/systemd/system/test15-a.service.wants/test15-b.service + cat >/usr/lib/systemd/system/test15-a.service.d/wants-b.conf<<EOF [Unit] -Wants=b.service +Wants=test15-b.service EOF - check_ok a Wants b.service + check_ok test15-a Wants test15-b.service # mask a dropin that points to an nonexistent unit. echo "*** test a wants nonexistent is masked" - create_services a - ln -sf /dev/null /etc/systemd/system/a.service.requires/nonexistent.service - ln -sf ../nonexistent.service /usr/lib/systemd/system/a.service.requires/ - check_ko a Requires nonexistent.service + create_services test15-a + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/nonexistent.service + ln -sf ../nonexistent.service /usr/lib/systemd/system/test15-a.service.requires/ + check_ko test15-a Requires nonexistent.service # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is # masked at a higher level. echo "*** test a wants b is masked" - create_services a b c - ln -sf ../b.service /etc/systemd/system/a.service.requires/ - ln -sf ../b.service /run/systemd/system/c.service.requires/ - ln -sf /dev/null /etc/systemd/system/c.service.requires/b.service - systemctl start a - check_ko c Requires b.service - systemctl stop a b + create_services test15-a test15-b test15-c + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b.service /run/systemd/system/test15-c.service.requires/ + ln -sf /dev/null /etc/systemd/system/test15-c.service.requires/test15-b.service + systemctl start test15-a + check_ko test15-c Requires test15-b.service + systemctl stop test15-a test15-b # 'b' is already loaded when 'c' pulls it in via a dropin but 'b' is # masked at a lower level. echo "*** test a requires b is masked" - create_services a b c - ln -sf ../b.service /etc/systemd/system/a.service.requires/ - ln -sf ../b.service /etc/systemd/system/c.service.requires/ - ln -sf /dev/null /run/systemd/system/c.service.requires/b.service - systemctl start a - check_ok c Requires b.service - systemctl stop a b + create_services test15-a test15-b test15-c + ln -sf ../test15-b.service /etc/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b.service /etc/systemd/system/test15-c.service.requires/ + ln -sf /dev/null /run/systemd/system/test15-c.service.requires/test15-b.service + systemctl start test15-a + check_ok test15-c Requires test15-b.service + systemctl stop test15-a test15-b # 'a' requires 2 aliases of 'b' and one of them is a mask. echo "*** test a requires alias of b, other alias masked" - create_services a b - ln -sf b.service /etc/systemd/system/b1.service - ln -sf b.service /etc/systemd/system/b2.service - ln -sf /dev/null /etc/systemd/system/a.service.requires/b1.service - ln -sf ../b1.service /run/systemd/system/a.service.requires/ - ln -sf ../b2.service /usr/lib/systemd/system/a.service.requires/ - check_ok a Requires b + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf test15-b.service /etc/systemd/system/test15-b2.service + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b1.service + ln -sf ../test15-b1.service /run/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b2.service /usr/lib/systemd/system/test15-a.service.requires/ + check_ok test15-a Requires test15-b # Same as above but now 'b' is masked. echo "*** test a requires alias of b, b dep masked" - create_services a b - ln -sf b.service /etc/systemd/system/b1.service - ln -sf b.service /etc/systemd/system/b2.service - ln -sf ../b1.service /run/systemd/system/a.service.requires/ - ln -sf ../b2.service /usr/lib/systemd/system/a.service.requires/ - ln -sf /dev/null /etc/systemd/system/a.service.requires/b.service - check_ok a Requires b - - clear_services a b + create_services test15-a test15-b + ln -sf test15-b.service /etc/systemd/system/test15-b1.service + ln -sf test15-b.service /etc/systemd/system/test15-b2.service + ln -sf ../test15-b1.service /run/systemd/system/test15-a.service.requires/ + ln -sf ../test15-b2.service /usr/lib/systemd/system/test15-a.service.requires/ + ln -sf /dev/null /etc/systemd/system/test15-a.service.requires/test15-b.service + check_ok test15-a Requires test15-b + + clear_services test15-a test15-b } test_invalid_dropins () { diff --git a/test/units/testsuite-16.service b/test/units/testsuite-16.service new file mode 100644 index 0000000000..b44baad91a --- /dev/null +++ b/test/units/testsuite-16.service @@ -0,0 +1,19 @@ +[Unit] +Description=TEST-16-EXTEND-TIMEOUT +# Testsuite: Assess all other testsuite-*.services worked as expected + +Wants=success-all.service +Wants=success-start.service +Wants=success-runtime.service +Wants=success-stop.service +Wants=fail-start.service +Wants=fail-stop.service +Wants=fail-runtime.service +StopWhenUnneeded=yes + +[Service] +ExecStartPre=rm -f /failed /testok +Type=simple +TimeoutStartSec=infinity +ExecStartPre=/usr/lib/systemd/tests/testdata/units/%N.sh +ExecStart=true diff --git a/test/TEST-16-EXTEND-TIMEOUT/assess.sh b/test/units/testsuite-16.sh index 6f98810b30..68e5561245 100755 --- a/test/TEST-16-EXTEND-TIMEOUT/assess.sh +++ b/test/units/testsuite-16.sh @@ -19,7 +19,7 @@ function wait_for() if [[ ! -f /${service}.${result} ]] then - journalctl -u testsuite-${service/_/-}.service >> "${TL}" + journalctl -u ${service/_/-}.service >> "${TL}" fi } diff --git a/test/units/testsuite-17.service b/test/units/testsuite-17.service new file mode 100644 index 0000000000..ed2017a848 --- /dev/null +++ b/test/units/testsuite-17.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-17-UDEV-WANTS + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-17-UDEV-WANTS/testsuite.sh b/test/units/testsuite-17.sh index 989c190ce3..7f8740ba35 100755 --- a/test/TEST-17-UDEV-WANTS/testsuite.sh +++ b/test/units/testsuite-17.sh @@ -69,6 +69,6 @@ while : ; do sleep .5 done -echo OK > /testok +echo OK >/testok exit 0 diff --git a/test/units/testsuite-18.service b/test/units/testsuite-18.service new file mode 100644 index 0000000000..e4a945dc3e --- /dev/null +++ b/test/units/testsuite-18.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-18-FAILUREACTION + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-18-FAILUREACTION/testsuite.sh b/test/units/testsuite-18.sh index e471cda51b..e471cda51b 100755 --- a/test/TEST-18-FAILUREACTION/testsuite.sh +++ b/test/units/testsuite-18.sh diff --git a/test/units/testsuite-19.service b/test/units/testsuite-19.service new file mode 100644 index 0000000000..d6ad5beded --- /dev/null +++ b/test/units/testsuite-19.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-19-DELEGATE + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-19-DELEGATE/testsuite.sh b/test/units/testsuite-19.sh index 57831c267f..57831c267f 100755 --- a/test/TEST-19-DELEGATE/testsuite.sh +++ b/test/units/testsuite-19.sh diff --git a/test/units/testsuite-20.service b/test/units/testsuite-20.service new file mode 100644 index 0000000000..d31d531175 --- /dev/null +++ b/test/units/testsuite-20.service @@ -0,0 +1,10 @@ +[Unit] +Description=TEST-20-MAINPIDGAMES +Before=getty-pre.target +Wants=getty-pre.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot +NotifyAccess=all diff --git a/test/TEST-20-MAINPIDGAMES/testsuite.sh b/test/units/testsuite-20.sh index f894026070..d94f6b2afb 100755 --- a/test/TEST-20-MAINPIDGAMES/testsuite.sh +++ b/test/units/testsuite-20.sh @@ -5,7 +5,7 @@ set -o pipefail systemd-analyze log-level debug systemd-analyze log-target console -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ # Start a test process inside of our own cgroup sleep infinity & @@ -13,48 +13,48 @@ INTERNALPID=$! disown # Start a test process outside of our own cgroup -systemd-run -p DynamicUser=1 --unit=sleep.service /bin/sleep infinity -EXTERNALPID=`systemctl show -p MainPID --value sleep.service` +systemd-run -p DynamicUser=1 --unit=test20-sleep.service /bin/sleep infinity +EXTERNALPID=`systemctl show -P MainPID test20-sleep.service` # Update our own main PID to the external test PID, this should work systemd-notify MAINPID=$EXTERNALPID -test `systemctl show -p MainPID --value testsuite.service` -eq $EXTERNALPID +test `systemctl show -P MainPID testsuite-20.service` -eq $EXTERNALPID # Update our own main PID to the internal test PID, this should work, too systemd-notify MAINPID=$INTERNALPID -test `systemctl show -p MainPID --value testsuite.service` -eq $INTERNALPID +test `systemctl show -P MainPID testsuite-20.service` -eq $INTERNALPID # Update it back to our own PID, this should also work systemd-notify MAINPID=$$ -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ # Try to set it to PID 1, which it should ignore, because that's the manager systemd-notify MAINPID=1 -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ # Try to set it to PID 0, which is invalid and should be ignored systemd-notify MAINPID=0 -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ # Try to set it to a valid but non-existing PID, which should be ignored. (Note # that we set the PID to a value well above any known /proc/sys/kernel/pid_max, # which means we can be pretty sure it doesn't exist by coincidence) systemd-notify MAINPID=1073741824 -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ # Change it again to the external PID, without privileges this time. This should be ignored, because the PID is from outside of our cgroup and we lack privileges. systemd-notify --uid=1000 MAINPID=$EXTERNALPID -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ # Change it again to the internal PID, without privileges this time. This should work, as the process is on our cgroup, and that's enough even if we lack privileges. systemd-notify --uid=1000 MAINPID=$INTERNALPID -test `systemctl show -p MainPID --value testsuite.service` -eq $INTERNALPID +test `systemctl show -P MainPID testsuite-20.service` -eq $INTERNALPID # Update it back to our own PID, this should also work systemd-notify --uid=1000 MAINPID=$$ -test `systemctl show -p MainPID --value testsuite.service` -eq $$ +test `systemctl show -P MainPID testsuite-20.service` -eq $$ -cat >/tmp/mainpid.sh <<EOF +cat >/tmp/test20-mainpid.sh <<EOF #!/usr/bin/env bash set -eux @@ -73,12 +73,12 @@ disown echo \$MAINPID > /run/mainpidsh/pid EOF -chmod +x /tmp/mainpid.sh +chmod +x /tmp/test20-mainpid.sh -systemd-run --unit=mainpidsh.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh -p PIDFile=/run/mainpidsh/pid /tmp/mainpid.sh -test `systemctl show -p MainPID --value mainpidsh.service` -eq `cat /run/mainpidsh/pid` +systemd-run --unit=test20-mainpidsh.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh -p PIDFile=/run/mainpidsh/pid /tmp/test20-mainpid.sh +test `systemctl show -P MainPID test20-mainpidsh.service` -eq `cat /run/mainpidsh/pid` -cat >/tmp/mainpid2.sh <<EOF +cat >/tmp/test20-mainpid2.sh <<EOF #!/usr/bin/env bash set -eux @@ -98,12 +98,12 @@ disown echo \$MAINPID > /run/mainpidsh2/pid chown 1001:1001 /run/mainpidsh2/pid EOF -chmod +x /tmp/mainpid2.sh +chmod +x /tmp/test20-mainpid2.sh -systemd-run --unit=mainpidsh2.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh2 -p PIDFile=/run/mainpidsh2/pid /tmp/mainpid2.sh -test `systemctl show -p MainPID --value mainpidsh2.service` -eq `cat /run/mainpidsh2/pid` +systemd-run --unit=test20-mainpidsh2.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh2 -p PIDFile=/run/mainpidsh2/pid /tmp/test20-mainpid2.sh +test `systemctl show -P MainPID test20-mainpidsh2.service` -eq `cat /run/mainpidsh2/pid` -cat >/dev/shm/mainpid3.sh <<EOF +cat >/dev/shm/test20-mainpid3.sh <<EOF #!/usr/bin/env bash set -eux @@ -124,13 +124,13 @@ ln -s ../mainpidsh/pid /run/mainpidsh3/pid # Quick assertion that the link isn't dead test -f /run/mainpidsh3/pid EOF -chmod 755 /dev/shm/mainpid3.sh +chmod 755 /dev/shm/test20-mainpid3.sh # This has to fail, as we shouldn't accept the dangerous PID file, and then inotify-wait on it to be corrected which we never do -! systemd-run --unit=mainpidsh3.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh3 -p PIDFile=/run/mainpidsh3/pid -p DynamicUser=1 -p TimeoutStartSec=2s /dev/shm/mainpid3.sh +! systemd-run --unit=test20-mainpidsh3.service -p StandardOutput=tty -p StandardError=tty -p Type=forking -p RuntimeDirectory=mainpidsh3 -p PIDFile=/run/mainpidsh3/pid -p DynamicUser=1 -p TimeoutStartSec=2s /dev/shm/test20-mainpid3.sh # Test that this failed due to timeout, and not some other error -test `systemctl show -p Result --value mainpidsh3.service` = timeout +test `systemctl show -P Result test20-mainpidsh3.service` = timeout systemd-analyze log-level info diff --git a/test/TEST-22-TMPFILES/test-01.sh b/test/units/testsuite-22.01.sh index d233e37fb2..d233e37fb2 100755 --- a/test/TEST-22-TMPFILES/test-01.sh +++ b/test/units/testsuite-22.01.sh diff --git a/test/TEST-22-TMPFILES/test-02.sh b/test/units/testsuite-22.02.sh index d1bf1ea04b..d1bf1ea04b 100755 --- a/test/TEST-22-TMPFILES/test-02.sh +++ b/test/units/testsuite-22.02.sh diff --git a/test/TEST-22-TMPFILES/test-03.sh b/test/units/testsuite-22.03.sh index 8d009fb5bb..8d009fb5bb 100755 --- a/test/TEST-22-TMPFILES/test-03.sh +++ b/test/units/testsuite-22.03.sh diff --git a/test/TEST-22-TMPFILES/test-04.sh b/test/units/testsuite-22.04.sh index f916086b1e..f916086b1e 100755 --- a/test/TEST-22-TMPFILES/test-04.sh +++ b/test/units/testsuite-22.04.sh diff --git a/test/TEST-22-TMPFILES/test-05.sh b/test/units/testsuite-22.05.sh index 13c4ac80fc..13c4ac80fc 100755 --- a/test/TEST-22-TMPFILES/test-05.sh +++ b/test/units/testsuite-22.05.sh diff --git a/test/TEST-22-TMPFILES/test-06.sh b/test/units/testsuite-22.06.sh index cd65ba6726..cd65ba6726 100755 --- a/test/TEST-22-TMPFILES/test-06.sh +++ b/test/units/testsuite-22.06.sh diff --git a/test/TEST-22-TMPFILES/test-07.sh b/test/units/testsuite-22.07.sh index 39c04b925c..39c04b925c 100755 --- a/test/TEST-22-TMPFILES/test-07.sh +++ b/test/units/testsuite-22.07.sh diff --git a/test/TEST-22-TMPFILES/test-08.sh b/test/units/testsuite-22.08.sh index e7bf044783..e7bf044783 100755 --- a/test/TEST-22-TMPFILES/test-08.sh +++ b/test/units/testsuite-22.08.sh diff --git a/test/TEST-22-TMPFILES/test-09.sh b/test/units/testsuite-22.09.sh index c558dfd4db..c558dfd4db 100755 --- a/test/TEST-22-TMPFILES/test-09.sh +++ b/test/units/testsuite-22.09.sh diff --git a/test/TEST-22-TMPFILES/testsuite.service b/test/units/testsuite-22.service index 2f1b15c3ed..55e3056d53 100644 --- a/test/TEST-22-TMPFILES/testsuite.service +++ b/test/units/testsuite-22.service @@ -1,12 +1,12 @@ [Unit] -Description=Testsuite service +Description=TEST-22-TMPFILES After=systemd-tmpfiles-setup.service Before=getty-pre.target Wants=getty-pre.target [Service] -WorkingDirectory=/testsuite -ExecStart=/testsuite/run-tmpfiles-tests.sh +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh Type=oneshot StandardOutput=tty StandardError=tty diff --git a/test/TEST-22-TMPFILES/run-tmpfiles-tests.sh b/test/units/testsuite-22.sh index a0158f0421..afce85aceb 100755 --- a/test/TEST-22-TMPFILES/run-tmpfiles-tests.sh +++ b/test/units/testsuite-22.sh @@ -5,8 +5,8 @@ set -e >/failed -for t in test-*.sh; do - echo "Running $t"; ./$t +for t in ${0%.sh}.*.sh; do + echo "Running $t"; ./$t done touch /testok diff --git a/test/units/testsuite-23.service b/test/units/testsuite-23.service new file mode 100644 index 0000000000..b3b3297af8 --- /dev/null +++ b/test/units/testsuite-23.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-23-TYPE-EXEC + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-23-TYPE-EXEC/testsuite.sh b/test/units/testsuite-23.sh index 5e2966f848..5e2966f848 100755 --- a/test/TEST-23-TYPE-EXEC/testsuite.sh +++ b/test/units/testsuite-23.sh diff --git a/test/units/testsuite-24.service b/test/units/testsuite-24.service new file mode 100644 index 0000000000..43d4816d48 --- /dev/null +++ b/test/units/testsuite-24.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-24-UNIT-TESTS + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-24-UNIT-TESTS/testsuite.sh b/test/units/testsuite-24.sh index cc78adbbe9..1ff1c3347b 100755 --- a/test/TEST-24-UNIT-TESTS/testsuite.sh +++ b/test/units/testsuite-24.sh @@ -6,6 +6,9 @@ NPROC=$(nproc) MAX_QUEUE_SIZE=${NPROC:-2} IFS=$'\n' TEST_LIST=($(ls /usr/lib/systemd/tests/test-*)) +# reset state +rm /failed-tests /skipped-tests /skipped + # Check & report test results # Arguments: # $1: test path @@ -21,23 +24,23 @@ function report_result() { if [[ $ret -ne 0 && $ret != 77 ]]; then echo "$name failed with $ret" - echo "$name" >> /failed-tests + echo "$name" >>/failed-tests { echo "--- $name begin ---" cat "/$name.log" echo "--- $name end ---" - } >> /failed + } >>/failed elif [[ $ret == 77 ]]; then echo "$name skipped" - echo "$name" >> /skipped-tests + echo "$name" >>/skipped-tests { echo "--- $name begin ---" cat "/$name.log" echo "--- $name end ---" - } >> /skipped + } >>/skipped else echo "$name OK" - echo "$name" >> /testok + echo "$name" >>/testok fi systemd-cat echo "--- $name ---" @@ -69,7 +72,7 @@ for task in "${TEST_LIST[@]}"; do if [[ -x $task ]]; then log_file="/${task##*/}.log" - $task &> "$log_file" & + $task &>"$log_file" & running[$task]=$! fi done diff --git a/test/units/testsuite-25.service b/test/units/testsuite-25.service new file mode 100644 index 0000000000..45d8b6945f --- /dev/null +++ b/test/units/testsuite-25.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-25-IMPORT + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-25-IMPORT/testsuite.sh b/test/units/testsuite-25.sh index 6dcb780508..2558d5bf4c 100755 --- a/test/TEST-25-IMPORT/testsuite.sh +++ b/test/units/testsuite-25.sh @@ -133,6 +133,11 @@ rm -rf /var/tmp/extract rm -rf /var/tmp/scratch +# Test removal +machinectl remove scratch5 +! test -f /var/lib/machines/scratch5 +! machinectl image-status scratch5 + echo OK > /testok exit 0 diff --git a/test/units/testsuite-26.service b/test/units/testsuite-26.service new file mode 100644 index 0000000000..65b66835ed --- /dev/null +++ b/test/units/testsuite-26.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-26-SETENV + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-26-SETENV/testsuite.sh b/test/units/testsuite-26.sh index 89c0937c8d..89c0937c8d 100755 --- a/test/TEST-26-SETENV/testsuite.sh +++ b/test/units/testsuite-26.sh diff --git a/test/units/testsuite-27.service b/test/units/testsuite-27.service new file mode 100644 index 0000000000..52185f0572 --- /dev/null +++ b/test/units/testsuite-27.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-27-STDOUTFILE + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-27-STDOUTFILE/testsuite.sh b/test/units/testsuite-27.sh index c522f75dbc..9d92e6e574 100755 --- a/test/TEST-27-STDOUTFILE/testsuite.sh +++ b/test/units/testsuite-27.sh @@ -5,7 +5,7 @@ set -o pipefail systemd-analyze log-level debug systemd-analyze log-target console -systemd-run --wait --unit=one \ +systemd-run --wait --unit=test27-one \ -p StandardOutput=file:/tmp/stdout \ -p StandardError=file:/tmp/stderr \ -p Type=exec \ @@ -17,7 +17,7 @@ cmp /tmp/stderr <<EOF y EOF -systemd-run --wait --unit=two \ +systemd-run --wait --unit=test27-two \ -p StandardOutput=file:/tmp/stdout \ -p StandardError=file:/tmp/stderr \ -p Type=exec \ @@ -29,7 +29,7 @@ cmp /tmp/stderr <<EOF a EOF -systemd-run --wait --unit=three \ +systemd-run --wait --unit=test27-three \ -p StandardOutput=append:/tmp/stdout \ -p StandardError=append:/tmp/stderr \ -p Type=exec \ @@ -45,6 +45,6 @@ EOF systemd-analyze log-level info -echo OK > /testok +echo OK >/testok exit 0 diff --git a/test/units/testsuite-28.service b/test/units/testsuite-28.service new file mode 100644 index 0000000000..7ea8630011 --- /dev/null +++ b/test/units/testsuite-28.service @@ -0,0 +1,11 @@ +[Unit] +Description=TEST-28-PERCENTJ-WANTEDBY +# Testsuite: Ensure %j Wants directives work +Wants=specifier-j-wants.service +After=specifier-j-wants.service +Requires=testsuite-28-pre.service +After=testsuite-28-pre.service + +[Service] +ExecStart=true +Type=oneshot diff --git a/test/units/testsuite-29.service b/test/units/testsuite-29.service new file mode 100644 index 0000000000..90c2187bd7 --- /dev/null +++ b/test/units/testsuite-29.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-29-UDEV-ID_RENAMING + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-29-UDEV-ID_RENAMING/testsuite.sh b/test/units/testsuite-29.sh index 5abdb53eb3..5abdb53eb3 100755 --- a/test/TEST-29-UDEV-ID_RENAMING/testsuite.sh +++ b/test/units/testsuite-29.sh diff --git a/test/units/testsuite-30.service b/test/units/testsuite-30.service new file mode 100644 index 0000000000..eb342f3d17 --- /dev/null +++ b/test/units/testsuite-30.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-30-ONCLOCKCHANGE + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-30-ONCLOCKCHANGE/testsuite.sh b/test/units/testsuite-30.sh index a507ffcd7b..a507ffcd7b 100755 --- a/test/TEST-30-ONCLOCKCHANGE/testsuite.sh +++ b/test/units/testsuite-30.sh diff --git a/test/units/testsuite-31.service b/test/units/testsuite-31.service new file mode 100644 index 0000000000..07dfb0bb54 --- /dev/null +++ b/test/units/testsuite-31.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-31-DEVICE-ENUMERATION + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-31-DEVICE-ENUMERATION/testsuite.sh b/test/units/testsuite-31.sh index fcff82d804..fcff82d804 100755 --- a/test/TEST-31-DEVICE-ENUMERATION/testsuite.sh +++ b/test/units/testsuite-31.sh diff --git a/test/units/testsuite-32.service b/test/units/testsuite-32.service new file mode 100644 index 0000000000..aab95cb741 --- /dev/null +++ b/test/units/testsuite-32.service @@ -0,0 +1,8 @@ +[Unit] +Description=TEST-32-OOMPOLICY + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot +MemoryAccounting=yes diff --git a/test/TEST-32-OOMPOLICY/testsuite.sh b/test/units/testsuite-32.sh index aafafc1183..c1704ab34e 100755 --- a/test/TEST-32-OOMPOLICY/testsuite.sh +++ b/test/units/testsuite-32.sh @@ -8,30 +8,32 @@ set -o pipefail # an easier thing to test for, and also: let's not get confused by older # kernels where the concept was still new. -if test -f /sys/fs/cgroup/system.slice/testsuite.service/memory.oom.group ; then +if test -f /sys/fs/cgroup/system.slice/testsuite-32.service/memory.oom.group; then systemd-analyze log-level debug systemd-analyze log-target console # Run a service that is guaranteed to be the first candidate for OOM killing - systemd-run --unit=oomtest.service -p Type=exec -p OOMScoreAdjust=1000 -p OOMPolicy=stop -p MemoryAccounting=yes /bin/sleep infinity + systemd-run --unit=oomtest.service \ + -p Type=exec -p OOMScoreAdjust=1000 -p OOMPolicy=stop -p MemoryAccounting=yes \ + sleep infinity # Trigger an OOM killer run - echo 1 > /proc/sys/kernel/sysrq - echo f > /proc/sysrq-trigger + echo 1 >/proc/sys/kernel/sysrq + echo f >/proc/sysrq-trigger while : ; do - STATE=`systemctl show -p ActiveState --value oomtest.service` + STATE=`systemctl show -P ActiveState oomtest.service` [ "$STATE" = "failed" ] && break sleep .5 done - RESULT=`systemctl show -p Result --value oomtest.service` + RESULT=`systemctl show -P Result oomtest.service` test "$RESULT" = "oom-kill" systemd-analyze log-level info fi -echo OK > /testok +echo OK >/testok exit 0 diff --git a/test/units/testsuite-33.service b/test/units/testsuite-33.service new file mode 100644 index 0000000000..b64f1e0b79 --- /dev/null +++ b/test/units/testsuite-33.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-33-CLEAN-UNIT + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-33-CLEAN-UNIT/testsuite.sh b/test/units/testsuite-33.sh index 0a6ee57b99..0a6ee57b99 100755 --- a/test/TEST-33-CLEAN-UNIT/testsuite.sh +++ b/test/units/testsuite-33.sh diff --git a/test/units/testsuite-34.service b/test/units/testsuite-34.service new file mode 100644 index 0000000000..361e328221 --- /dev/null +++ b/test/units/testsuite-34.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-34-DYNAMICUSERMIGRATE + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-34-DYNAMICUSERMIGRATE/testsuite.sh b/test/units/testsuite-34.sh index 6d9488688a..6d9488688a 100755 --- a/test/TEST-34-DYNAMICUSERMIGRATE/testsuite.sh +++ b/test/units/testsuite-34.sh diff --git a/test/units/testsuite-36.service b/test/units/testsuite-36.service new file mode 100644 index 0000000000..a681153ee4 --- /dev/null +++ b/test/units/testsuite-36.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-36-NUMAPOLICY + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-36-NUMAPOLICY/testsuite.sh b/test/units/testsuite-36.sh index bd04bb2efe..d04751b3f0 100755 --- a/test/TEST-36-NUMAPOLICY/testsuite.sh +++ b/test/units/testsuite-36.sh @@ -22,7 +22,7 @@ journalLog='journal.log' # Systemd config files testUnit='numa-test.service' -testUnitFile="/etc/systemd/system/$testUnit" +testUnitFile="/run/systemd/system/$testUnit" testUnitNUMAConf="$testUnitFile.d/numa.conf" # Sleep constants (we should probably figure out something better but nothing comes to mind) @@ -70,9 +70,9 @@ writePID1NUMAPolicy() { } writeTestUnit() { + mkdir -p $testUnitFile.d/ echo [Service] > $testUnitFile echo ExecStart=/bin/sleep 3600 >> $testUnitFile - mkdir -p $testUnitFile.d/ } writeTestUnitNUMAPolicy() { @@ -129,7 +129,7 @@ systemctlCheckNUMAProperties() { writeTestUnit # Create systemd config drop-in directory -confDir="/etc/systemd/system.conf.d/" +confDir="/run/systemd/system.conf.d/" mkdir -p "$confDir" if ! checkNUMA; then diff --git a/test/units/testsuite-37.service b/test/units/testsuite-37.service new file mode 100644 index 0000000000..d25c6d2cf9 --- /dev/null +++ b/test/units/testsuite-37.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-37-RUNTIMEDIRECTORYPRESERVE + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-37-RUNTIMEDIRECTORYPRESERVE/testsuite.sh b/test/units/testsuite-37.sh index 32a9dd8694..32a9dd8694 100755 --- a/test/TEST-37-RUNTIMEDIRECTORYPRESERVE/testsuite.sh +++ b/test/units/testsuite-37.sh diff --git a/test/units/testsuite-39.service b/test/units/testsuite-39.service new file mode 100644 index 0000000000..395fe803e7 --- /dev/null +++ b/test/units/testsuite-39.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-39-EXECRELOAD + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-39-EXECRELOAD/testsuite.sh b/test/units/testsuite-39.sh index eb7363fa6a..eb7363fa6a 100644..100755 --- a/test/TEST-39-EXECRELOAD/testsuite.sh +++ b/test/units/testsuite-39.sh diff --git a/test/units/testsuite-40.service b/test/units/testsuite-40.service new file mode 100644 index 0000000000..38b0bd80d1 --- /dev/null +++ b/test/units/testsuite-40.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-40-EXEC-COMMAND-EX + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-40-EXEC-COMMAND-EX/testsuite.sh b/test/units/testsuite-40.sh index 957d22031a..957d22031a 100755 --- a/test/TEST-40-EXEC-COMMAND-EX/testsuite.sh +++ b/test/units/testsuite-40.sh diff --git a/test/units/testsuite-41.service b/test/units/testsuite-41.service new file mode 100644 index 0000000000..766cb4c99a --- /dev/null +++ b/test/units/testsuite-41.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-41-ONESHOT-RESTART + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-41-ONESHOT-RESTART/testsuite.sh b/test/units/testsuite-41.sh index 905f32e994..81fa1716f1 100755 --- a/test/TEST-41-ONESHOT-RESTART/testsuite.sh +++ b/test/units/testsuite-41.sh @@ -12,16 +12,16 @@ systemd-analyze log-target console ! systemd-run --unit=one -p Type=oneshot -p Restart=on-failure /bin/bash -c "exit 1" for ((secs=0; secs<$MAX_SECS; secs++)); do - [[ "$(systemctl show one.service -p NRestarts --value)" -le 0 ]] || break + [[ "$(systemctl show one.service -P NRestarts)" -le 0 ]] || break sleep 1 done -if [[ "$(systemctl show one.service -p NRestarts --value)" -le 0 ]]; then +if [[ "$(systemctl show one.service -P NRestarts)" -le 0 ]]; then exit 1 fi -TMP_FILE="/test-41-oneshot-restart-test" +TMP_FILE="/tmp/test-41-oneshot-restart-test" -touch $TMP_FILE +: >$TMP_FILE # test two: make sure StartLimitBurst correctly limits the number of restarts # and restarts execution of the unit from the first ExecStart= diff --git a/test/units/testsuite-42.service b/test/units/testsuite-42.service new file mode 100644 index 0000000000..a5504b515d --- /dev/null +++ b/test/units/testsuite-42.service @@ -0,0 +1,9 @@ +[Unit] +Description=TEST-42-EXECSTOPPOST +Before=getty-pre.target +Wants=getty-pre.target + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-42-EXECSTOPPOST/testsuite.sh b/test/units/testsuite-42.sh index 154398dd66..154398dd66 100755 --- a/test/TEST-42-EXECSTOPPOST/testsuite.sh +++ b/test/units/testsuite-42.sh diff --git a/test/units/testsuite-43.service b/test/units/testsuite-43.service new file mode 100644 index 0000000000..31248f17e8 --- /dev/null +++ b/test/units/testsuite-43.service @@ -0,0 +1,9 @@ +[Unit] +Description=TEST-43-PRIVATEUSER-UNPRIV +After=systemd-logind.service user@4711.service +Wants=user@4711.service + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-43-PRIVATEUSER-UNPRIV/testsuite.sh b/test/units/testsuite-43.sh index ff94ad4d81..ff94ad4d81 100755 --- a/test/TEST-43-PRIVATEUSER-UNPRIV/testsuite.sh +++ b/test/units/testsuite-43.sh diff --git a/test/units/testsuite-44.service b/test/units/testsuite-44.service new file mode 100644 index 0000000000..bd4dd728aa --- /dev/null +++ b/test/units/testsuite-44.service @@ -0,0 +1,12 @@ +[Unit] +Description=TESTSUITE-44-LOG-NAMESPACE +Before=getty-pre.target +Wants=getty-pre.target +Wants=systemd-journald@foobar.socket systemd-journald-varlink@foobar.socket +After=systemd-journald@foobar.socket systemd-journald-varlink@foobar.socket + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot +LogTarget=foobar diff --git a/test/TEST-44-LOG-NAMESPACE/testsuite.sh b/test/units/testsuite-44.sh index 97541634d0..97541634d0 100755 --- a/test/TEST-44-LOG-NAMESPACE/testsuite.sh +++ b/test/units/testsuite-44.sh diff --git a/test/units/testsuite-46.service b/test/units/testsuite-46.service new file mode 100644 index 0000000000..7698f35979 --- /dev/null +++ b/test/units/testsuite-46.service @@ -0,0 +1,12 @@ +[Unit] +Description=TEST-46-HOMED +Wants=getty-pre.target +Before=getty-pre.target +Wants=systemd-homed.service +After=systemd-homed.service + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot +NotifyAccess=all diff --git a/test/TEST-46-HOMED/testsuite.sh b/test/units/testsuite-46.sh index 9ef9f30f1e..9ef9f30f1e 100755 --- a/test/TEST-46-HOMED/testsuite.sh +++ b/test/units/testsuite-46.sh diff --git a/test/units/testsuite-47-repro.service b/test/units/testsuite-47-repro.service new file mode 100644 index 0000000000..655eea68e5 --- /dev/null +++ b/test/units/testsuite-47-repro.service @@ -0,0 +1,7 @@ +[Unit] +Description=Issue 14566 Repro + +[Service] +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +ExecStopPost=/bin/true +KillMode=mixed diff --git a/test/TEST-47-ISSUE-14566/repro.sh b/test/units/testsuite-47-repro.sh index 5217602257..8c34289c52 100755 --- a/test/TEST-47-ISSUE-14566/repro.sh +++ b/test/units/testsuite-47-repro.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash sleep infinity & echo $! > /leakedtestpid diff --git a/test/units/testsuite-47.service b/test/units/testsuite-47.service new file mode 100644 index 0000000000..3816c57eed --- /dev/null +++ b/test/units/testsuite-47.service @@ -0,0 +1,7 @@ +[Unit] +Description=TEST-47-ISSUE-14566 + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/units/testsuite-47.sh index a0ba32530e..09be780a68 100755 --- a/test/TEST-47-ISSUE-14566/testsuite.sh +++ b/test/units/testsuite-47.sh @@ -1,17 +1,17 @@ -#!/bin/bash +#!/usr/bin/env bash set -ex set -o pipefail systemd-analyze log-level debug systemd-analyze log-target console -systemctl start issue_14566_test +systemctl start testsuite-47-repro sleep 1 -systemctl status issue_14566_test +systemctl status testsuite-47-repro leaked_pid=$(cat /leakedtestpid) -systemctl stop issue_14566_test +systemctl stop testsuite-47-repro # Leaked PID will still be around if we're buggy. # I personally prefer to see 42. diff --git a/test/testsuite.target b/test/units/testsuite.target index 1a7e5b371a..1a7e5b371a 100644 --- a/test/testsuite.target +++ b/test/units/testsuite.target diff --git a/test/units/timers.target b/test/units/timers.target new file mode 100644 index 0000000000..b1aa8c797c --- /dev/null +++ b/test/units/timers.target @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Timers +Documentation=man:systemd.special(7) + +DefaultDependencies=no +Conflicts=shutdown.target diff --git a/test/unit-.service.d/10-override.conf b/test/units/unit-.service.d/10-override.conf index 916737d415..916737d415 100644 --- a/test/unit-.service.d/10-override.conf +++ b/test/units/unit-.service.d/10-override.conf diff --git a/test/unit-with-.service.d/20-override.conf b/test/units/unit-with-.service.d/20-override.conf index c6c2438f73..c6c2438f73 100644 --- a/test/unit-with-.service.d/20-override.conf +++ b/test/units/unit-with-.service.d/20-override.conf diff --git a/test/unit-with-multiple-.service.d/20-override.conf b/test/units/unit-with-multiple-.service.d/20-override.conf index 62fafd2e3b..62fafd2e3b 100644 --- a/test/unit-with-multiple-.service.d/20-override.conf +++ b/test/units/unit-with-multiple-.service.d/20-override.conf diff --git a/test/unit-with-multiple-.service.d/30-override.conf b/test/units/unit-with-multiple-.service.d/30-override.conf index b9616da8a8..b9616da8a8 100644 --- a/test/unit-with-multiple-.service.d/30-override.conf +++ b/test/units/unit-with-multiple-.service.d/30-override.conf diff --git a/test/unit-with-multiple-dashes.service b/test/units/unit-with-multiple-dashes.service index b38b3604b8..b38b3604b8 100644 --- a/test/unit-with-multiple-dashes.service +++ b/test/units/unit-with-multiple-dashes.service diff --git a/test/unit-with-multiple-dashes.service.d/10-override.conf b/test/units/unit-with-multiple-dashes.service.d/10-override.conf index 982c3621a6..982c3621a6 100644 --- a/test/unit-with-multiple-dashes.service.d/10-override.conf +++ b/test/units/unit-with-multiple-dashes.service.d/10-override.conf diff --git a/test/unstoppable.service b/test/units/unstoppable.service index 56b72c98f7..56b72c98f7 100644 --- a/test/unstoppable.service +++ b/test/units/unstoppable.service diff --git a/tools/meson-make-symlink.sh b/tools/meson-make-symlink.sh index da0d13a341..cdd5214125 100755 --- a/tools/meson-make-symlink.sh +++ b/tools/meson-make-symlink.sh @@ -5,8 +5,8 @@ set -eu # and we need to create the target directory... mkdir -vp "$(dirname "${DESTDIR:-}$2")" -if [ "$(dirname $1)" = . ]; then - ln -vfs -T "$1" "${DESTDIR:-}$2" +if [ "$(dirname $1)" = . -o "$(dirname $1)" = .. ]; then + ln -vfs -T -- "$1" "${DESTDIR:-}$2" else - ln -vfs -T --relative "${DESTDIR:-}$1" "${DESTDIR:-}$2" + ln -vfs -T --relative -- "${DESTDIR:-}$1" "${DESTDIR:-}$2" fi diff --git a/travis-ci/managers/fuzzbuzz.sh b/travis-ci/managers/fuzzbuzz.sh index c841af1214..295fc03613 100755 --- a/travis-ci/managers/fuzzbuzz.sh +++ b/travis-ci/managers/fuzzbuzz.sh @@ -20,11 +20,6 @@ tools/oss-fuzz.sh ./out/fuzz-unit-file -max_total_time=5 git clean -dxff -wget https://app.fuzzbuzz.io/releases/cli/latest/linux/fuzzbuzz -chmod +x fuzzbuzz -./fuzzbuzz validate -./fuzzbuzz target test fuzz-unit-file --all - git clone https://github.com/google/oss-fuzz /tmp/oss-fuzz cd /tmp/oss-fuzz sudo ./infra/helper.py pull_images diff --git a/travis-ci/managers/fuzzit.sh b/travis-ci/managers/fuzzit.sh index c3d76134fe..6c487de6ed 100755 --- a/travis-ci/managers/fuzzit.sh +++ b/travis-ci/managers/fuzzit.sh @@ -13,10 +13,10 @@ REPO_ROOT=${REPO_ROOT:-$(pwd)} sudo bash -c "echo 'deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse' >>/etc/apt/sources.list" sudo apt-get update -y sudo apt-get build-dep systemd -y -sudo apt-get install -y ninja-build python3-pip python3-setuptools +sudo apt-get install -y python3-pip python3-setuptools # The following should be dropped when debian packaging has been updated to include them sudo apt-get install -y libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev -pip3 install meson +pip3 install ninja meson cd $REPO_ROOT export PATH="$HOME/.local/bin/:$PATH" diff --git a/units/meson.build b/units/meson.build index ea91f0cc9e..ba3abc29ea 100644 --- a/units/meson.build +++ b/units/meson.build @@ -139,8 +139,7 @@ units = [ 'sysinit.target.wants/'], ['systemd-udevd-kernel.socket', '', 'sockets.target.wants/'], - ['systemd-userdbd.socket', 'ENABLE_USERDB', - 'sockets.target.wants/'], + ['systemd-userdbd.socket', 'ENABLE_USERDB'], ['time-set.target', ''], ['time-sync.target', ''], ['timers.target', ''], @@ -201,8 +200,7 @@ in_units = [ ['systemd-portabled.service', 'ENABLE_PORTABLED', 'dbus-org.freedesktop.portable1.service'], ['systemd-userdbd.service', 'ENABLE_USERDB'], - ['systemd-homed.service', 'ENABLE_HOMED', - 'multi-user.target.wants/ dbus-org.freedesktop.home1.service'], + ['systemd-homed.service', 'ENABLE_HOMED'], ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'], ['systemd-random-seed.service', 'ENABLE_RANDOMSEED', 'sysinit.target.wants/'], diff --git a/units/systemd-homed.service.in b/units/systemd-homed.service.in index 7cf98e6fa6..91dabee034 100644 --- a/units/systemd-homed.service.in +++ b/units/systemd-homed.service.in @@ -10,7 +10,7 @@ [Unit] Description=Home Area Manager Documentation=man:systemd-homed.service(8) -RequiresMountsFor=/home +After=home.mount [Service] BusName=org.freedesktop.home1 @@ -34,3 +34,7 @@ SystemCallArchitectures=native SystemCallErrorNumber=EPERM SystemCallFilter=@system-service @mount @SERVICE_WATCHDOG@ + +[Install] +WantedBy=multi-user.target +Alias=dbus-org.freedesktop.home1.service diff --git a/units/systemd-journal-remote.service.in b/units/systemd-journal-remote.service.in index 6181d15d77..334f030caa 100644 --- a/units/systemd-journal-remote.service.in +++ b/units/systemd-journal-remote.service.in @@ -21,6 +21,7 @@ NoNewPrivileges=yes PrivateDevices=yes PrivateNetwork=yes PrivateTmp=yes +ProtectClock=yes ProtectControlGroups=yes ProtectHome=yes ProtectHostname=yes diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in index 5144868bcb..0cb1bfa3ca 100644 --- a/units/systemd-journald.service.in +++ b/units/systemd-journald.service.in @@ -25,6 +25,7 @@ LockPersonality=yes MemoryDenyWriteExecute=yes NoNewPrivileges=yes OOMScoreAdjust=-250 +ProtectClock=yes Restart=always RestartSec=0 RestrictAddressFamilies=AF_UNIX AF_NETLINK diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in index 23aa828591..ed573b8f3c 100644 --- a/units/systemd-logind.service.in +++ b/units/systemd-logind.service.in @@ -36,6 +36,7 @@ LockPersonality=yes MemoryDenyWriteExecute=yes NoNewPrivileges=yes PrivateTmp=yes +ProtectClock=yes ProtectControlGroups=yes ProtectHome=yes ProtectHostname=yes diff --git a/units/systemd-network-generator.service.in b/units/systemd-network-generator.service.in index 070d87e154..248a8dc64e 100644 --- a/units/systemd-network-generator.service.in +++ b/units/systemd-network-generator.service.in @@ -12,6 +12,7 @@ Description=Generate network units from Kernel command line Documentation=man:systemd-network-generator.service(8) DefaultDependencies=no Before=network-pre.target +Wants=network-pre.target [Service] Type=oneshot @@ -19,4 +20,4 @@ RemainAfterExit=yes ExecStart=@rootlibexecdir@/systemd-network-generator [Install] -WantedBy=network-pre.target +WantedBy=sysinit.target diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in index 1b69677496..2673146841 100644 --- a/units/systemd-networkd.service.in +++ b/units/systemd-networkd.service.in @@ -26,6 +26,7 @@ ExecStart=!!@rootlibexecdir@/systemd-networkd LockPersonality=yes MemoryDenyWriteExecute=yes NoNewPrivileges=yes +ProtectClock=yes ProtectControlGroups=yes ProtectHome=yes ProtectKernelModules=yes diff --git a/units/systemd-repart.service.in b/units/systemd-repart.service.in index 7ce6aefd29..9393a64f00 100644 --- a/units/systemd-repart.service.in +++ b/units/systemd-repart.service.in @@ -15,11 +15,15 @@ Conflicts=shutdown.target After=sysroot.mount Before=initrd-root-fs.target shutdown.target ConditionVirtualization=!container +ConditionDirectoryNotEmpty=|/usr/lib/repart.d +ConditionDirectoryNotEmpty=|/usr/local/lib/repart.d +ConditionDirectoryNotEmpty=|/etc/repart.d +ConditionDirectoryNotEmpty=|/run/repart.d [Service] Type=oneshot RemainAfterExit=yes ExecStart=@rootbindir@/systemd-repart --dry-run=no -# The tool returns 77 if there's no GPT partition table pre-existing +# The tool returns 77 if there's no existing GPT partition table SuccessExitStatus=77 diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in index f73697832c..5723f1c1e2 100644 --- a/units/systemd-resolved.service.in +++ b/units/systemd-resolved.service.in @@ -28,6 +28,7 @@ MemoryDenyWriteExecute=yes NoNewPrivileges=yes PrivateDevices=yes PrivateTmp=yes +ProtectClock=yes ProtectControlGroups=yes ProtectHome=yes ProtectKernelModules=yes diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in index 5eee69933b..f3ebaa18a6 100644 --- a/units/systemd-udevd.service.in +++ b/units/systemd-udevd.service.in @@ -16,6 +16,8 @@ Before=sysinit.target ConditionPathIsReadWrite=/sys [Service] +DeviceAllow=block-* rwm +DeviceAllow=char-* rwm Type=notify # Note that udev also adjusts the OOM score internally and will reset the value internally for its workers OOMScoreAdjust=-1000 @@ -27,6 +29,7 @@ ExecReload=udevadm control --reload --timeout 0 KillMode=mixed TasksMax=infinity PrivateMounts=yes +ProtectClock=yes ProtectHostname=yes MemoryDenyWriteExecute=yes RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 diff --git a/units/systemd-userdbd.service.in b/units/systemd-userdbd.service.in index e30ed2109e..3b76705373 100644 --- a/units/systemd-userdbd.service.in +++ b/units/systemd-userdbd.service.in @@ -39,3 +39,6 @@ SystemCallErrorNumber=EPERM SystemCallFilter=@system-service Type=notify @SERVICE_WATCHDOG@ + +[Install] +Also=systemd-userdbd.socket diff --git a/units/systemd-userdbd.socket b/units/systemd-userdbd.socket index 1c749ea1d2..2b4bb7a87a 100644 --- a/units/systemd-userdbd.socket +++ b/units/systemd-userdbd.socket @@ -17,3 +17,6 @@ Before=sockets.target ListenStream=/run/systemd/userdb/io.systemd.Multiplexer Symlinks=/run/systemd/userdb/io.systemd.NameServiceSwitch SocketMode=0666 + +[Install] +WantedBy=sockets.target |