Compare commits

...

46 Commits

Author SHA1 Message Date
Lennart Poettering 8c5616d7f4
Merge e33d1a2222 into a3c2a9ee5d 2024-09-19 16:39:04 +02:00
Yu Watanabe a3c2a9ee5d
Merge pull request #34486 from DaanDeMeyer/test-process-util
test-process-util: Migrate to new assertion macros
2024-09-19 23:28:15 +09:00
Daan De Meyer 062332f3db
Merge pull request #34481 from yuwata/has-tpm2
tpm2-util: several cleanups for tpm2_support()
2024-09-19 16:22:24 +02:00
Daan De Meyer bc9a9177b2
Merge pull request #34483 from yuwata/network-conf-parser-neighbor-nexthop
network: several cleanups for conf parsers
2024-09-19 13:59:56 +02:00
Daan De Meyer e5c6dcac87 test-process-util: Ignore EINVAL from setresuid() and setresgid()
If we're running in a user namespace with a single user and without
the nobody user, we'll get EINVAL from these system calls so make
sure we handle those gracefully.
2024-09-19 13:42:05 +02:00
Daan De Meyer 34a7ca6db2 test-process-util: Use FORK_REOPEN_LOG everywhere we close all fds
To make sure logging works in the child processes.
2024-09-19 13:42:05 +02:00
Daan De Meyer 397820961d test-process-util: Migrate to new assertion macros 2024-09-19 13:42:03 +02:00
Yu Watanabe 3b16e9f419 man/systemd-analyze: mention required libraries for TPM2 support
Closes #34477.
2024-09-19 19:21:08 +09:00
Yu Watanabe d5a7f3b7d4 tpm2-util: colorize output of 'systemd-analyze has-tpm2' 2024-09-19 19:14:19 +09:00
Yu Watanabe f1c16ca6d6 shell-completion/analyze: add has-tpm2 2024-09-19 19:08:49 +09:00
Yu Watanabe b094398b0f tpm2-util: update comment
has-tpm2 command is moved to systemd-analyze.

Follow-up for 58e359604f.
2024-09-19 19:08:10 +09:00
Yu Watanabe 1ee6570843 tpm2-util: do not load tpm2 libraries when not interested in the existence of the libraries
For example, 'bootctl status' only interested in if the efi has TPM2
support and a TPM2 driver is loaded. Hence, not necessary to load
libtss2.
2024-09-19 19:06:46 +09:00
Yu Watanabe b7f051c91d tpm2-util: introduce tpm2_is_fully_supported() 2024-09-19 19:04:15 +09:00
Yu Watanabe a13ead6814
Merge pull request #34479 from yuwata/sd-json-dispatch-field-table-static
tree-wide: make sd_json_dispatch_field table static
2024-09-19 18:59:17 +09:00
Yu Watanabe f901a7b39f network/nexthop: introduce generic conf parser for [NextHop] section 2024-09-19 18:41:47 +09:00
Yu Watanabe 9b01cf0406 network/nexthop: make conf parsers for Family= and Gateway= independent of each other 2024-09-19 18:41:46 +09:00
Yu Watanabe d5aae0713d network/nexthop: use log_section_warning() and friend 2024-09-19 18:40:38 +09:00
Daan De Meyer 1d8a81eb4e Add ASSERT_OK_ZERO_ERRNO() and ASSERT_OK_EQ_ERRNO() 2024-09-19 11:38:47 +02:00
Daan De Meyer 86c1317270
Merge pull request #34474 from DaanDeMeyer/user-group
Two integration test fixes
2024-09-19 09:20:03 +02:00
Daan De Meyer f4faac2073 test: Run TEST-74-AUX-UTILS in virtual machine
Various tests skip themselves when running in a container so make
sure the test runs in a virtual machine so we get full coverage.
2024-09-19 14:56:34 +09:00
Yu Watanabe 2bcc2a89f3 test: create .netdev file at last
Previously, when the test ran on mkosi, then networkd was not masked, and
might be already started. In that case, the interface test2 would be created
soon after the .netdev file is created, and the .link file would not be
applied to the interface. Hence, the later test case for
'networkctl cat @test2:link' would fail.

This make networkd always started at the beginning of the test, and
.netdev file created after .link file is created. So, .link file is
always applied to the interface created by the .netdev file.
2024-09-19 14:50:10 +09:00
Yu Watanabe 07e6a111c0 man: fix typo
Follow-up for 8aee931e7a.
2024-09-19 09:18:47 +09:00
Yu Watanabe c2648f6e23 efi: fix typo
Follow-up for f4e081051d.
2024-09-19 09:14:25 +09:00
Daan De Meyer 1d5b4317cd ci: Don't add testuser to wheel and systemd-journal groups
This breaks TEST-74-AUX-UTILS when run in a VM as the user gets access
to journal files that the test expects it can't access.
2024-09-19 08:47:53 +09:00
Yu Watanabe 8d6eedd8a3 network/neighbor: use log_section_warning_errno() 2024-09-19 04:03:11 +09:00
Yu Watanabe 91eaa90b81 network/neighbor: introduce generic Neighbor section parser 2024-09-19 03:59:34 +09:00
Yu Watanabe 3b5c5da73a network/neighbor: use struct in_addr_data 2024-09-19 03:58:28 +09:00
Yu Watanabe 1775654e2c conf-parser: drop unnecessary temporary variable 2024-09-19 03:39:15 +09:00
Yu Watanabe 0ea6d55a4b conf-parser: introduce config_parse_in_addr_data() 2024-09-19 03:38:22 +09:00
Yu Watanabe 26d35019de tree-wide: drop unnecessary 'struct' 2024-09-19 01:34:57 +09:00
Yu Watanabe b962338104 nsresource: make sd_json_dispatch_field table static
This also adds missing error check of sd_json_dispatch().

Follow-up for 54452c7b2a.
2024-09-19 01:34:57 +09:00
Yu Watanabe fae0b00434 creds-util: make sd_json_dispatch_field table static 2024-09-19 01:34:57 +09:00
Yu Watanabe f7923ef318 resolve: make sd_json_dispatch_field table static 2024-09-19 01:34:57 +09:00
Yu Watanabe 36df48d863 resolvectl: make sd_json_dispatch_field table static 2024-09-19 01:34:57 +09:00
Yu Watanabe 53c638db16 updatectl: make sd_json_dispatch_field table static
This also fixes memory leak of Version object on failure.

Follow-up for ec15bb71c2.
2024-09-19 01:34:57 +09:00
Yu Watanabe 751a247794 varlinkctl: make sd_json_dispatch_field table static 2024-09-19 01:34:56 +09:00
Yu Watanabe 07dbbda0fc ssh-generator: make sd_json_dispatch_field table static 2024-09-19 01:34:56 +09:00
Yu Watanabe ed4a6c476e machine: make sd_json_dispatch_field table static 2024-09-19 01:34:56 +09:00
Lennart Poettering e33d1a2222 hwbd: use newer KEY_PICKUP_PHONE, KEY_HANGUP_PHONE, KEY_SELECTIVE_SCREENSHOT, KEY_NOTIFICATION_CENTER keycodes where appropriate
According to kernel commit cd80ec795156346236e9b1cd9f5cbff5a9bbd212
these were added expressly for these thinkpads, hence use them now.
2024-09-12 10:04:26 +02:00
Lennart Poettering 57aa23bcc6 hwdb: use KEY_ROTATE_DISPLAY for various cases of display rotation keys
The keycode is reletively new. Let's fix some "FIXMEs" and actually make
use of the keycode wherever it appears appropriate according to
commentary.
2024-09-12 10:04:26 +02:00
Lennart Poettering c1ebb399db hwdb: there's KEY_BRIGHTNESSAUTO these days, hence hook it up where a FIXME suggests that 2024-09-12 10:04:26 +02:00
Lennart Poettering 1ee1997629 hwdb: make key map match comment for one laptop
No idea what the right fix is here, the commnt says "touchpad off" but
uses "f22" which is touchpad "on".

let's trust the comment, because it's more literal, and assume this was
a mistake.
2024-09-12 10:04:26 +02:00
Lennart Poettering a415d73e3c hwdb: f23 → touchpad_off 2024-09-12 10:04:26 +02:00
Lennart Poettering 70eb5b0b7c hwdb: f23 → touchpad_on 2024-09-12 10:04:26 +02:00
Lennart Poettering 380683c22f hwdb: f21 → touchpad_toggle
Similar to the previous commit.
2024-09-12 10:04:25 +02:00
Lennart Poettering 81c8d85744 hwdb: replace f20 hwdb key maps by micmute
See: #34323
2024-09-12 10:03:31 +02:00
39 changed files with 860 additions and 932 deletions

View File

@ -116,8 +116,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:*
KEYBOARD_KEY_d9=brightnessup # Fn+Right KEYBOARD_KEY_d9=brightnessup # Fn+Right
KEYBOARD_KEY_ee=brightnessup # Fn+Right KEYBOARD_KEY_ee=brightnessup # Fn+Right
KEYBOARD_KEY_ef=brightnessdown # Fn+Left KEYBOARD_KEY_ef=brightnessdown # Fn+Left
KEYBOARD_KEY_f1=f22 # Fn+F7 Touchpad toggle (off-to-on) KEYBOARD_KEY_f1=touchpad_on # Fn+F7 Touchpad toggle (off-to-on)
KEYBOARD_KEY_f2=f23 # Fn+F7 Touchpad toggle (on-to-off) KEYBOARD_KEY_f2=touchpad_off # Fn+F7 Touchpad toggle (on-to-off)
KEYBOARD_KEY_f3=prog2 # "P2" programmable button KEYBOARD_KEY_f3=prog2 # "P2" programmable button
KEYBOARD_KEY_f4=prog1 # "P1" programmable button KEYBOARD_KEY_f4=prog1 # "P1" programmable button
KEYBOARD_KEY_f5=presentation KEYBOARD_KEY_f5=presentation
@ -127,7 +127,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:*
# Acer kernel driver # Acer kernel driver
evdev:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:* evdev:name:Acer WMI hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnAcer*:*
KEYBOARD_KEY_82=f21 # Touchpad toggle KEYBOARD_KEY_82=touchpad_toggle # Touchpad toggle
# Aspire models # Aspire models
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAspire*:*
@ -186,11 +186,11 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredator*PH*315-52:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMateB311-31*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMateB311-31*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMateB311R-31*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMateB311R-31*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMateB311RN-31*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMateB311RN-31*:pvr*
KEYBOARD_KEY_8a=f20 # Microphone mute KEYBOARD_KEY_8a=micmute # Microphone mute
# Travelmate C300 # Travelmate C300
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:*
KEYBOARD_KEY_67=f24 # FIXME: rotate screen KEYBOARD_KEY_67=rotate_display # rotate screen
KEYBOARD_KEY_68=up KEYBOARD_KEY_68=up
KEYBOARD_KEY_69=down KEYBOARD_KEY_69=down
KEYBOARD_KEY_6b=fn KEYBOARD_KEY_6b=fn
@ -200,7 +200,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*C3[01]0*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G2-MG*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G2-MG*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G3-M*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G3-M*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P645-S*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P645-S*:*
KEYBOARD_KEY_8a=f20 # Microphone mute button; should be micmute KEYBOARD_KEY_8a=micmute # Microphone mute button
# on some models this isn't brightnessup # on some models this isn't brightnessup
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:*
@ -223,7 +223,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPackard*Bell*:pn*:*
# Swift SF314-511 # Swift SF314-511
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnSwiftSF314-511:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnSwiftSF314-511:pvr*
KEYBOARD_KEY_8a=f20 # Fn+F12, microphone mute KEYBOARD_KEY_8a=micmute # Fn+F12, microphone mute
# Predator PHN16-71 # Predator PHN16-71
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredatorPHN16-71:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredatorPHN16-71:*
@ -237,7 +237,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnPredatorPHN16-72:*
# Nitro AN515-58 # Nitro AN515-58
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnNitro*AN*515-58:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnNitro*AN*515-58:pvr*
KEYBOARD_KEY_8a=f20 # Microphone mute button KEYBOARD_KEY_8a=micmute # Microphone mute button
KEYBOARD_KEY_55=power KEYBOARD_KEY_55=power
########################################################### ###########################################################
@ -246,7 +246,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnNitro*AN*515-58:pvr*
# Alienware/Dell reserves these keys; safe to apply on all their devices # Alienware/Dell reserves these keys; safe to apply on all their devices
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pn*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pn*:*
KEYBOARD_KEY_81=f21 # Touchpad toggle KEYBOARD_KEY_81=touchpad_toggle # Touchpad toggle
KEYBOARD_KEY_8a=ejectcd KEYBOARD_KEY_8a=ejectcd
KEYBOARD_KEY_bf=!prog1 # graphics amplifier, cable plug-in event KEYBOARD_KEY_bf=!prog1 # graphics amplifier, cable plug-in event
KEYBOARD_KEY_c1=!prog2 # graphics amplifier, undock-button event KEYBOARD_KEY_c1=!prog2 # graphics amplifier, undock-button event
@ -263,7 +263,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pnM17xR3:*
# Aquarius Cmp NS483 # Aquarius Cmp NS483
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAquarius*:pnCmp*NS483*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAquarius*:pnCmp*NS483*:*
KEYBOARD_KEY_56=backslash KEYBOARD_KEY_56=backslash
KEYBOARD_KEY_76=f21 # Touchpad Toggle KEYBOARD_KEY_76=touchpad_toggle # Touchpad Toggle
########################################################### ###########################################################
# Asus # Asus
@ -277,12 +277,12 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnASUS:pn*:*
evdev:name:Asus WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:* evdev:name:Asus WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:*
evdev:name:Eee PC WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:* evdev:name:Eee PC WMI hotkeys:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:*
evdev:name:Asus Laptop extra buttons:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:* evdev:name:Asus Laptop extra buttons:dmi:bvn*:bvr*:bd*:svnASUS*:pn*:*
KEYBOARD_KEY_6b=f21 # Touchpad Toggle KEYBOARD_KEY_6b=touchpad_toggle # Touchpad Toggle
KEYBOARD_KEY_7c=f20 # Remap micmute to f20 KEYBOARD_KEY_7c=micmute
# USB keyboard in Asus FX503VD # USB keyboard in Asus FX503VD
evdev:input:b0003v0B05p1869* evdev:input:b0003v0B05p1869*
KEYBOARD_KEY_ff31007c=f20 # Remap micmute to f20 KEYBOARD_KEY_ff31007c=micmute
# Asus TF103C misses the home button in its PNP0C40 GPIO resources # Asus TF103C misses the home button in its PNP0C40 GPIO resources
# causing the volume-button mappings to be off by one, correct this # causing the volume-button mappings to be off by one, correct this
@ -340,15 +340,15 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnNotebook:pnW65_67SZ:*
evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNS50_70MU:* evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNS50_70MU:*
evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNV4XMB,ME,MZ:* evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNV4XMB,ME,MZ:*
evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNS5x_NS7xPU:* evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNS5x_NS7xPU:*
KEYBOARD_KEY_f7=f21 # Touchpad Toggle KEYBOARD_KEY_f7=touchpad_toggle # Touchpad Toggle
KEYBOARD_KEY_f8=f21 # Touchpad Toggle KEYBOARD_KEY_f8=touchpad_toggle # Touchpad Toggle
evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnV5xTNC_TND_TNE:* evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnV5xTNC_TND_TNE:*
evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNV4xPZ:* evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnNV4xPZ:*
evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnV54x_6x_TU:* evdev:atkbd:dmi:bvn*:bvr*:svnNotebook:pnV54x_6x_TU:*
KEYBOARD_KEY_f7=f21 # Touchpad Toggle KEYBOARD_KEY_f7=touchpad_toggle # Touchpad Toggle
KEYBOARD_KEY_f8=f21 # Touchpad Toggle KEYBOARD_KEY_f8=touchpad_toggle # Touchpad Toggle
KEYBOARD_KEY_81=f20 # Fn+4; Mic Mute KEYBOARD_KEY_81=micmute # Fn+4; Mic Mute
########################################################### ###########################################################
# Compal # Compal
@ -369,7 +369,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnCompaq*:pn*Evo*N*:*
KEYBOARD_KEY_9f=homepage KEYBOARD_KEY_9f=homepage
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnCompaq:pn*:pvr*:rvn*:rnN14KP6* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnCompaq:pn*:pvr*:rvn*:rnN14KP6*
KEYBOARD_KEY_76=f21 # Fn+f2 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+f2 toggle touchpad
evdev:input:b0003v049Fp0051* evdev:input:b0003v049Fp0051*
evdev:input:b0003v049Fp008D* evdev:input:b0003v049Fp008D*
@ -403,24 +403,24 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pn*:*
KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD KEYBOARD_KEY_89=ejectclosecd # Fn+F10 Eject CD
KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate KEYBOARD_KEY_8a=suspend # Fn+F1 hibernate
KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle") KEYBOARD_KEY_8b=switchvideomode # Fn+F8 CRT/LCD (high keycode: "displaytoggle")
KEYBOARD_KEY_8c=unknown # Fn+Right Auto Brightness KEYBOARD_KEY_8c=brightnessauto # Fn+Right Auto Brightness
KEYBOARD_KEY_8f=switchvideomode # Fn+F7 aspect ratio KEYBOARD_KEY_8f=switchvideomode # Fn+F7 aspect ratio
KEYBOARD_KEY_90=previoussong # Front panel previous song KEYBOARD_KEY_90=previoussong # Front panel previous song
KEYBOARD_KEY_91=prog1 # Wi-Fi Catcher (Dell-specific) KEYBOARD_KEY_91=prog1 # Wi-Fi Catcher (Dell-specific)
KEYBOARD_KEY_92=media # MediaDirect button (house icon) KEYBOARD_KEY_92=media # MediaDirect button (house icon)
KEYBOARD_KEY_93=unknown # FIXME Fn+Left Auto Brightness KEYBOARD_KEY_93=brightnessauto # Fn+Left Auto Brightness
KEYBOARD_KEY_95=camera # Shutter button - Takes a picture if optional camera available KEYBOARD_KEY_95=camera # Shutter button - Takes a picture if optional camera available
KEYBOARD_KEY_97=email # Tablet email button KEYBOARD_KEY_97=email # Tablet email button
KEYBOARD_KEY_98=f21 # FIXME: Tablet screen rotation KEYBOARD_KEY_98=rotate_display # Tablet screen rotation
KEYBOARD_KEY_99=nextsong # Front panel next song KEYBOARD_KEY_99=nextsong # Front panel next song
KEYBOARD_KEY_9a=setup # Tablet tools button KEYBOARD_KEY_9a=setup # Tablet tools button
KEYBOARD_KEY_9b=switchvideomode # Display toggle button KEYBOARD_KEY_9b=switchvideomode # Display toggle button
KEYBOARD_KEY_9e=f21 # Touchpad toggle KEYBOARD_KEY_9e=touchpad_toggle # Touchpad toggle
KEYBOARD_KEY_a2=playpause # Front panel play/pause KEYBOARD_KEY_a2=playpause # Front panel play/pause
KEYBOARD_KEY_a4=stopcd # Front panel stop KEYBOARD_KEY_a4=stopcd # Front panel stop
KEYBOARD_KEY_ed=media # MediaDirect button KEYBOARD_KEY_ed=media # MediaDirect button
KEYBOARD_KEY_d8=screenlock # FIXME: Tablet lock button KEYBOARD_KEY_d8=screenlock # FIXME: Tablet lock button
KEYBOARD_KEY_d9=f21 # Touchpad toggle KEYBOARD_KEY_d9=touchpad_toggle # Touchpad toggle
# #
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*910:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnInspiron*910:*
@ -462,7 +462,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnStudio*155[78]:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:*
KEYBOARD_KEY_88=! # wireless switch KEYBOARD_KEY_88=! # wireless switch
KEYBOARD_KEY_9e=!f21 KEYBOARD_KEY_9e=!touchpad_toggle
# Dell Latitude E[67]* # Dell Latitude E[67]*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*E6*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*E6*:*
@ -481,7 +481,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDellInc.:pnDellSystemXPSL702X:*
# Dell XPS12 9Q33 # Dell XPS12 9Q33
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS12-9Q33*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS12-9Q33*:*
KEYBOARD_KEY_88=wlan KEYBOARD_KEY_88=wlan
KEYBOARD_KEY_65=direction # Screen Rotate KEYBOARD_KEY_65=rotate_display # Screen Rotate
# Dell Pro Rugged microphone mute # Dell Pro Rugged microphone mute
evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnDellProRugged*:* evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnDellProRugged*:*
@ -493,17 +493,17 @@ evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:*
evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:* evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:*
# Dell XPS microphone mute # Dell XPS microphone mute
evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:* evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:*
KEYBOARD_KEY_100150=f20 # Mic mute toggle, should be micmute KEYBOARD_KEY_100150=micmute # Mic mute toggle
# Dell Latitude privacy microphone mute # Dell Latitude privacy microphone mute
evdev:name:Dell Privacy Driver:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:* evdev:name:Dell Privacy Driver:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*:*
# Dell Precision privacy microphone mute # Dell Precision privacy microphone mute
evdev:name:Dell Privacy Driver:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:* evdev:name:Dell Privacy Driver:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*:*
KEYBOARD_KEY_120001=f20 # Mic mute toggle, should be micmute KEYBOARD_KEY_120001=micmute # Mic mute toggle
# Dell Professional Sound Bar AE515 # Dell Professional Sound Bar AE515
evdev:input:b0003v413CpA506* evdev:input:b0003v413CpA506*
KEYBOARD_KEY_b002f=f20 # Mic mute toggle, should be micmute KEYBOARD_KEY_b002f=micmute # Mic mute toggle
########################################################### ###########################################################
# Everex # Everex
@ -511,7 +511,7 @@ evdev:input:b0003v413CpA506*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnEverex:pnXT5000*:*
KEYBOARD_KEY_5c=media KEYBOARD_KEY_5c=media
KEYBOARD_KEY_65=f21 # Fn+F5 Touchpad toggle KEYBOARD_KEY_65=touchpad_toggle # Fn+F5 Touchpad toggle
KEYBOARD_KEY_67=prog3 # Fan speed control button KEYBOARD_KEY_67=prog3 # Fan speed control button
KEYBOARD_KEY_6f=brightnessup KEYBOARD_KEY_6f=brightnessup
KEYBOARD_KEY_7f=brightnessdown KEYBOARD_KEY_7f=brightnessdown
@ -550,7 +550,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*Edition*V3505*:*
# Amilo Pro v3205 # Amilo Pro v3205
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*V3205*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnFUJITSU*:pn*AMILO*Pro*V3205*:*
KEYBOARD_KEY_f4=f21 # FIXME: silent-mode decrease CPU/GPU clock KEYBOARD_KEY_f4=touchpad_toggle # FIXME: silent-mode decrease CPU/GPU clock
KEYBOARD_KEY_f7=switchvideomode # Fn+F3 KEYBOARD_KEY_f7=switchvideomode # Fn+F3
# Amilo Si 1520 # Amilo Si 1520
@ -639,7 +639,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*:*
KEYBOARD_KEY_8c=media # music KEYBOARD_KEY_8c=media # music
KEYBOARD_KEY_8e=dvd KEYBOARD_KEY_8e=dvd
KEYBOARD_KEY_b1=help KEYBOARD_KEY_b1=help
KEYBOARD_KEY_b3=unknown # FIXME: Auto brightness KEYBOARD_KEY_b3=brightnessauto # Auto brightness
KEYBOARD_KEY_d7=wlan KEYBOARD_KEY_d7=wlan
KEYBOARD_KEY_92=brightnessdown # Fn+F7 (Fn+F9 on 6730b) KEYBOARD_KEY_92=brightnessdown # Fn+F7 (Fn+F9 on 6730b)
KEYBOARD_KEY_97=brightnessup # Fn+F8 (Fn+F10 on 6730b) KEYBOARD_KEY_97=brightnessup # Fn+F8 (Fn+F10 on 6730b)
@ -658,8 +658,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][aA][bB][lL][eE][tT]*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*:*
KEYBOARD_KEY_88=media # FIXME: quick play KEYBOARD_KEY_88=media # FIXME: quick play
KEYBOARD_KEY_b7=print KEYBOARD_KEY_b7=print
KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d8=!touchpad_off # touchpad off
KEYBOARD_KEY_d9=!f22 # touchpad on KEYBOARD_KEY_d9=!touchpad_on # touchpad on
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:*
KEYBOARD_KEY_b7=print KEYBOARD_KEY_b7=print
@ -669,7 +669,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:
# Pavilion 13 x360 (Tablet mode and SYSRQ key) # Pavilion 13 x360 (Tablet mode and SYSRQ key)
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:*
KEYBOARD_KEY_d7=!f22 # touchpad off KEYBOARD_KEY_d7=!touchpad_off # touchpad off
KEYBOARD_KEY_d9=unknown KEYBOARD_KEY_d9=unknown
KEYBOARD_KEY_d2=sysrq # Fn+Print = SYSRQ KEYBOARD_KEY_d2=sysrq # Fn+Print = SYSRQ
@ -687,7 +687,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*[sS][pP][eE][cC][tT][rR][eE]*x360Convert
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPSpectrex360Convertible13*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPSpectrex360Convertible13*:*
# ENVY x360 13 # ENVY x360 13
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPENVYx360Convertible13*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPENVYx360Convertible13*:*
KEYBOARD_KEY_82=f20 # Microphone mute button, should be micmute KEYBOARD_KEY_82=micmute # Microphone mute button
# Spectre x360 16 2022 # Spectre x360 16 2022
evdev:name:Intel HID events:dmi:bvn*:bvr*:bd*:svnHP*:pn*HP[sS][pP][eE][cC][tT][rR][eE]*x3602-in-1*:* evdev:name:Intel HID events:dmi:bvn*:bvr*:bd*:svnHP*:pn*HP[sS][pP][eE][cC][tT][rR][eE]*x3602-in-1*:*
@ -700,7 +700,7 @@ evdev:name:Intel HID events:dmi:bvn*:bvr*:bd*:svnHP*:pnHPENVYx3602-in-1*:*
evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:* evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:*
KEYBOARD_KEY_f8=unknown # rfkill is also reported by HP Wireless hotkeys KEYBOARD_KEY_f8=unknown # rfkill is also reported by HP Wireless hotkeys
KEYBOARD_KEY_64=calendar KEYBOARD_KEY_64=calendar
KEYBOARD_KEY_81=f20 # Microphone mute button KEYBOARD_KEY_81=micmute # Microphone mute button
KEYBOARD_KEY_ee=switchvideomode # Switch display outputs KEYBOARD_KEY_ee=switchvideomode # Switch display outputs
KEYBOARD_KEY_92=brightnessdown KEYBOARD_KEY_92=brightnessdown
KEYBOARD_KEY_97=brightnessup KEYBOARD_KEY_97=brightnessup
@ -718,15 +718,15 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2230s*:*
# Presario # Presario
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Presario*CQ*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Presario*CQ*:*
KEYBOARD_KEY_d8=f21 KEYBOARD_KEY_d8=touchpad_toggle
KEYBOARD_KEY_d9=f21 KEYBOARD_KEY_d9=touchpad_toggle
# 2510p 2530p # 2510p 2530p
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2510p*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2510p*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2530p*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2530p*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*G60*Notebook*PC:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*G60*Notebook*PC:*
KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d8=!touchpad_off # touchpad off
KEYBOARD_KEY_d9=!f22 # touchpad on KEYBOARD_KEY_d9=!touchpad_on # touchpad on
# 2570p # 2570p
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2570p*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2570p*:*
@ -740,15 +740,15 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*2760p*:*
KEYBOARD_KEY_87=volumedown KEYBOARD_KEY_87=volumedown
KEYBOARD_KEY_92=brightnessdown KEYBOARD_KEY_92=brightnessdown
KEYBOARD_KEY_97=brightnessup KEYBOARD_KEY_97=brightnessup
KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d8=!touchpad_off # touchpad off
KEYBOARD_KEY_d9=!f22 # touchpad on KEYBOARD_KEY_d9=!touchpad_on # touchpad on
KEYBOARD_KEY_b3=unknown # FIXME: Auto brightness KEYBOARD_KEY_b3=brightnessauto # Auto brightness
# TX2 # TX2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[tT][xX]2*:*
KEYBOARD_KEY_c2=media KEYBOARD_KEY_c2=media
KEYBOARD_KEY_d8=!f23 # Toggle touchpad button on tx2 (OFF) KEYBOARD_KEY_d8=!touchpad_off # Toggle touchpad button on tx2 (OFF)
KEYBOARD_KEY_d9=!f22 # Toggle touchpad button on tx2 (ON) KEYBOARD_KEY_d9=!touchpad_on # Toggle touchpad button on tx2 (ON)
# Presario 2100 # Presario 2100
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario*2100*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnPresario*2100*:*
@ -773,8 +773,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*EliteBook*8460p:*
# HDX9494nr # HDX9494nr
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHDX9494NR:*
KEYBOARD_KEY_b2=www # Fn+F3 KEYBOARD_KEY_b2=www # Fn+F3
KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d8=!touchpad_off # touchpad off
KEYBOARD_KEY_d9=!f22 # touchpad on KEYBOARD_KEY_d9=!touchpad_on # touchpad on
# HP EliteBook 725 G2 # HP EliteBook 725 G2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPLicrice:*
@ -793,14 +793,14 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHP*ProBook*:*
# HP ZBook # HP ZBook
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBook*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBook*:*
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute KEYBOARD_KEY_81=micmute # Fn+F8; Microphone mute button
# HP ZBook Studio G5 # HP ZBook Studio G5
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBookStudioG5*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPZBookStudioG5*:*
KEYBOARD_KEY_64=calendar # Calendar icon (Fn + F12) KEYBOARD_KEY_64=calendar # Calendar icon (Fn + F12)
KEYBOARD_KEY_6d=displaytoggle # Display icon KEYBOARD_KEY_6d=displaytoggle # Display icon
KEYBOARD_KEY_66=connect # Pickup phone button → connect → XF86Go KEYBOARD_KEY_66=pickup_phone # Pickup phone button
KEYBOARD_KEY_65=cancel # Hangup phone button → cancel → Cancel KEYBOARD_KEY_65=hangup_phone # Hangup phone button
# HP ZBook 15 G2 # HP ZBook 15 G2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook15G2:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook15G2:*
@ -808,9 +808,9 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPZBook15G2:*
# HP ProBook 11 G1 # HP ProBook 11 G1
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPProBook11G1:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPProBook11G1:*
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute KEYBOARD_KEY_81=micmute # Fn+F8; Microphone mute button
KEYBOARD_KEY_d8=f21 # touchpad toggle KEYBOARD_KEY_d8=touchpad_toggle # touchpad toggle
KEYBOARD_KEY_d9=f21 # touchpad toggle KEYBOARD_KEY_d9=touchpad_toggle # touchpad toggle
# HP ZBook Studio G4 # HP ZBook Studio G4
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPZBookStudioG4:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPZBookStudioG4:*
@ -818,13 +818,13 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPZBookStudioG4:*
# HP EliteBook Folio 1040 G2 # HP EliteBook Folio 1040 G2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHPEliteBookFolio1040G2:*
KEYBOARD_KEY_d8=!f23 # touchpad off KEYBOARD_KEY_d8=!touchpad_off # touchpad off
KEYBOARD_KEY_d9=!f22 # touchpad on KEYBOARD_KEY_d9=!touchpad_on # touchpad on
# HP EliteBook Folio G1 # HP EliteBook Folio G1
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteBookFolioG1:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteBookFolioG1:*
KEYBOARD_KEY_64=calendar KEYBOARD_KEY_64=calendar
KEYBOARD_KEY_81=f20 KEYBOARD_KEY_81=micmute
# HP EliteBook 845 G7 # HP EliteBook 845 G7
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPEliteBook845G7*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPEliteBook845G7*:pvr*
@ -857,16 +857,16 @@ evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*ProBook*455*G5*:*
# HP ProBook 11G2 # HP ProBook 11G2
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPProBook11G2*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPProBook11G2*:pvr*
KEYBOARD_KEY_d8=!f23 # Fn+F2: touchpad off KEYBOARD_KEY_d8=!touchpad_off # Fn+F2: touchpad off
KEYBOARD_KEY_d9=!f22 # Fn+F2: touchpad on KEYBOARD_KEY_d9=!touchpad_on # Fn+F2: touchpad on
# HP mt44 Mobile Thin Client # HP mt44 Mobile Thin Client
evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*mt44*Mobile*Thin*Client*:* evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHP*mt44*Mobile*Thin*Client*:*
KEYBOARD_KEY_64=calendar # Calendar icon (Fn + F12) KEYBOARD_KEY_64=calendar # Calendar icon (Fn + F12)
KEYBOARD_KEY_6d=displaytoggle # Display icon KEYBOARD_KEY_6d=displaytoggle # Display icon
KEYBOARD_KEY_66=connect # Pickup phone button → connect → XF86Go KEYBOARD_KEY_66=pickup_phone # Pickup phone button
KEYBOARD_KEY_65=cancel # Hangup phone button → cancel → Cancel KEYBOARD_KEY_65=hangup_phone # Hangup phone button
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button, should be micmute KEYBOARD_KEY_81=micmute # Fn+F8; Microphone mute button
KEYBOARD_KEY_85=unknown # lid close; also reported via special evdev KEYBOARD_KEY_85=unknown # lid close; also reported via special evdev
KEYBOARD_KEY_f8=wlan # Wireless HW switch button KEYBOARD_KEY_f8=wlan # Wireless HW switch button
@ -884,7 +884,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnOMEN*:pvr*
# HP Dev One # HP Dev One
evdev:atkbd:dmi:*:rvnHP:rn8A78:* evdev:atkbd:dmi:*:rvnHP:rn8A78:*
KEYBOARD_KEY_81=f20 # Fn+F8; Microphone mute button KEYBOARD_KEY_81=micmute # Fn+F8; Microphone mute button
KEYBOARD_KEY_f9=prog1 # Fn+F12; Programmable hotkey KEYBOARD_KEY_f9=prog1 # Fn+F12; Programmable hotkey
# HP Victus # HP Victus
@ -913,7 +913,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP:pnHPEliteDragonfly13.5inchG3NotebookPC:pvr*
# Huawei WMI hotkeys driver # Huawei WMI hotkeys driver
evdev:name:Huawei WMI hotkeys:dmi:bvn*:bvr*:bd*:svnHUAWEI:* evdev:name:Huawei WMI hotkeys:dmi:bvn*:bvr*:bd*:svnHUAWEI:*
KEYBOARD_KEY_287=f20 # Microphone mute button, should be micmute KEYBOARD_KEY_287=micmute # Microphone mute button
# Huawei MACH-WX9 and EUL-WX9 # Huawei MACH-WX9 and EUL-WX9
evdev:atkbd:dmi:bvn*:bvr*:svnHUAWEI*:pnMACH-WX9:* evdev:atkbd:dmi:bvn*:bvr*:svnHUAWEI*:pnMACH-WX9:*
@ -974,7 +974,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINVENTEC:pnSYMPHONY*6.0/7.0:*
# LEAP W502 # LEAP W502
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnJP-IK:pnLEAPW502:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnJP-IK:pnLEAPW502:pvr*
KEYBOARD_KEY_76=f21 # touchpad toggle KEYBOARD_KEY_76=touchpad_toggle # touchpad toggle
########################################################### ###########################################################
# Kvadra # Kvadra
@ -982,7 +982,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnJP-IK:pnLEAPW502:pvr*
# LE14U/LE15U # LE14U/LE15U
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnKVADRA*:pn*LE1*U*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnKVADRA*:pn*LE1*U*:*
KEYBOARD_KEY_76=f21 # Fn+F1 Toggle touchpad, sends meta+ctrl+toggle KEYBOARD_KEY_76=touchpad_toggle # Fn+F1 Toggle touchpad, sends meta+ctrl+toggle
########################################################### ###########################################################
# Lenovo # Lenovo
@ -995,7 +995,7 @@ evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:*
KEYBOARD_KEY_03=sleep KEYBOARD_KEY_03=sleep
KEYBOARD_KEY_04=wlan KEYBOARD_KEY_04=wlan
KEYBOARD_KEY_06=switchvideomode KEYBOARD_KEY_06=switchvideomode
KEYBOARD_KEY_07=f21 KEYBOARD_KEY_07=touchpad_toggle
KEYBOARD_KEY_08=f24 KEYBOARD_KEY_08=f24
KEYBOARD_KEY_0b=suspend KEYBOARD_KEY_0b=suspend
KEYBOARD_KEY_0f=brightnessup KEYBOARD_KEY_0f=brightnessup
@ -1006,13 +1006,13 @@ evdev:name:ThinkPad Extra Buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:*
KEYBOARD_KEY_15=volumedown KEYBOARD_KEY_15=volumedown
KEYBOARD_KEY_16=mute KEYBOARD_KEY_16=mute
KEYBOARD_KEY_17=prog1 KEYBOARD_KEY_17=prog1
KEYBOARD_KEY_1a=f20 # Microphone mute button; should be micmute KEYBOARD_KEY_1a=micmute # Microphone mute button
KEYBOARD_KEY_45=bookmarks KEYBOARD_KEY_45=bookmarks
KEYBOARD_KEY_46=prog2 # Fn + PrtSc, on Windows: Snipping tool KEYBOARD_KEY_46=selective_screenshot # Fn + PrtSc, on Windows: Snipping tool
KEYBOARD_KEY_4a=prog3 # Fn + Right shift, on Windows: No idea KEYBOARD_KEY_4a=prog3 # Fn + Right shift, on Windows: No idea
KEYBOARD_KEY_4b=chat # Fn + F9, on Windows: Notifications panel key KEYBOARD_KEY_4b=notification_center # Fn + F9, on Windows: Notifications panel key
KEYBOARD_KEY_4c=connect # Fn + F10, on Windows: Answer (Teams) call KEYBOARD_KEY_4c=pickup_phone # Fn + F10, on Windows: Answer (Teams) call
KEYBOARD_KEY_4d=cancel # Fn + F11, on Windows: Hangup/decline (Teams) call KEYBOARD_KEY_4d=hangup_phone # Fn + F11, on Windows: Hangup/decline (Teams) call
# ThinkPad Keyboard with TrackPoint # ThinkPad Keyboard with TrackPoint
evdev:input:b0003v17EFp6009* evdev:input:b0003v17EFp6009*
@ -1020,14 +1020,14 @@ evdev:input:b0003v17EFp6009*
KEYBOARD_KEY_090013=battery # Fn+F3 KEYBOARD_KEY_090013=battery # Fn+F3
KEYBOARD_KEY_090014=wlan # Fn+F5 KEYBOARD_KEY_090014=wlan # Fn+F5
KEYBOARD_KEY_090016=switchvideomode # Fn+F7 KEYBOARD_KEY_090016=switchvideomode # Fn+F7
KEYBOARD_KEY_090017=f21 # Fn+F8 touchpad toggle KEYBOARD_KEY_090017=touchpad_toggle # Fn+F8 touchpad toggle
KEYBOARD_KEY_090019=suspend # Fn+F12 KEYBOARD_KEY_090019=suspend # Fn+F12
KEYBOARD_KEY_09001a=brightnessup # Fn+Home KEYBOARD_KEY_09001a=brightnessup # Fn+Home
KEYBOARD_KEY_09001b=brightnessdown # Fn+End KEYBOARD_KEY_09001b=brightnessdown # Fn+End
KEYBOARD_KEY_09001d=zoom # Fn+Space KEYBOARD_KEY_09001d=zoom # Fn+Space
KEYBOARD_KEY_090011=prog1 # ThinkVantage button KEYBOARD_KEY_090011=prog1 # ThinkVantage button
KEYBOARD_KEY_090015=camera # Fn+F6 headset/camera VoIP key ?? KEYBOARD_KEY_090015=camera # Fn+F6 headset/camera VoIP key ??
KEYBOARD_KEY_090010=f20 # Microphone mute button; should be micmute KEYBOARD_KEY_090010=micmute # Microphone mute button
# Lenovo 3000 # Lenovo 3000
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*3000*:pvr*
@ -1049,8 +1049,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pnS10-*:*
KEYBOARD_KEY_b9=brightnessup # does nothing in BIOS KEYBOARD_KEY_b9=brightnessup # does nothing in BIOS
KEYBOARD_KEY_ba=brightnessdown # does nothing in BIOS KEYBOARD_KEY_ba=brightnessdown # does nothing in BIOS
KEYBOARD_KEY_f1=camera # BIOS toggles camera power KEYBOARD_KEY_f1=camera # BIOS toggles camera power
KEYBOARD_KEY_f2=f21 # touchpad toggle (key alternately emits F2 and F3) KEYBOARD_KEY_f2=touchpad_toggle # touchpad toggle (key alternately emits F2 and F3)
KEYBOARD_KEY_f3=f21 KEYBOARD_KEY_f3=touchpad_toggle
# Lenovo IdeaPad 5 # Lenovo IdeaPad 5
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrIdeaPad5*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrIdeaPad5*:*
@ -1063,11 +1063,11 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X2*T*:rvn*
KEYBOARD_KEY_66=screenlock KEYBOARD_KEY_66=screenlock
KEYBOARD_KEY_67=cyclewindows # bezel circular arrow KEYBOARD_KEY_67=cyclewindows # bezel circular arrow
KEYBOARD_KEY_68=setup # bezel setup / menu KEYBOARD_KEY_68=setup # bezel setup / menu
KEYBOARD_KEY_6c=direction # rotate screen KEYBOARD_KEY_6c=rotate_display # rotate screen
# ThinkPad X6 Tablet # ThinkPad X6 Tablet
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X6*Tablet*:rvn* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X6*Tablet*:rvn*
KEYBOARD_KEY_6c=direction # rotate KEYBOARD_KEY_6c=rotate_display # rotate
KEYBOARD_KEY_68=leftmeta # toolbox KEYBOARD_KEY_68=leftmeta # toolbox
KEYBOARD_KEY_6b=esc # escape KEYBOARD_KEY_6b=esc # escape
KEYBOARD_KEY_6d=right # right on d-pad KEYBOARD_KEY_6d=right # right on d-pad
@ -1078,7 +1078,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:pvrThinkPad*X6*Tablet*:rvn*
# ThinkPad X41 Tablet # ThinkPad X41 Tablet
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnIBM*:pn18666TU:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnIBM*:pn18666TU:*
KEYBOARD_KEY_6c=direction # rotate KEYBOARD_KEY_6c=rotate_display # rotate
KEYBOARD_KEY_68=leftmeta # toolbox KEYBOARD_KEY_68=leftmeta # toolbox
KEYBOARD_KEY_6b=esc # escape KEYBOARD_KEY_6b=esc # escape
KEYBOARD_KEY_69=enter # enter on d-pad KEYBOARD_KEY_69=enter # enter on d-pad
@ -1086,17 +1086,17 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnIBM*:pn18666TU:*
# IdeaPad # IdeaPad
evdev:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:* evdev:name:Ideapad extra buttons:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:*
KEYBOARD_KEY_0d=rfkill # airplane mode switch (toggle all wireless devices) KEYBOARD_KEY_0d=rfkill # airplane mode switch (toggle all wireless devices)
KEYBOARD_KEY_08=f20 # micmute KEYBOARD_KEY_08=micmute
KEYBOARD_KEY_42=f23 KEYBOARD_KEY_42=touchpad_off
KEYBOARD_KEY_43=f22 KEYBOARD_KEY_43=touchpad_on
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*Y550*:pvr*
KEYBOARD_KEY_95=media KEYBOARD_KEY_95=media
KEYBOARD_KEY_a3=play KEYBOARD_KEY_a3=play
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*IdeaPad*U300s*:pvr*
KEYBOARD_KEY_f1=f21 KEYBOARD_KEY_f1=touchpad_toggle
KEYBOARD_KEY_ce=f20 # micmute KEYBOARD_KEY_ce=micmute
evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr* evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*IdeaPad*Z370*:pvr*
# Lenovo IdeaPad Flex 5 # Lenovo IdeaPad Flex 5
@ -1117,16 +1117,16 @@ evdev:atkbd:dmi:*:svnLENOVO:*:pvrLenovoYoga300-11IBR:*
evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*20378*:pvr* evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*20378*:pvr*
# Lenovo IdeaPad Z500 # Lenovo IdeaPad Z500
evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*5931*:pvr* evdev:atkbd:dmi:bvn*:bvr*:svnLENOVO*:pn*5931*:pvr*
KEYBOARD_KEY_f3=f21 # Fn+F6 (toggle touchpad) KEYBOARD_KEY_f3=touchpad_toggle # Fn+F6 (toggle touchpad)
# V480 # V480
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*Lenovo*V480*:pvr*
KEYBOARD_KEY_f1=f21 KEYBOARD_KEY_f1=touchpad_toggle
# Lenovo ThinkCentre M800z/M820z/M920z AIO machines # Lenovo ThinkCentre M800z/M820z/M920z AIO machines
# key_scancode 00 is KEY_MICMUTE # key_scancode 00 is KEY_MICMUTE
evdev:name:Microphone Mute Button:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:* evdev:name:Microphone Mute Button:dmi:bvn*:bvr*:bd*:svnLENOVO*:pn*:*
KEYBOARD_KEY_00=f20 KEYBOARD_KEY_00=micmute
# enhanced USB keyboard # enhanced USB keyboard
evdev:input:b0003v04B3p301B* evdev:input:b0003v04B3p301B*
@ -1141,7 +1141,7 @@ evdev:input:b0003v04B3p301B*
# Lenovo Ideapad D330-10IGM # Lenovo Ideapad D330-10IGM
evdev:name:SIPODEV Lenovo HID Device:dmi:*:svnLENOVO:*:pvrLenovoideapadD330-10IGM:* evdev:name:SIPODEV Lenovo HID Device:dmi:*:svnLENOVO:*:pvrLenovoideapadD330-10IGM:*
KEYBOARD_KEY_70073=f21 # Fn+Supr (Touchpad toggle) KEYBOARD_KEY_70073=touchpad_toggle # Fn+Supr (Touchpad toggle)
evdev:name:SIPODEV Lenovo HID Device Consumer Control:dmi:*:svnLENOVO:*:pvrLenovoideapadD330-10IGM:* evdev:name:SIPODEV Lenovo HID Device Consumer Control:dmi:*:svnLENOVO:*:pvrLenovoideapadD330-10IGM:*
KEYBOARD_KEY_c00ff=fn_esc # Fn+Tab (FnLk toggle) KEYBOARD_KEY_c00ff=fn_esc # Fn+Tab (FnLk toggle)
@ -1198,8 +1198,8 @@ evdev:input:b0003v046Dp00*
KEYBOARD_KEY_c102b=cyclewindows # Empty window icon KEYBOARD_KEY_c102b=cyclewindows # Empty window icon
KEYBOARD_KEY_c102c=fn # Fn key KEYBOARD_KEY_c102c=fn # Fn key
KEYBOARD_KEY_c102d=www # www text + magnifierglass icon KEYBOARD_KEY_c102d=www # www text + magnifierglass icon
KEYBOARD_KEY_c1031=connect # Pickup phone button → connect → XF86Go KEYBOARD_KEY_c1031=pickup_phone # Pickup phone button
KEYBOARD_KEY_c1032=cancel # Hangup phone button → cancel → Cancel KEYBOARD_KEY_c1032=hangup_phone # Hangup phone button
KEYBOARD_KEY_c1041=help # Help text or icon (Fn + F1) KEYBOARD_KEY_c1041=help # Help text or icon (Fn + F1)
KEYBOARD_KEY_c1042=wordprocessor # Word icon (Fn + F2) KEYBOARD_KEY_c1042=wordprocessor # Word icon (Fn + F2)
KEYBOARD_KEY_c1043=spreadsheet # Excel icon (Fn + F3) KEYBOARD_KEY_c1043=spreadsheet # Excel icon (Fn + F3)
@ -1500,7 +1500,7 @@ evdev:input:b0003v1532p0200*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pn*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:*
KEYBOARD_KEY_76=f21 # Toggle touchpad, sends meta+ctrl+toggle KEYBOARD_KEY_76=touchpad_toggle # Toggle touchpad, sends meta+ctrl+toggle
KEYBOARD_KEY_91=config # MSIControl Center KEYBOARD_KEY_91=config # MSIControl Center
KEYBOARD_KEY_a0=mute # Fn+F9 KEYBOARD_KEY_a0=mute # Fn+F9
KEYBOARD_KEY_ae=volumedown # Fn+F7 KEYBOARD_KEY_ae=volumedown # Fn+F7
@ -1509,10 +1509,10 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*:*
KEYBOARD_KEY_c2=ejectcd KEYBOARD_KEY_c2=ejectcd
KEYBOARD_KEY_df=sleep # Fn+F12 KEYBOARD_KEY_df=sleep # Fn+F12
KEYBOARD_KEY_e2=bluetooth # satellite dish2 KEYBOARD_KEY_e2=bluetooth # satellite dish2
KEYBOARD_KEY_e4=f21 # Fn+F3 Touchpad disable KEYBOARD_KEY_e4=touchpad_toggle # Fn+F3 Touchpad disable
KEYBOARD_KEY_ec=email # envelope button KEYBOARD_KEY_ec=email # envelope button
KEYBOARD_KEY_ee=camera # Fn+F6 camera disable KEYBOARD_KEY_ee=camera # Fn+F6 camera disable
KEYBOARD_KEY_f1=f20 # Microphone mute KEYBOARD_KEY_f1=micmute # Microphone mute
KEYBOARD_KEY_f2=rotate_display # Rotate screen KEYBOARD_KEY_f2=rotate_display # Rotate screen
KEYBOARD_KEY_f6=wlan # satellite dish1 KEYBOARD_KEY_f6=wlan # satellite dish1
KEYBOARD_KEY_f7=brightnessdown # Fn+F4 KEYBOARD_KEY_f7=brightnessdown # Fn+F4
@ -1546,7 +1546,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMICRO-STAR*:pnU90/U100:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Prestige*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Prestige*:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Modern*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Modern*:*
KEYBOARD_KEY_91=prog1 # Fn+F7 Creation Center, sometime F7 KEYBOARD_KEY_91=prog1 # Fn+F7 Creation Center, sometime F7
KEYBOARD_KEY_f2=prog2 # Fn+F12 Screen rotation KEYBOARD_KEY_f2=rotate_display # Fn+F12 Screen rotation
KEYBOARD_KEY_8d=prog3 # Fn+A Change True Color selections KEYBOARD_KEY_8d=prog3 # Fn+A Change True Color selections
KEYBOARD_KEY_8c=prog4 # Fn+Z Launch True Color KEYBOARD_KEY_8c=prog4 # Fn+Z Launch True Color
KEYBOARD_KEY_f5=fn_esc # Fn+esc Toggle the behaviour of Fn keys KEYBOARD_KEY_f5=fn_esc # Fn+esc Toggle the behaviour of Fn keys
@ -1554,8 +1554,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnMicro-Star*:pn*Modern*:*
KEYBOARD_KEY_98=unknown # Lid open KEYBOARD_KEY_98=unknown # Lid open
evdev:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:* evdev:name:MSI Laptop hotkeys:dmi:bvn*:bvr*:bd*:svn*:pnM[iI][cC][rR][oO]-S[tT][aA][rR]*:*
KEYBOARD_KEY_0213=f22 KEYBOARD_KEY_0213=touchpad_on
KEYBOARD_KEY_0214=f23 KEYBOARD_KEY_0214=touchpad_off
# MSI Claw # MSI Claw
evdev:name:AT Translated Set 2 keyboard:dmi:*:svnMicro-StarInternationalCo.,Ltd.:pnClawA1M:* evdev:name:AT Translated Set 2 keyboard:dmi:*:svnMicro-StarInternationalCo.,Ltd.:pnClawA1M:*
@ -1568,7 +1568,7 @@ evdev:name:AT Translated Set 2 keyboard:dmi:*:svnMicro-StarInternationalCo.,Ltd.
# VersaPro VG-S # VersaPro VG-S
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnNEC:pnPC-VK22TGSGS:pvr* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnNEC:pnPC-VK22TGSGS:pvr*
KEYBOARD_KEY_a8=f21 # Fn+Space touchpad toggle KEYBOARD_KEY_a8=touchpad_toggle # Fn+Space touchpad toggle
KEYBOARD_KEY_67=brightnessdown # Fn+F7 brightness down KEYBOARD_KEY_67=brightnessdown # Fn+F7 brightness down
KEYBOARD_KEY_65=brightnessup # Fn+F8 brightness up KEYBOARD_KEY_65=brightnessup # Fn+F8 brightness up
KEYBOARD_KEY_71=battery # Fn+F4 ECO KEYBOARD_KEY_71=battery # Fn+F4 ECO
@ -1581,7 +1581,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnNEC:pnPC-VK22TGSGS:pvr*
evdev:input:b0003v15BAp003C* evdev:input:b0003v15BAp003C*
KEYBOARD_KEY_70066=sleep # Fn+F1 KEYBOARD_KEY_70066=sleep # Fn+F1
KEYBOARD_KEY_700f6=wlan # Fn+F2 KEYBOARD_KEY_700f6=wlan # Fn+F2
KEYBOARD_KEY_700c7=f21 # Fn+F3 touchpad toggle KEYBOARD_KEY_700c7=touchpad_toggle # Fn+F3 touchpad toggle
KEYBOARD_KEY_7006f=brightnessdown # Fn+F7 KEYBOARD_KEY_7006f=brightnessdown # Fn+F7
KEYBOARD_KEY_70070=brightnessup # Fn+F8 KEYBOARD_KEY_70070=brightnessup # Fn+F8
KEYBOARD_KEY_7006e=switchvideomode # Fn+F9 KEYBOARD_KEY_7006e=switchvideomode # Fn+F9
@ -1622,8 +1622,8 @@ evdev:name:AT Translated Set 2 keyboard:phys:sp/serio*/input*:ev:120013:*
KEYBOARD_KEY_f3=f17 KEYBOARD_KEY_f3=f17
KEYBOARD_KEY_f2=f18 KEYBOARD_KEY_f2=f18
KEYBOARD_KEY_f1=f19 KEYBOARD_KEY_f1=f19
KEYBOARD_KEY_f0=f20 # micmute KEYBOARD_KEY_f0=micmute
KEYBOARD_KEY_ef=f21 KEYBOARD_KEY_ef=touchpad_toggle
KEYBOARD_KEY_ee=chat KEYBOARD_KEY_ee=chat
KEYBOARD_KEY_e4=chat KEYBOARD_KEY_e4=chat
KEYBOARD_KEY_dd=menu # Frame KEYBOARD_KEY_dd=menu # Frame
@ -1665,7 +1665,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnONKYO*CORPORATION:pnONKYOPC:*
KEYBOARD_KEY_f0=media # Fn+R KEYBOARD_KEY_f0=media # Fn+R
KEYBOARD_KEY_f5=switchvideomode # Fn+E KEYBOARD_KEY_f5=switchvideomode # Fn+E
KEYBOARD_KEY_f6=camera # Fn+T KEYBOARD_KEY_f6=camera # Fn+T
KEYBOARD_KEY_f7=f21 # Fn+Y (touchpad toggle) KEYBOARD_KEY_f7=touchpad_toggle # Fn+Y (touchpad toggle)
KEYBOARD_KEY_f8=brightnessup # Fn+S KEYBOARD_KEY_f8=brightnessup # Fn+S
KEYBOARD_KEY_f9=brightnessdown # Fn+A KEYBOARD_KEY_f9=brightnessdown # Fn+A
KEYBOARD_KEY_fb=wlan # Fn+J KEYBOARD_KEY_fb=wlan # Fn+J
@ -1741,7 +1741,7 @@ evdev:input:b0003v258Ap001E*
# Plantronics .Audio 626 DSP # Plantronics .Audio 626 DSP
evdev:input:b0003v047FpC006* evdev:input:b0003v047FpC006*
KEYBOARD_KEY_b002f=f20 # Microphone mute button; should be micmute KEYBOARD_KEY_b002f=micmute # Microphone mute button
########################################################### ###########################################################
# Purism # Purism
@ -1806,8 +1806,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*:*
KEYBOARD_KEY_b4=!wlan # Fn+F9 (X60P) KEYBOARD_KEY_b4=!wlan # Fn+F9 (X60P)
KEYBOARD_KEY_c5=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance) KEYBOARD_KEY_c5=!prog3 # Fn+F8 switch power mode (battery/dynamic/performance)
KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch KEYBOARD_KEY_d5=!wlan # Fn+F12 wlan/airplane switch
KEYBOARD_KEY_f7=!f22 # Fn+F10 Touchpad on KEYBOARD_KEY_f7=!touchpad_on # Fn+F10 Touchpad on
KEYBOARD_KEY_f9=!f23 # Fn+F10 Touchpad off KEYBOARD_KEY_f9=!touchpad_off # Fn+F10 Touchpad off
# Series 3 # Series 3
evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*300E[457]*:*
@ -1820,8 +1820,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*355V[45]*:pvr*
KEYBOARD_KEY_89=!brightnessdown # Fn+F2 brightness down KEYBOARD_KEY_89=!brightnessdown # Fn+F2 brightness down
KEYBOARD_KEY_88=!brightnessup # Fn+F3 brightness up KEYBOARD_KEY_88=!brightnessup # Fn+F3 brightness up
KEYBOARD_KEY_82=!switchvideomode # Fn+F4 display toggle KEYBOARD_KEY_82=!switchvideomode # Fn+F4 display toggle
KEYBOARD_KEY_f7=!f22 # Fn+F5 touchpad on KEYBOARD_KEY_f7=!touchpad_on # Fn+F5 touchpad on
KEYBOARD_KEY_f9=!f23 # Fn+F5 touchpad off KEYBOARD_KEY_f9=!touchpad_off # Fn+F5 touchpad off
KEYBOARD_KEY_a0=!mute # Fn+F6 mute KEYBOARD_KEY_a0=!mute # Fn+F6 mute
KEYBOARD_KEY_ae=!volumedown # Fn+F7 volume down KEYBOARD_KEY_ae=!volumedown # Fn+F7 volume down
KEYBOARD_KEY_b0=!volumeup # Fn+F8 volume up KEYBOARD_KEY_b0=!volumeup # Fn+F8 volume up
@ -1901,8 +1901,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pnSQ1US:*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*SX20S*:*
KEYBOARD_KEY_74=mute KEYBOARD_KEY_74=mute
KEYBOARD_KEY_75=mute KEYBOARD_KEY_75=mute
KEYBOARD_KEY_77=f22 # Touchpad on KEYBOARD_KEY_77=touchpad_on # Touchpad on
KEYBOARD_KEY_79=f23 # Touchpad off KEYBOARD_KEY_79=touchpad_off # Touchpad off
evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svn[sS][aA][mM][sS][uU][nN][gG]*:pn*700T*:*
KEYBOARD_KEY_ad=leftmeta KEYBOARD_KEY_ad=leftmeta
@ -1959,7 +1959,7 @@ evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVGN-FW250*:*
KEYBOARD_KEY_10=suspend # Fn+F12 KEYBOARD_KEY_10=suspend # Fn+F12
evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:* evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:*
KEYBOARD_KEY_05=f21 # Fn+F1 -> KEY_F21 (The actual touchpad toggle) KEYBOARD_KEY_05=touchpad_toggle # Fn+F1
KEYBOARD_KEY_0d=down # Fn+F9 zoomout KEYBOARD_KEY_0d=down # Fn+F9 zoomout
KEYBOARD_KEY_0e=up # Fn+F10 zoomin KEYBOARD_KEY_0e=up # Fn+F10 zoomin
@ -1968,19 +1968,19 @@ evdev:name:Sony Vaio Keys:dmi:bvn*:bvr*:bd*:svnSony*:pnVPC*:*
########################################################### ###########################################################
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnSystem76*:pn*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnSystem76*:pn*:*
KEYBOARD_KEY_f7=f21 # Touchpad toggle KEYBOARD_KEY_f7=touchpad_toggle # Touchpad toggle
KEYBOARD_KEY_f8=f21 # Touchpad toggle KEYBOARD_KEY_f8=touchpad_toggle # Touchpad toggle
# Pangolin 12 # Pangolin 12
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnSystem76*:pnPangolin*:pvrpang12* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnSystem76*:pnPangolin*:pvrpang12*
KEYBOARD_KEY_76=f21 # Touchpad toggle KEYBOARD_KEY_76=touchpad_toggle # Touchpad toggle
########################################################### ###########################################################
# T-bao # T-bao
########################################################### ###########################################################
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnT-bao:pnTbookair:*
KEYBOARD_KEY_76=f21 # Touchpad toggle KEYBOARD_KEY_76=touchpad_toggle # Touchpad toggle
########################################################### ###########################################################
# Toshiba # Toshiba
@ -1996,8 +1996,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*A110:*
KEYBOARD_KEY_92=stop KEYBOARD_KEY_92=stop
KEYBOARD_KEY_93=www KEYBOARD_KEY_93=www
KEYBOARD_KEY_94=media KEYBOARD_KEY_94=media
KEYBOARD_KEY_9e=f22 # Touchpad on KEYBOARD_KEY_9e=touchpad_on # Touchpad on
KEYBOARD_KEY_9f=f23 # Touchpad off KEYBOARD_KEY_9f=touchpad_off # Touchpad off
KEYBOARD_KEY_b9=nextsong KEYBOARD_KEY_b9=nextsong
KEYBOARD_KEY_d9=brightnessup KEYBOARD_KEY_d9=brightnessup
KEYBOARD_KEY_ee=screenlock KEYBOARD_KEY_ee=screenlock
@ -2010,8 +2010,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*M30X:*
KEYBOARD_KEY_d9=brightnessup KEYBOARD_KEY_d9=brightnessup
KEYBOARD_KEY_ee=screenlock KEYBOARD_KEY_ee=screenlock
KEYBOARD_KEY_93=media KEYBOARD_KEY_93=media
KEYBOARD_KEY_9e=f22 # touchpad enable KEYBOARD_KEY_9e=touchpad_on # touchpad enable
KEYBOARD_KEY_9f=f23 # touchpad disable KEYBOARD_KEY_9f=touchpad_off # touchpad disable
# Satellite P75-A # Satellite P75-A
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:*
@ -2025,14 +2025,14 @@ evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSATELLITEU940:*
KEYBOARD_KEY_13c=brightnessdown KEYBOARD_KEY_13c=brightnessdown
KEYBOARD_KEY_13d=brightnessup KEYBOARD_KEY_13d=brightnessup
KEYBOARD_KEY_13e=switchvideomode KEYBOARD_KEY_13e=switchvideomode
KEYBOARD_KEY_13f=f21 # Touchpad toggle KEYBOARD_KEY_13f=touchpad_toggle # Touchpad toggle
# Satellite P75-A7200 # Satellite P75-A7200
evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:* evdev:name:Toshiba*input*device:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnSatellite*P75-A:*
KEYBOARD_KEY_13c=brightnessdown KEYBOARD_KEY_13c=brightnessdown
KEYBOARD_KEY_13d=brightnessup KEYBOARD_KEY_13d=brightnessup
KEYBOARD_KEY_13e=switchvideomode KEYBOARD_KEY_13e=switchvideomode
KEYBOARD_KEY_13f=f21 # Touchpad toggle KEYBOARD_KEY_13f=touchpad_toggle # Touchpad toggle
KEYBOARD_KEY_9e=wlan KEYBOARD_KEY_9e=wlan
# Portege Z830 ACPI quickstart buttons # Portege Z830 ACPI quickstart buttons
@ -2043,7 +2043,7 @@ evdev:name:Quickstart Button 2:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
KEYBOARD_KEY_1=prog2 # TOSHIBA Presentation button KEYBOARD_KEY_1=prog2 # TOSHIBA Presentation button
evdev:name:Quickstart Button 3:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:* evdev:name:Quickstart Button 3:dmi:bvn*:bvr*:bd*:svnTOSHIBA*:pnPORTEGEZ830:*
KEYBOARD_KEY_1=f21 # Touchpad toggle KEYBOARD_KEY_1=touchpad_toggle # Touchpad toggle
########################################################### ###########################################################
# VIA # VIA
@ -2057,7 +2057,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:*
########################################################### ###########################################################
evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:bd*:svnVIOS:pnLTH17:* evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:bd*:svnVIOS:pnLTH17:*
KEYBOARD_KEY_70073=f21 # Touchpad toggle KEYBOARD_KEY_70073=touchpad_toggle # Touchpad toggle
########################################################### ###########################################################
# WeiHeng # WeiHeng
@ -2065,7 +2065,7 @@ evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:bd*:svnVIOS:pnLTH17:*
# P325J # P325J
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINET:pnP325J:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINET:pnP325J:*
KEYBOARD_KEY_76=f21 # Touchpad toggle KEYBOARD_KEY_76=touchpad_toggle # Touchpad toggle
########################################################### ###########################################################
# Xiaomi # Xiaomi
@ -2091,8 +2091,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnZepto:pnZnote:*
KEYBOARD_KEY_93=switchvideomode # Fn+F3 Toggle Video Output KEYBOARD_KEY_93=switchvideomode # Fn+F3 Toggle Video Output
KEYBOARD_KEY_95=brightnessdown # Fn+F4 Brightness Down KEYBOARD_KEY_95=brightnessdown # Fn+F4 Brightness Down
KEYBOARD_KEY_91=brightnessup # Fn+F5 Brightness Up KEYBOARD_KEY_91=brightnessup # Fn+F5 Brightness Up
KEYBOARD_KEY_a5=f23 # Fn+F6 Disable Touchpad KEYBOARD_KEY_a5=touchpad_off # Fn+F6 Disable Touchpad
KEYBOARD_KEY_a6=f22 # Fn+F6 Enable Touchpad KEYBOARD_KEY_a6=touchpad_on # Fn+F6 Enable Touchpad
KEYBOARD_KEY_a7=bluetooth # Fn+F10 Enable Bluetooth KEYBOARD_KEY_a7=bluetooth # Fn+F10 Enable Bluetooth
KEYBOARD_KEY_a9=bluetooth # Fn+F10 Disable Bluetooth KEYBOARD_KEY_a9=bluetooth # Fn+F10 Disable Bluetooth
KEYBOARD_KEY_f1=wlan # RF Switch Off KEYBOARD_KEY_f1=wlan # RF Switch Off
@ -2192,7 +2192,7 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnViewSonic:pnVPAD10:*
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:bd*:svnPositivoBahia-VAIO:pnVJPW1[12]F11X*:pvr*:* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:bd*:svnPositivoBahia-VAIO:pnVJPW1[12]F11X*:pvr*:*
# Vaio FE14 (VJFE41F11X, VJE42F11X, VJFE44F11X, VJFE54F11X) # Vaio FE14 (VJFE41F11X, VJE42F11X, VJFE44F11X, VJFE54F11X)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:bd*:svnPositivoBahia-VAIO:pnVJFE*:pvr*:* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:bd*:svnPositivoBahia-VAIO:pnVJFE*:pvr*:*
KEYBOARD_KEY_76=f21 # Fn+F1 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+F1 toggle touchpad
########################################################### ###########################################################
# Positivo # Positivo
@ -2203,23 +2203,23 @@ evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr*:rvnPositivoTecnologiaSA:rnCF40CM-V2* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr*:rvnPositivoTecnologiaSA:rnCF40CM-V2*
# Positivo DUO (k116) # Positivo DUO (k116)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr*:rvnPositivoTecnologiaSA:rnK116* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivoTecnologiaSA:pn*:pvr*:rvnPositivoTecnologiaSA:rnK116*
KEYBOARD_KEY_76=f21 # Fn+F1 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+F1 toggle touchpad
# Positivo (N14NPE-N, N15NPE-N) # Positivo (N14NPE-N, N15NPE-N)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivo*:pn*:pvr*:rvnPositivo*:rnN1[45]NPE-N* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivo*:pn*:pvr*:rvnPositivo*:rnN1[45]NPE-N*
KEYBOARD_KEY_76=f21 # Fn+F1 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+F1 toggle touchpad
KEYBOARD_KEY_dd=search KEYBOARD_KEY_dd=search
# Positivo (N15EPE, N14EPE) # Positivo (N15EPE, N14EPE)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivo*:pn*:pvr*:rvnPositivo*:rnN1[45]EPE* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:svnPositivo*:pn*:pvr*:rvnPositivo*:rnN1[45]EPE*
KEYBOARD_KEY_76=f21 # Fn+F1 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+F1 toggle touchpad
KEYBOARD_KEY_6e=search KEYBOARD_KEY_6e=search
# Positivo (CG15D) # Positivo (CG15D)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnCG15D* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnCG15D*
# Positivo Motion (N14AP7, N14DP6, N14DP7, N14DP7-V2, N14DP9, N14JP6, N14KP6) # Positivo Motion (N14AP7, N14DP6, N14DP7, N14DP7-V2, N14DP9, N14JP6, N14KP6)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnN14[ADJK]P* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnN14[ADJK]P*
KEYBOARD_KEY_76=f21 # Fn+f2 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+f2 toggle touchpad
KEYBOARD_KEY_67=prog1 # Programmable button KEYBOARD_KEY_67=prog1 # Programmable button
KEYBOARD_KEY_68=prog2 # Programmable button KEYBOARD_KEY_68=prog2 # Programmable button
KEYBOARD_KEY_69=prog3 # Programmable button KEYBOARD_KEY_69=prog3 # Programmable button
@ -2233,7 +2233,7 @@ evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn
evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:br*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnN14EP6* evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:br*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnN14EP6*
# Positivo Motion (CW14Q01P) (CW14Q01P-V2) # Positivo Motion (CW14Q01P) (CW14Q01P-V2)
evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnCW14Q01P* evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn*:pvr*:rvn*:rnCW14Q01P*
KEYBOARD_KEY_70073=f21 # Fn+f2 toggle touchpad KEYBOARD_KEY_70073=touchpad_toggle # Fn+f2 toggle touchpad
KEYBOARD_KEY_7006b=prog1 # Programmable button KEYBOARD_KEY_7006b=prog1 # Programmable button
KEYBOARD_KEY_7006c=prog2 # Programmable button KEYBOARD_KEY_7006c=prog2 # Programmable button
KEYBOARD_KEY_7006d=prog3 # Programmable button KEYBOARD_KEY_7006d=prog3 # Programmable button
@ -2244,7 +2244,7 @@ evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:svnPositivoTecnologiaSA:pn
########################################################### ###########################################################
# Multilaser Ultra (UL154) # Multilaser Ultra (UL154)
evdev:name:AT Translated Set 2 keyboard:dmi:bvn*bvr*:svnMultilaserIndustrial:pn*:pvr*:rvn*:rnUL154* evdev:name:AT Translated Set 2 keyboard:dmi:bvn*bvr*:svnMultilaserIndustrial:pn*:pvr*:rvn*:rnUL154*
KEYBOARD_KEY_76=f21 # Fn+f2 toggle touchpad KEYBOARD_KEY_76=touchpad_toggle # Fn+f2 toggle touchpad
########################################################### ###########################################################
# Other # Other

View File

@ -962,7 +962,9 @@ default ignore - -</programlisting>
discovered/supported/used, prints <literal>no</literal>. Otherwise prints discovered/supported/used, prints <literal>no</literal>. Otherwise prints
<literal>partial</literal>. In either of these two cases exits with non-zero exit status. It also shows <literal>partial</literal>. In either of these two cases exits with non-zero exit status. It also shows
five lines indicating separately whether firmware, drivers, the system, the kernel and libraries five lines indicating separately whether firmware, drivers, the system, the kernel and libraries
discovered/support/use TPM2.</para> discovered/support/use TPM2. Currently, required libraries are <filename>libtss2-esys.so.0</filename>,
<filename>libtss2-rc.so.0</filename>, and <filename>libtss2-mu.so.0</filename>. The requirement may be
changed in the future release.</para>
<para>Note, this checks for TPM 2.0 devices only, and does not consider TPM 1.2 at all.</para> <para>Note, this checks for TPM 2.0 devices only, and does not consider TPM 1.2 at all.</para>

View File

@ -29,7 +29,7 @@
<refsect1> <refsect1>
<title>Description</title> <title>Description</title>
<para><command>systemd-nsresourced</command> is a system service that permits transient delegation of a a <para><command>systemd-nsresourced</command> is a system service that permits transient delegation of a
UID/GID range to a user namespace (see <citerefentry UID/GID range to a user namespace (see <citerefentry
project='man-pages'><refentrytitle>user_namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>) project='man-pages'><refentrytitle>user_namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>)
allocated by a client, via a Varlink IPC API.</para> allocated by a client, via a Varlink IPC API.</para>

View File

@ -3,18 +3,11 @@
set -e set -e
set -o nounset set -o nounset
if [[ "$DISTRIBUTION" =~ ubuntu|debian ]]; then
SUDO_GROUP=sudo
else
SUDO_GROUP=wheel
fi
useradd \ useradd \
--uid 4711 \ --uid 4711 \
--user-group \ --user-group \
--create-home \ --create-home \
--password "$(openssl passwd -1 testuser)" \ --password "$(openssl passwd -1 testuser)" \
--groups "$SUDO_GROUP",systemd-journal \
--shell /bin/bash \ --shell /bin/bash \
testuser testuser

View File

@ -67,7 +67,7 @@ _systemd_analyze() {
) )
local -A VERBS=( local -A VERBS=(
[STANDALONE]='time blame unit-files unit-paths exit-status compare-versions calendar timestamp timespan pcrs srk' [STANDALONE]='time blame unit-files unit-paths exit-status compare-versions calendar timestamp timespan pcrs srk has-tpm2'
[CRITICAL_CHAIN]='critical-chain' [CRITICAL_CHAIN]='critical-chain'
[DOT]='dot' [DOT]='dot'
[DUMP]='dump' [DUMP]='dump'

View File

@ -73,6 +73,7 @@ JSON or table format'
'timespan:Parse a systemd syntax timespan' 'timespan:Parse a systemd syntax timespan'
'security:Analyze security settings of a service' 'security:Analyze security settings of a service'
'inspect-elf:Parse and print ELF package metadata' 'inspect-elf:Parse and print ELF package metadata'
'has-tpm2:Report whether TPM2 support is available'
# log-level, log-target, service-watchdogs have been deprecated # log-level, log-target, service-watchdogs have been deprecated
) )

View File

@ -96,7 +96,7 @@ int verb_pcrs(int argc, char *argv[], void *userdata) {
const char *alg = NULL; const char *alg = NULL;
int r; int r;
if (tpm2_support() != TPM2_SUPPORT_FULL) if (!tpm2_is_fully_supported())
log_notice("System lacks full TPM2 support, not showing PCR state."); log_notice("System lacks full TPM2 support, not showing PCR state.");
else { else {
r = get_pcr_alg(&alg); r = get_pcr_alg(&alg);

View File

@ -411,7 +411,6 @@ int verb_status(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL, *stub_path = NULL, _cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL, *stub_path = NULL,
*current_entry = NULL, *oneshot_entry = NULL, *default_entry = NULL; *current_entry = NULL, *oneshot_entry = NULL, *default_entry = NULL;
uint64_t loader_features = 0, stub_features = 0; uint64_t loader_features = 0, stub_features = 0;
Tpm2Support s;
int have; int have;
(void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE(LoaderFirmwareType), &fw_type); (void) efi_get_variable_string_and_warn(EFI_LOADER_VARIABLE(LoaderFirmwareType), &fw_type);
@ -440,7 +439,7 @@ int verb_status(int argc, char *argv[], void *userdata) {
else else
printf("\n"); printf("\n");
s = tpm2_support(); Tpm2Support s = tpm2_support_full(TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER);
printf(" TPM2 Support: %s%s%s\n", printf(" TPM2 Support: %s%s%s\n",
FLAGS_SET(s, TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER) ? ansi_highlight_green() : FLAGS_SET(s, TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER) ? ansi_highlight_green() :
(s & (TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER)) != 0 ? ansi_highlight_red() : ansi_highlight_yellow(), (s & (TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER)) != 0 ? ansi_highlight_red() : ansi_highlight_yellow(),

View File

@ -450,7 +450,7 @@ static size_t pe_section_table_find_profile_length(
assert(start >= section_table); assert(start >= section_table);
assert(start < section_table + n_section_table); assert(start < section_table + n_section_table);
/* Look for the next .profile (or the end of the table), this is where the the sections for this /* Look for the next .profile (or the end of the table), this is where the sections for this
* profile end. The base profile does not start with a .profile, the others do, hence conditionally * profile end. The base profile does not start with a .profile, the others do, hence conditionally
* skip over the first entry. */ * skip over the first entry. */
const PeSectionHeader *e; const PeSectionHeader *e;
@ -485,7 +485,7 @@ EFI_STATUS pe_locate_profile_sections(
if (!p) if (!p)
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
/* Look for the next .profile (or the end of the table), this is where the the sections for this /* Look for the next .profile (or the end of the table), this is where the sections for this
* profile end. */ * profile end. */
size_t n = pe_section_table_find_profile_length(section_table, n_section_table, p, profile); size_t n = pe_section_table_find_profile_length(section_table, n_section_table, p, profile);

View File

@ -1005,7 +1005,7 @@ static int validate_stub(void) {
bool found = false; bool found = false;
int r; int r;
if (tpm2_support() != TPM2_SUPPORT_FULL) if (!tpm2_is_fully_supported())
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Sorry, system lacks full TPM2 support."); return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Sorry, system lacks full TPM2 support.");
r = efi_stub_get_features(&features); r = efi_stub_get_features(&features);

View File

@ -1229,7 +1229,7 @@ static int generic_method_get_interface_description(
sd_varlink_method_flags_t flags, sd_varlink_method_flags_t flags,
void *userdata) { void *userdata) {
static const struct sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "interface", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY }, { "interface", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY },
{} {}
}; };

View File

@ -416,19 +416,18 @@ static int list_machine_one(sd_varlink *link, Machine *m, bool more) {
} }
static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
Manager *m = ASSERT_PTR(userdata); static const sd_json_dispatch_field dispatch_table[] = {
const char *mn = NULL; { "name", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, 0 },
const sd_json_dispatch_field dispatch_table[] = {
{ "name", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, PTR_TO_SIZE(&mn), 0 },
{} {}
}; };
Manager *m = ASSERT_PTR(userdata);
const char *mn = NULL;
int r; int r;
assert(parameters); assert(parameters);
r = sd_varlink_dispatch(link, parameters, dispatch_table, 0); r = sd_varlink_dispatch(link, parameters, dispatch_table, &mn);
if (r != 0) if (r != 0)
return r; return r;

View File

@ -97,8 +97,8 @@ static int neighbor_append_json(Neighbor *n, sd_json_variant **array) {
return sd_json_variant_append_arraybo( return sd_json_variant_append_arraybo(
array, array,
SD_JSON_BUILD_PAIR_INTEGER("Family", n->family), SD_JSON_BUILD_PAIR_INTEGER("Family", n->dst_addr.family),
JSON_BUILD_PAIR_IN_ADDR("Destination", &n->in_addr, n->family), JSON_BUILD_PAIR_IN_ADDR("Destination", &n->dst_addr.address, n->dst_addr.family),
JSON_BUILD_PAIR_HW_ADDR("LinkLayerAddress", &n->ll_addr), JSON_BUILD_PAIR_HW_ADDR("LinkLayerAddress", &n->ll_addr),
SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(n->source)), SD_JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(n->source)),
SD_JSON_BUILD_PAIR_STRING("ConfigState", state)); SD_JSON_BUILD_PAIR_STRING("ConfigState", state));
@ -168,7 +168,7 @@ static int nexthop_append_json(NextHop *n, sd_json_variant **array) {
return sd_json_variant_append_arraybo( return sd_json_variant_append_arraybo(
array, array,
SD_JSON_BUILD_PAIR_UNSIGNED("ID", n->id), SD_JSON_BUILD_PAIR_UNSIGNED("ID", n->id),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("Gateway", &n->gw, n->family), JSON_BUILD_PAIR_IN_ADDR_NON_NULL("Gateway", &n->gw.address, n->family),
SD_JSON_BUILD_PAIR_UNSIGNED("Flags", n->flags), SD_JSON_BUILD_PAIR_UNSIGNED("Flags", n->flags),
SD_JSON_BUILD_PAIR_STRING("FlagsString", strempty(flags)), SD_JSON_BUILD_PAIR_STRING("FlagsString", strempty(flags)),
SD_JSON_BUILD_PAIR_UNSIGNED("Protocol", n->protocol), SD_JSON_BUILD_PAIR_UNSIGNED("Protocol", n->protocol),

View File

@ -147,29 +147,29 @@ static int neighbor_dup(const Neighbor *neighbor, Neighbor **ret) {
static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) { static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
assert(neighbor); assert(neighbor);
siphash24_compress_typesafe(neighbor->family, state); siphash24_compress_typesafe(neighbor->dst_addr.family, state);
if (!IN_SET(neighbor->family, AF_INET, AF_INET6)) if (!IN_SET(neighbor->dst_addr.family, AF_INET, AF_INET6))
/* treat any other address family as AF_UNSPEC */ /* treat any other address family as AF_UNSPEC */
return; return;
/* Equality of neighbors are given by the destination address. /* Equality of neighbors are given by the destination address.
* See neigh_lookup() in the kernel. */ * See neigh_lookup() in the kernel. */
in_addr_hash_func(&neighbor->in_addr, neighbor->family, state); in_addr_hash_func(&neighbor->dst_addr.address, neighbor->dst_addr.family, state);
} }
static int neighbor_compare_func(const Neighbor *a, const Neighbor *b) { static int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
int r; int r;
r = CMP(a->family, b->family); r = CMP(a->dst_addr.family, b->dst_addr.family);
if (r != 0) if (r != 0)
return r; return r;
if (!IN_SET(a->family, AF_INET, AF_INET6)) if (!IN_SET(a->dst_addr.family, AF_INET, AF_INET6))
/* treat any other address family as AF_UNSPEC */ /* treat any other address family as AF_UNSPEC */
return 0; return 0;
return memcmp(&a->in_addr, &b->in_addr, FAMILY_ADDRESS_SIZE(a->family)); return memcmp(&a->dst_addr.address, &b->dst_addr.address, FAMILY_ADDRESS_SIZE(a->dst_addr.family));
} }
static int neighbor_get_request(Link *link, const Neighbor *neighbor, Request **ret) { static int neighbor_get_request(Link *link, const Neighbor *neighbor, Request **ret) {
@ -244,7 +244,7 @@ static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const
"%s %s neighbor (%s): lladdr: %s, dst: %s", "%s %s neighbor (%s): lladdr: %s, dst: %s",
str, strna(network_config_source_to_string(neighbor->source)), strna(state), str, strna(network_config_source_to_string(neighbor->source)), strna(state),
HW_ADDR_TO_STR(&neighbor->ll_addr), HW_ADDR_TO_STR(&neighbor->ll_addr),
IN_ADDR_TO_STRING(neighbor->family, &neighbor->in_addr)); IN_ADDR_TO_STRING(neighbor->dst_addr.family, &neighbor->dst_addr.address));
} }
static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) { static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
@ -261,7 +261,7 @@ static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
log_neighbor_debug(neighbor, "Configuring", link); log_neighbor_debug(neighbor, "Configuring", link);
r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_NEWNEIGH, r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_NEWNEIGH,
link->ifindex, neighbor->family); link->ifindex, neighbor->dst_addr.family);
if (r < 0) if (r < 0)
return r; return r;
@ -273,7 +273,7 @@ static int neighbor_configure(Neighbor *neighbor, Link *link, Request *req) {
if (r < 0) if (r < 0)
return r; return r;
r = netlink_message_append_in_addr_union(m, NDA_DST, neighbor->family, &neighbor->in_addr); r = netlink_message_append_in_addr_union(m, NDA_DST, neighbor->dst_addr.family, &neighbor->dst_addr.address);
if (r < 0) if (r < 0)
return r; return r;
@ -338,7 +338,7 @@ static int link_request_neighbor(Link *link, const Neighbor *neighbor) {
"The link layer address length (%zu) for neighbor %s does not match with " "The link layer address length (%zu) for neighbor %s does not match with "
"the hardware address length (%zu), ignoring the setting.", "the hardware address length (%zu), ignoring the setting.",
neighbor->ll_addr.length, neighbor->ll_addr.length,
IN_ADDR_TO_STRING(neighbor->family, &neighbor->in_addr), IN_ADDR_TO_STRING(neighbor->dst_addr.family, &neighbor->dst_addr.address),
link->hw_addr.length); link->hw_addr.length);
return 0; return 0;
} }
@ -451,11 +451,11 @@ int neighbor_remove(Neighbor *neighbor, Link *link) {
log_neighbor_debug(neighbor, "Removing", link); log_neighbor_debug(neighbor, "Removing", link);
r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_DELNEIGH, r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_DELNEIGH,
link->ifindex, neighbor->family); link->ifindex, neighbor->dst_addr.family);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not allocate RTM_DELNEIGH message: %m"); return log_link_error_errno(link, r, "Could not allocate RTM_DELNEIGH message: %m");
r = netlink_message_append_in_addr_union(m, NDA_DST, neighbor->family, &neighbor->in_addr); r = netlink_message_append_in_addr_union(m, NDA_DST, neighbor->dst_addr.family, &neighbor->dst_addr.address);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append NDA_DST attribute: %m"); return log_link_error_errno(link, r, "Could not append NDA_DST attribute: %m");
@ -593,19 +593,19 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
return log_oom(); return log_oom();
/* First, retrieve the fundamental information about the neighbor. */ /* First, retrieve the fundamental information about the neighbor. */
r = sd_rtnl_message_neigh_get_family(message, &tmp->family); r = sd_rtnl_message_neigh_get_family(message, &tmp->dst_addr.family);
if (r < 0) { if (r < 0) {
log_link_warning(link, "rtnl: received neighbor message without family, ignoring."); log_link_warning(link, "rtnl: received neighbor message without family, ignoring.");
return 0; return 0;
} }
if (tmp->family == AF_BRIDGE) /* Currently, we do not support it. */ if (tmp->dst_addr.family == AF_BRIDGE) /* Currently, we do not support it. */
return 0; return 0;
if (!IN_SET(tmp->family, AF_INET, AF_INET6)) { if (!IN_SET(tmp->dst_addr.family, AF_INET, AF_INET6)) {
log_link_debug(link, "rtnl: received neighbor message with invalid family '%i', ignoring.", tmp->family); log_link_debug(link, "rtnl: received neighbor message with invalid family '%i', ignoring.", tmp->dst_addr.family);
return 0; return 0;
} }
r = netlink_message_read_in_addr_union(message, NDA_DST, tmp->family, &tmp->in_addr); r = netlink_message_read_in_addr_union(message, NDA_DST, tmp->dst_addr.family, &tmp->dst_addr.address);
if (r < 0) { if (r < 0) {
log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m"); log_link_warning_errno(link, r, "rtnl: received neighbor message without valid address, ignoring: %m");
return 0; return 0;
@ -660,28 +660,28 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
return 1; return 1;
} }
#define log_neighbor_section(neighbor, fmt, ...) \
({ \
const Neighbor *_neighbor = (neighbor); \
log_section_warning_errno( \
_neighbor ? _neighbor->section : NULL, \
SYNTHETIC_ERRNO(EINVAL), \
fmt " Ignoring [Neighbor] section.", \
##__VA_ARGS__); \
})
static int neighbor_section_verify(Neighbor *neighbor) { static int neighbor_section_verify(Neighbor *neighbor) {
if (section_is_invalid(neighbor->section)) if (section_is_invalid(neighbor->section))
return -EINVAL; return -EINVAL;
if (neighbor->family == AF_UNSPEC) if (neighbor->dst_addr.family == AF_UNSPEC)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_neighbor_section(neighbor, "Neighbor section without Address= configured.");
"%s: Neighbor section without Address= configured. "
"Ignoring [Neighbor] section from line %u.",
neighbor->section->filename, neighbor->section->line);
if (neighbor->family == AF_INET6 && !socket_ipv6_is_supported()) if (neighbor->dst_addr.family == AF_INET6 && !socket_ipv6_is_supported())
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_neighbor_section(neighbor, "Neighbor section with an IPv6 destination address configured, but the kernel does not support IPv6.");
"%s: Neighbor section with an IPv6 destination address configured, "
"but the kernel does not support IPv6. "
"Ignoring [Neighbor] section from line %u.",
neighbor->section->filename, neighbor->section->line);
if (neighbor->ll_addr.length == 0) if (neighbor->ll_addr.length == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_neighbor_section(neighbor, "Neighbor section without LinkLayerAddress= configured.");
"%s: Neighbor section without LinkLayerAddress= configured. "
"Ignoring [Neighbor] section from line %u.",
neighbor->section->filename, neighbor->section->line);
return 0; return 0;
} }
@ -709,7 +709,7 @@ int network_drop_invalid_neighbors(Network *network) {
log_warning("%s: Duplicated neighbor settings for %s is specified at line %u and %u, " log_warning("%s: Duplicated neighbor settings for %s is specified at line %u and %u, "
"dropping the neighbor setting specified at line %u.", "dropping the neighbor setting specified at line %u.",
dup->section->filename, dup->section->filename,
IN_ADDR_TO_STRING(neighbor->family, &neighbor->in_addr), IN_ADDR_TO_STRING(neighbor->dst_addr.family, &neighbor->dst_addr.address),
neighbor->section->line, neighbor->section->line,
dup->section->line, dup->section->line); dup->section->line, dup->section->line);
/* neighbor_detach() will drop the neighbor from neighbors_by_section. */ /* neighbor_detach() will drop the neighbor from neighbors_by_section. */
@ -728,7 +728,7 @@ int network_drop_invalid_neighbors(Network *network) {
} }
int config_parse_neighbor_address( int config_parse_neighbor_section(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -740,76 +740,26 @@ int config_parse_neighbor_address(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(neighbor_unref_or_set_invalidp) Neighbor *n = NULL; static const ConfigSectionParser table[_NEIGHBOR_CONF_PARSER_MAX] = {
[NEIGHBOR_DESTINATION_ADDRESS] = { .parser = config_parse_in_addr_data, .ltype = 0, .offset = offsetof(Neighbor, dst_addr), },
[NEIGHBOR_LINK_LAYER_ADDRESS] = { .parser = config_parse_hw_addr, .ltype = 0, .offset = offsetof(Neighbor, ll_addr), },
};
_cleanup_(neighbor_unref_or_set_invalidp) Neighbor *neighbor = NULL;
Network *network = ASSERT_PTR(userdata); Network *network = ASSERT_PTR(userdata);
int r; int r;
assert(filename); assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
r = neighbor_new_static(network, filename, section_line, &n); r = neighbor_new_static(network, filename, section_line, &neighbor);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
if (isempty(rvalue)) { r = config_section_parse(table, ELEMENTSOF(table),
n->family = AF_UNSPEC; unit, filename, line, section, section_line, lvalue, ltype, rvalue, neighbor);
n->in_addr = IN_ADDR_NULL; if (r <= 0) /* 0 means non-critical error, but the section will be ignored. */
TAKE_PTR(n); return r;
return 0;
}
r = in_addr_from_string_auto(rvalue, &n->family, &n->in_addr); TAKE_PTR(neighbor);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Neighbor Address is invalid, ignoring assignment: %s", rvalue);
return 0;
}
TAKE_PTR(n);
return 0;
}
int config_parse_neighbor_lladdr(
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_(neighbor_unref_or_set_invalidp) Neighbor *n = NULL;
Network *network = ASSERT_PTR(userdata);
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
r = neighbor_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
n->ll_addr = HW_ADDR_NULL;
TAKE_PTR(n);
return 0;
}
r = parse_hw_addr(rvalue, &n->ll_addr);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Neighbor %s= is invalid, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
TAKE_PTR(n);
return 0; return 0;
} }

View File

@ -23,8 +23,7 @@ typedef struct Neighbor {
unsigned n_ref; unsigned n_ref;
int family; struct in_addr_data dst_addr;
union in_addr_union in_addr;
struct hw_addr_data ll_addr; struct hw_addr_data ll_addr;
} Neighbor; } Neighbor;
@ -46,5 +45,11 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Neighbor, neighbor); DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Neighbor, neighbor);
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_address); typedef enum NeighborConfParserType {
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_lladdr); NEIGHBOR_DESTINATION_ADDRESS,
NEIGHBOR_LINK_LAYER_ADDRESS,
_NEIGHBOR_CONF_PARSER_MAX,
_NEIGHBOR_CONF_PARSER_INVALID = -EINVAL,
} NeighborConfParserType;
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_section);

View File

@ -173,9 +173,9 @@ Address.NetLabel, config_parse_address_section,
Address.NFTSet, config_parse_address_section, ADDRESS_NFT_SET, 0 Address.NFTSet, config_parse_address_section, ADDRESS_NFT_SET, 0
IPv6AddressLabel.Prefix, config_parse_ipv6_address_label_section, IPV6_ADDRESS_LABEL_PREFIX, 0 IPv6AddressLabel.Prefix, config_parse_ipv6_address_label_section, IPV6_ADDRESS_LABEL_PREFIX, 0
IPv6AddressLabel.Label, config_parse_ipv6_address_label_section, IPV6_ADDRESS_LABEL, 0 IPv6AddressLabel.Label, config_parse_ipv6_address_label_section, IPV6_ADDRESS_LABEL, 0
Neighbor.Address, config_parse_neighbor_address, 0, 0 Neighbor.Address, config_parse_neighbor_section, NEIGHBOR_DESTINATION_ADDRESS, 0
Neighbor.LinkLayerAddress, config_parse_neighbor_lladdr, 0, 0 Neighbor.LinkLayerAddress, config_parse_neighbor_section, NEIGHBOR_LINK_LAYER_ADDRESS, 0
Neighbor.MACAddress, config_parse_neighbor_lladdr, 0, 0 /* deprecated */ Neighbor.MACAddress, config_parse_neighbor_section, NEIGHBOR_LINK_LAYER_ADDRESS, 0 /* deprecated */
RoutingPolicyRule.TypeOfService, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_TOS, 0 RoutingPolicyRule.TypeOfService, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_TOS, 0
RoutingPolicyRule.Priority, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_PRIORITY, 0 RoutingPolicyRule.Priority, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_PRIORITY, 0
RoutingPolicyRule.GoTo, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_GOTO, 0 RoutingPolicyRule.GoTo, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_GOTO, 0
@ -219,12 +219,12 @@ Route.QuickAck, config_parse_route_metric_boolean,
Route.TCPCongestionControlAlgorithm, config_parse_route_metric_tcp_congestion, RTAX_CC_ALGO, 0 Route.TCPCongestionControlAlgorithm, config_parse_route_metric_tcp_congestion, RTAX_CC_ALGO, 0
Route.FastOpenNoCookie, config_parse_route_metric_boolean, RTAX_FASTOPEN_NO_COOKIE, 0 Route.FastOpenNoCookie, config_parse_route_metric_boolean, RTAX_FASTOPEN_NO_COOKIE, 0
Route.TTLPropagate, config_parse_warn_compat, DISABLED_LEGACY, 0 Route.TTLPropagate, config_parse_warn_compat, DISABLED_LEGACY, 0
NextHop.Id, config_parse_nexthop_id, 0, 0 NextHop.Id, config_parse_nexthop_section, NEXTHOP_ID, 0
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0 NextHop.Gateway, config_parse_nexthop_section, NEXTHOP_GATEWAY, 0
NextHop.Family, config_parse_nexthop_family, 0, 0 NextHop.Family, config_parse_nexthop_section, NEXTHOP_FAMILY, 0
NextHop.OnLink, config_parse_nexthop_onlink, 0, 0 NextHop.OnLink, config_parse_nexthop_section, NEXTHOP_ONLINK, 0
NextHop.Blackhole, config_parse_nexthop_blackhole, 0, 0 NextHop.Blackhole, config_parse_nexthop_section, NEXTHOP_BLACKHOLE, 0
NextHop.Group, config_parse_nexthop_group, 0, 0 NextHop.Group, config_parse_nexthop_section, NEXTHOP_GROUP, 0
DHCPv4.RequestAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_request_address) DHCPv4.RequestAddress, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_request_address)
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCPv4.UseDNS, config_parse_tristate, 0, offsetof(Network, dhcp_use_dns) DHCPv4.UseDNS, config_parse_tristate, 0, offsetof(Network, dhcp_use_dns)

View File

@ -854,7 +854,7 @@ bool network_has_static_ipv6_configurations(Network *network) {
return true; return true;
ORDERED_HASHMAP_FOREACH(neighbor, network->neighbors_by_section) ORDERED_HASHMAP_FOREACH(neighbor, network->neighbors_by_section)
if (neighbor->family == AF_INET6) if (neighbor->dst_addr.family == AF_INET6)
return true; return true;
if (!hashmap_isempty(network->address_labels_by_section)) if (!hashmap_isempty(network->address_labels_by_section))

View File

@ -236,7 +236,7 @@ static int nexthop_compare_full(const NextHop *a, const NextHop *b) {
return r; return r;
if (IN_SET(a->family, AF_INET, AF_INET6)) { if (IN_SET(a->family, AF_INET, AF_INET6)) {
r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family)); r = memcmp(&a->gw.address, &b->gw.address, FAMILY_ADDRESS_SIZE(a->family));
if (r != 0) if (r != 0)
return r; return r;
} }
@ -481,7 +481,7 @@ static void log_nexthop_debug(const NextHop *nexthop, const char *str, Manager *
log_link_debug(link, "%s %s nexthop (%s): id: %"PRIu32", gw: %s, blackhole: %s, group: %s, flags: %s", log_link_debug(link, "%s %s nexthop (%s): id: %"PRIu32", gw: %s, blackhole: %s, group: %s, flags: %s",
str, strna(network_config_source_to_string(nexthop->source)), strna(state), str, strna(network_config_source_to_string(nexthop->source)), strna(state),
nexthop->id, nexthop->id,
IN_ADDR_TO_STRING(nexthop->family, &nexthop->gw), IN_ADDR_TO_STRING(nexthop->family, &nexthop->gw.address),
yes_no(nexthop->blackhole), strna(group), strna(flags)); yes_no(nexthop->blackhole), strna(group), strna(flags));
} }
@ -627,8 +627,8 @@ static int nexthop_configure(NextHop *nexthop, Link *link, Request *req) {
if (r < 0) if (r < 0)
return r; return r;
if (in_addr_is_set(nexthop->family, &nexthop->gw)) { if (in_addr_is_set(nexthop->family, &nexthop->gw.address)) {
r = netlink_message_append_in_addr_union(m, NHA_GATEWAY, nexthop->family, &nexthop->gw); r = netlink_message_append_in_addr_union(m, NHA_GATEWAY, nexthop->family, &nexthop->gw.address);
if (r < 0) if (r < 0)
return r; return r;
@ -722,7 +722,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
return r; return r;
} }
return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw); return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw.address);
} }
static int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) { static int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) {
@ -1093,9 +1093,9 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
(void) nexthop_update_group(nexthop, message); (void) nexthop_update_group(nexthop, message);
if (nexthop->family != AF_UNSPEC) { if (nexthop->family != AF_UNSPEC) {
r = netlink_message_read_in_addr_union(message, NHA_GATEWAY, nexthop->family, &nexthop->gw); r = netlink_message_read_in_addr_union(message, NHA_GATEWAY, nexthop->family, &nexthop->gw.address);
if (r == -ENODATA) if (r == -ENODATA)
nexthop->gw = IN_ADDR_NULL; nexthop->gw.address = IN_ADDR_NULL;
else if (r < 0) else if (r < 0)
log_debug_errno(r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m"); log_debug_errno(r, "rtnl: could not get NHA_GATEWAY attribute, ignoring: %m");
} }
@ -1129,66 +1129,60 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
return 1; return 1;
} }
#define log_nexthop_section(nexthop, fmt, ...) \
({ \
const NextHop *_nexthop = (nexthop); \
log_section_warning_errno( \
_nexthop ? _nexthop->section : NULL, \
SYNTHETIC_ERRNO(EINVAL), \
fmt " Ignoring [NextHop] section.", \
##__VA_ARGS__); \
})
static int nexthop_section_verify(NextHop *nh) { static int nexthop_section_verify(NextHop *nh) {
if (section_is_invalid(nh->section)) if (section_is_invalid(nh->section))
return -EINVAL; return -EINVAL;
if (!nh->network->manager->manage_foreign_nexthops && nh->id == 0) if (!nh->network->manager->manage_foreign_nexthops && nh->id == 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Nexthop without specifying Id= is not supported if ManageForeignNextHops=no is set in networkd.conf.");
"%s: [NextHop] section without specifying Id= is not supported "
"if ManageForeignNextHops=no is set in networkd.conf. " if (nh->family == AF_UNSPEC)
"Ignoring [NextHop] section from line %u.", nh->family = nh->gw.family;
nh->section->filename, nh->section->line); else if (nh->gw.family != AF_UNSPEC && nh->gw.family != nh->family)
return log_nexthop_section(nh, "Family= and Gateway= settings for nexthop contradict each other.");
assert(nh->gw.family == nh->family || nh->gw.family == AF_UNSPEC);
if (!hashmap_isempty(nh->group)) { if (!hashmap_isempty(nh->group)) {
if (in_addr_is_set(nh->family, &nh->gw)) if (in_addr_is_set(nh->family, &nh->gw.address))
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Nexthop group cannot have gateway address.");
"%s: nexthop group cannot have gateway address. "
"Ignoring [NextHop] section from line %u.",
nh->section->filename, nh->section->line);
if (nh->family != AF_UNSPEC) if (nh->family != AF_UNSPEC)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Nexthop group cannot have Family= setting.");
"%s: nexthop group cannot have Family= setting. "
"Ignoring [NextHop] section from line %u.",
nh->section->filename, nh->section->line);
if (nh->blackhole) if (nh->blackhole)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Nexthop group cannot be a blackhole.");
"%s: nexthop group cannot be a blackhole. "
"Ignoring [NextHop] section from line %u.",
nh->section->filename, nh->section->line);
if (nh->onlink > 0) if (nh->onlink > 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Nexthop group cannot have on-link flag.");
"%s: nexthop group cannot have on-link flag. "
"Ignoring [NextHop] section from line %u.",
nh->section->filename, nh->section->line);
} else if (nh->family == AF_UNSPEC) } else if (nh->family == AF_UNSPEC)
/* When neither Family=, Gateway=, nor Group= is specified, assume IPv4. */ /* When neither Family=, Gateway=, nor Group= is specified, assume IPv4. */
nh->family = AF_INET; nh->family = AF_INET;
if (nh->blackhole) { if (nh->blackhole) {
if (in_addr_is_set(nh->family, &nh->gw)) if (in_addr_is_set(nh->family, &nh->gw.address))
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Blackhole nexthop cannot have gateway address.");
"%s: blackhole nexthop cannot have gateway address. "
"Ignoring [NextHop] section from line %u.",
nh->section->filename, nh->section->line);
if (nh->onlink > 0) if (nh->onlink > 0)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_nexthop_section(nh, "Blackhole nexthop cannot have on-link flag.");
"%s: blackhole nexthop cannot have on-link flag. "
"Ignoring [NextHop] section from line %u.",
nh->section->filename, nh->section->line);
} }
if (nh->onlink < 0 && in_addr_is_set(nh->family, &nh->gw) && if (nh->onlink < 0 && in_addr_is_set(nh->family, &nh->gw.address) &&
ordered_hashmap_isempty(nh->network->addresses_by_section)) { ordered_hashmap_isempty(nh->network->addresses_by_section)) {
/* If no address is configured, in most cases the gateway cannot be reachable. /* If no address is configured, in most cases the gateway cannot be reachable.
* TODO: we may need to improve the condition above. */ * TODO: we may need to improve the condition above. */
log_warning("%s: Gateway= without static address configured. " log_section_warning(nh->section, "Nexthop with Gateway= specified, but no static address configured. Enabling OnLink= option.");
"Enabling OnLink= option.",
nh->section->filename);
nh->onlink = true; nh->onlink = true;
} }
@ -1262,7 +1256,7 @@ int manager_build_nexthop_ids(Manager *manager) {
return 0; return 0;
} }
int config_parse_nexthop_id( static int config_parse_nexthop_family(
const char *unit, const char *unit,
const char *filename, const char *filename,
unsigned line, unsigned line,
@ -1274,261 +1268,38 @@ int config_parse_nexthop_id(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_(nexthop_unref_or_set_invalidp) NextHop *n = NULL; int *family = ASSERT_PTR(data);
Network *network = userdata;
uint32_t id; if (isempty(rvalue))
*family = AF_UNSPEC;
else if (streq(rvalue, "ipv4"))
*family = AF_INET;
else if (streq(rvalue, "ipv6"))
*family = AF_INET6;
else
return log_syntax_parse_error(unit, filename, line, 0, lvalue, rvalue);
return 1;
}
static int config_parse_nexthop_group(
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) {
Hashmap **group = ASSERT_PTR(data);
int r; int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
if (isempty(rvalue)) { if (isempty(rvalue)) {
n->id = 0; *group = hashmap_free_free(*group);
TAKE_PTR(n); return 1;
return 0;
}
r = safe_atou32(rvalue, &id);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse nexthop id \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
if (id == 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid nexthop id \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
n->id = id;
TAKE_PTR(n);
return 0;
}
int config_parse_nexthop_gateway(
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_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
n->family = AF_UNSPEC;
n->gw = IN_ADDR_NULL;
TAKE_PTR(n);
return 0;
}
r = in_addr_from_string_auto(rvalue, &n->family, &n->gw);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue);
return 0;
}
TAKE_PTR(n);
return 0;
}
int config_parse_nexthop_family(
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_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
Network *network = userdata;
AddressFamily a;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
if (isempty(rvalue) &&
!in_addr_is_set(n->family, &n->gw)) {
/* Accept an empty string only when Gateway= is null or not specified. */
n->family = AF_UNSPEC;
TAKE_PTR(n);
return 0;
}
a = nexthop_address_family_from_string(rvalue);
if (a < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue);
return 0;
}
if (in_addr_is_set(n->family, &n->gw) &&
((a == ADDRESS_FAMILY_IPV4 && n->family == AF_INET6) ||
(a == ADDRESS_FAMILY_IPV6 && n->family == AF_INET))) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Specified family '%s' conflicts with the family of the previously specified Gateway=, "
"ignoring assignment.", rvalue);
return 0;
}
switch (a) {
case ADDRESS_FAMILY_IPV4:
n->family = AF_INET;
break;
case ADDRESS_FAMILY_IPV6:
n->family = AF_INET6;
break;
default:
assert_not_reached();
}
TAKE_PTR(n);
return 0;
}
int config_parse_nexthop_onlink(
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_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
r = parse_tristate(rvalue, &n->onlink);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
TAKE_PTR(n);
return 0;
}
int config_parse_nexthop_blackhole(
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_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
n->blackhole = r;
TAKE_PTR(n);
return 0;
}
int config_parse_nexthop_group(
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_(nexthop_unref_or_set_invalidp) NextHop *n = NULL;
Network *network = userdata;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = nexthop_new_static(network, filename, section_line, &n);
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
n->group = hashmap_free_free(n->group);
TAKE_PTR(n);
return 0;
} }
for (const char *p = rvalue;;) { for (const char *p = rvalue;;) {
@ -1538,15 +1309,10 @@ int config_parse_nexthop_group(
char *sep; char *sep;
r = extract_first_word(&p, &word, NULL, 0); r = extract_first_word(&p, &word, NULL, 0);
if (r == -ENOMEM) if (r < 0)
return log_oom(); return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
if (r == 0) if (r == 0)
break; return 1;
nhg = new0(struct nexthop_grp, 1); nhg = new0(struct nexthop_grp, 1);
if (!nhg) if (!nhg)
@ -1586,7 +1352,7 @@ int config_parse_nexthop_group(
continue; continue;
} }
r = hashmap_ensure_put(&n->group, NULL, UINT32_TO_PTR(nhg->id), nhg); r = hashmap_ensure_put(group, NULL, UINT32_TO_PTR(nhg->id), nhg);
if (r == -ENOMEM) if (r == -ENOMEM)
return log_oom(); return log_oom();
if (r == -EEXIST) { if (r == -EEXIST) {
@ -1598,7 +1364,44 @@ int config_parse_nexthop_group(
assert(r > 0); assert(r > 0);
TAKE_PTR(nhg); TAKE_PTR(nhg);
} }
}
TAKE_PTR(n); int config_parse_nexthop_section(
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) {
static const ConfigSectionParser table[_NEXTHOP_CONF_PARSER_MAX] = {
[NEXTHOP_ID] = { .parser = config_parse_uint32, .ltype = 0, .offset = offsetof(NextHop, id), },
[NEXTHOP_GATEWAY] = { .parser = config_parse_in_addr_data, .ltype = 0, .offset = offsetof(NextHop, gw), },
[NEXTHOP_FAMILY] = { .parser = config_parse_nexthop_family, .ltype = 0, .offset = offsetof(NextHop, family), },
[NEXTHOP_ONLINK] = { .parser = config_parse_tristate, .ltype = 0, .offset = offsetof(NextHop, onlink), },
[NEXTHOP_BLACKHOLE] = { .parser = config_parse_bool, .ltype = 0, .offset = offsetof(NextHop, blackhole), },
[NEXTHOP_GROUP] = { .parser = config_parse_nexthop_group, .ltype = 0, .offset = offsetof(NextHop, group), },
};
_cleanup_(nexthop_unref_or_set_invalidp) NextHop *nexthop = NULL;
Network *network = ASSERT_PTR(userdata);
int r;
assert(filename);
r = nexthop_new_static(network, filename, section_line, &nexthop);
if (r < 0)
return log_oom();
r = config_section_parse(table, ELEMENTSOF(table),
unit, filename, line, section, section_line, lvalue, ltype, rvalue, nexthop);
if (r <= 0) /* 0 means non-critical error, but the section will be ignored. */
return r;
TAKE_PTR(nexthop);
return 0; return 0;
} }

View File

@ -36,7 +36,7 @@ typedef struct NextHop {
Hashmap *group; /* NHA_GROUP */ Hashmap *group; /* NHA_GROUP */
bool blackhole; /* NHA_BLACKHOLE */ bool blackhole; /* NHA_BLACKHOLE */
int ifindex; /* NHA_OIF */ int ifindex; /* NHA_OIF */
union in_addr_union gw; /* NHA_GATEWAY */ struct in_addr_data gw; /* NHA_GATEWAY, gw.family is only used by conf parser. */
/* Only used in conf parser and nexthop_section_verify(). */ /* Only used in conf parser and nexthop_section_verify(). */
int onlink; int onlink;
@ -71,9 +71,15 @@ int manager_build_nexthop_ids(Manager *manager);
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(NextHop, nexthop); DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(NextHop, nexthop);
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_id); typedef enum NextHopConfParserType {
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_gateway); NEXTHOP_ID,
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_family); NEXTHOP_GATEWAY,
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_onlink); NEXTHOP_FAMILY,
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_blackhole); NEXTHOP_ONLINK,
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_group); NEXTHOP_BLACKHOLE,
NEXTHOP_GROUP,
_NEXTHOP_CONF_PARSER_MAX,
_NEXTHOP_CONF_PARSER_INVALID = -EINVAL,
} NextHopConfParserType;
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_section);

View File

@ -1742,7 +1742,7 @@ static int oci_seccomp_args(const char *name, sd_json_variant *v, sd_json_dispat
int r; int r;
JSON_VARIANT_ARRAY_FOREACH(e, v) { JSON_VARIANT_ARRAY_FOREACH(e, v) {
static const struct sd_json_dispatch_field table[] = { static const sd_json_dispatch_field table[] = {
{ "index", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint32, offsetof(struct scmp_arg_cmp, arg), SD_JSON_MANDATORY }, { "index", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint32, offsetof(struct scmp_arg_cmp, arg), SD_JSON_MANDATORY },
{ "value", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint64, offsetof(struct scmp_arg_cmp, datum_a), SD_JSON_MANDATORY }, { "value", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint64, offsetof(struct scmp_arg_cmp, datum_a), SD_JSON_MANDATORY },
{ "valueTwo", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint64, offsetof(struct scmp_arg_cmp, datum_b), 0 }, { "valueTwo", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint64, offsetof(struct scmp_arg_cmp, datum_b), 0 },

View File

@ -369,7 +369,7 @@ static int run(int argc, char *argv[]) {
event = TPM2_EVENT_PHASE; event = TPM2_EVENT_PHASE;
} }
if (arg_graceful && tpm2_support() != TPM2_SUPPORT_FULL) { if (arg_graceful && !tpm2_is_fully_supported()) {
log_notice("No complete TPM2 support detected, exiting gracefully."); log_notice("No complete TPM2 support detected, exiting gracefully.");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -2876,55 +2876,76 @@ static int print_answer(sd_json_variant *answer) {
return 0; return 0;
} }
typedef struct MonitorQueryParams {
sd_json_variant *question;
sd_json_variant *answer;
sd_json_variant *collected_questions;
int rcode;
int error;
int ede_code;
const char *state;
const char *result;
const char *ede_msg;
} MonitorQueryParams;
static void monitor_query_params_done(MonitorQueryParams *p) {
assert(p);
sd_json_variant_unref(p->question);
sd_json_variant_unref(p->answer);
sd_json_variant_unref(p->collected_questions);
}
static void monitor_query_dump(sd_json_variant *v) { static void monitor_query_dump(sd_json_variant *v) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *question = NULL, *answer = NULL, *collected_questions = NULL; static const sd_json_dispatch_field dispatch_table[] = {
int rcode = -1, error = 0, ede_code = -1; { "question", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, offsetof(MonitorQueryParams, question), SD_JSON_MANDATORY },
const char *state = NULL, *result = NULL, *ede_msg = NULL; { "answer", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, offsetof(MonitorQueryParams, answer), 0 },
{ "collectedQuestions", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, offsetof(MonitorQueryParams, collected_questions), 0 },
assert(v); { "state", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MonitorQueryParams, state), SD_JSON_MANDATORY },
{ "result", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MonitorQueryParams, result), 0 },
sd_json_dispatch_field dispatch_table[] = { { "rcode", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int, offsetof(MonitorQueryParams, rcode), 0 },
{ "question", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, PTR_TO_SIZE(&question), SD_JSON_MANDATORY }, { "errno", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int, offsetof(MonitorQueryParams, error), 0 },
{ "answer", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, PTR_TO_SIZE(&answer), 0 }, { "extendedDNSErrorCode", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int, offsetof(MonitorQueryParams, ede_code), 0 },
{ "collectedQuestions", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, PTR_TO_SIZE(&collected_questions), 0 }, { "extendedDNSErrorMessage", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(MonitorQueryParams, ede_msg), 0 },
{ "state", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, PTR_TO_SIZE(&state), SD_JSON_MANDATORY },
{ "result", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, PTR_TO_SIZE(&result), 0 },
{ "rcode", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int, PTR_TO_SIZE(&rcode), 0 },
{ "errno", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int, PTR_TO_SIZE(&error), 0 },
{ "extendedDNSErrorCode", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int, PTR_TO_SIZE(&ede_code), 0 },
{ "extendedDNSErrorMessage", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, PTR_TO_SIZE(&ede_msg), 0 },
{} {}
}; };
if (sd_json_dispatch(v, dispatch_table, SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS, NULL) < 0) _cleanup_(monitor_query_params_done) MonitorQueryParams p = {
.rcode = -1,
.ede_code = -1,
};
assert(v);
if (sd_json_dispatch(v, dispatch_table, SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS, &p) < 0)
return; return;
/* First show the current question */ /* First show the current question */
print_question('Q', ansi_highlight_cyan(), question); print_question('Q', ansi_highlight_cyan(), p.question);
/* And then show the questions that led to this one in case this was a CNAME chain */ /* And then show the questions that led to this one in case this was a CNAME chain */
print_question('C', ansi_highlight_grey(), collected_questions); print_question('C', ansi_highlight_grey(), p.collected_questions);
printf("%s%s S%s: %s", printf("%s%s S%s: %s",
streq_ptr(state, "success") ? ansi_highlight_green() : ansi_highlight_red(), streq_ptr(p.state, "success") ? ansi_highlight_green() : ansi_highlight_red(),
special_glyph(SPECIAL_GLYPH_ARROW_LEFT), special_glyph(SPECIAL_GLYPH_ARROW_LEFT),
ansi_normal(), ansi_normal(),
strna(streq_ptr(state, "errno") ? errno_to_name(error) : strna(streq_ptr(p.state, "errno") ? errno_to_name(p.error) :
streq_ptr(state, "rcode-failure") ? dns_rcode_to_string(rcode) : streq_ptr(p.state, "rcode-failure") ? dns_rcode_to_string(p.rcode) :
state)); p.state));
if (!isempty(result)) if (!isempty(p.result))
printf(": %s", result); printf(": %s", p.result);
if (ede_code >= 0) if (p.ede_code >= 0)
printf(" (%s%s%s)", printf(" (%s%s%s)",
FORMAT_DNS_EDE_RCODE(ede_code), FORMAT_DNS_EDE_RCODE(p.ede_code),
!isempty(ede_msg) ? ": " : "", !isempty(p.ede_msg) ? ": " : "",
strempty(ede_msg)); strempty(p.ede_msg));
puts(""); puts("");
print_answer(answer); print_answer(p.answer);
} }
static int monitor_reply( static int monitor_reply(

View File

@ -2145,26 +2145,31 @@ int dns_resource_key_to_json(DnsResourceKey *key, sd_json_variant **ret) {
} }
int dns_resource_key_from_json(sd_json_variant *v, DnsResourceKey **ret) { int dns_resource_key_from_json(sd_json_variant *v, DnsResourceKey **ret) {
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL; struct params {
uint16_t type = 0, class = 0; uint16_t type;
const char *name = NULL; uint16_t class;
int r; const char *name;
};
sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "class", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint16, PTR_TO_SIZE(&class), SD_JSON_MANDATORY }, { "class", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint16, offsetof(struct params, class), SD_JSON_MANDATORY },
{ "type", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint16, PTR_TO_SIZE(&type), SD_JSON_MANDATORY }, { "type", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint16, offsetof(struct params, type), SD_JSON_MANDATORY },
{ "name", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, PTR_TO_SIZE(&name), SD_JSON_MANDATORY }, { "name", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(struct params, name), SD_JSON_MANDATORY },
{} {}
}; };
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
struct params p;
int r;
assert(v); assert(v);
assert(ret); assert(ret);
r = sd_json_dispatch(v, dispatch_table, 0, NULL); r = sd_json_dispatch(v, dispatch_table, 0, &p);
if (r < 0) if (r < 0)
return r; return r;
key = dns_resource_key_new(class, type, name); key = dns_resource_key_new(p.class, p.type, p.name);
if (!key) if (!key)
return -ENOMEM; return -ENOMEM;

View File

@ -667,7 +667,7 @@ static int has_tpm2(void) {
* *
* Note that we don't check if we ourselves are built with TPM2 support here! */ * Note that we don't check if we ourselves are built with TPM2 support here! */
return FLAGS_SET(tpm2_support(), TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_FIRMWARE); return FLAGS_SET(tpm2_support_full(TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_FIRMWARE), TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_FIRMWARE);
} }
static int condition_test_security(Condition *c, char **env) { static int condition_test_security(Condition *c, char **env) {

View File

@ -1764,7 +1764,7 @@ int config_parse_hw_addr(
void *data, void *data,
void *userdata) { void *userdata) {
struct hw_addr_data a, *hwaddr = ASSERT_PTR(data); struct hw_addr_data *hwaddr = ASSERT_PTR(data);
int r; int r;
assert(filename); assert(filename);
@ -1776,11 +1776,10 @@ int config_parse_hw_addr(
return 1; return 1;
} }
r = parse_hw_addr_full(rvalue, ltype, &a); r = parse_hw_addr_full(rvalue, ltype, hwaddr);
if (r < 0) if (r < 0)
return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue); return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
*hwaddr = a;
return 1; return 1;
} }
@ -1973,6 +1972,36 @@ int config_parse_in_addr_non_null(
return 1; return 1;
} }
int config_parse_in_addr_data(
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) {
struct in_addr_data *p = ASSERT_PTR(data);
int r;
assert(filename);
assert(lvalue);
if (isempty(rvalue)) {
*p = (struct in_addr_data) {};
return 1;
}
r = in_addr_from_string_auto(rvalue, &p->family, &p->address);
if (r < 0)
return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
return 1;
}
int config_parse_unsigned_bounded( int config_parse_unsigned_bounded(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -304,6 +304,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_hw_addrs);
CONFIG_PARSER_PROTOTYPE(config_parse_ether_addr); CONFIG_PARSER_PROTOTYPE(config_parse_ether_addr);
CONFIG_PARSER_PROTOTYPE(config_parse_ether_addrs); CONFIG_PARSER_PROTOTYPE(config_parse_ether_addrs);
CONFIG_PARSER_PROTOTYPE(config_parse_in_addr_non_null); CONFIG_PARSER_PROTOTYPE(config_parse_in_addr_non_null);
CONFIG_PARSER_PROTOTYPE(config_parse_in_addr_data);
CONFIG_PARSER_PROTOTYPE(config_parse_percent); CONFIG_PARSER_PROTOTYPE(config_parse_percent);
CONFIG_PARSER_PROTOTYPE(config_parse_permyriad); CONFIG_PARSER_PROTOTYPE(config_parse_permyriad);
CONFIG_PARSER_PROTOTYPE(config_parse_pid); CONFIG_PARSER_PROTOTYPE(config_parse_pid);

View File

@ -886,7 +886,7 @@ int encrypt_credential_and_warn(
* container tpm2_support will detect this, and will return a different flag combination of * container tpm2_support will detect this, and will return a different flag combination of
* TPM2_SUPPORT_FULL, effectively skipping the use of TPM2 when inside one. */ * TPM2_SUPPORT_FULL, effectively skipping the use of TPM2 when inside one. */
try_tpm2 = tpm2_support() == TPM2_SUPPORT_FULL; try_tpm2 = tpm2_is_fully_supported();
if (!try_tpm2) if (!try_tpm2)
log_debug("System lacks TPM2 support or running in a container, not attempting to use TPM2."); log_debug("System lacks TPM2 support or running in a container, not attempting to use TPM2.");
} else } else
@ -1582,14 +1582,12 @@ int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after,
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to encrypt: %s", error_id); return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to encrypt: %s", error_id);
} }
r = sd_json_dispatch( static const sd_json_dispatch_field dispatch_table[] = {
reply, { "blob", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, 0, SD_JSON_MANDATORY },
(const sd_json_dispatch_field[]) { {},
{ "blob", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, PTR_TO_SIZE(ret), SD_JSON_MANDATORY }, };
{},
}, r = sd_json_dispatch(reply, dispatch_table, SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS, ret);
SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS,
/* userdata= */ NULL);
if (r < 0) if (r < 0)
return r; return r;
@ -1649,14 +1647,12 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp,
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id); return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id);
} }
r = sd_json_dispatch( static const sd_json_dispatch_field dispatch_table[] = {
reply, { "data", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, 0, SD_JSON_MANDATORY },
(const sd_json_dispatch_field[]) { {},
{ "data", SD_JSON_VARIANT_STRING, json_dispatch_unbase64_iovec, PTR_TO_SIZE(ret), SD_JSON_MANDATORY }, };
{},
}, r = sd_json_dispatch(reply, dispatch_table, SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS, ret);
SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS,
/* userdata= */ NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -250,6 +250,18 @@ int nsresource_add_cgroup(int userns_fd, int cgroup_fd) {
return 1; return 1;
} }
typedef struct InterfaceParams {
char *host_interface_name;
char *namespace_interface_name;
} InterfaceParams;
static void interface_params_done(InterfaceParams *p) {
assert(p);
free(p->host_interface_name);
free(p->namespace_interface_name);
}
int nsresource_add_netif( int nsresource_add_netif(
int userns_fd, int userns_fd,
int netns_fd, int netns_fd,
@ -313,20 +325,20 @@ int nsresource_add_netif(
if (error_id) if (error_id)
return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to add network to user namespace: %s", error_id); return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to add network to user namespace: %s", error_id);
_cleanup_free_ char *host_interface_name = NULL, *namespace_interface_name = NULL; static const sd_json_dispatch_field dispatch_table[] = {
r = sd_json_dispatch( { "hostInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, host_interface_name), 0 },
reply, { "namespaceInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, namespace_interface_name), 0 },
(const sd_json_dispatch_field[]) { };
{ "hostInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, PTR_TO_SIZE(&host_interface_name) },
{ "namespaceInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, PTR_TO_SIZE(&namespace_interface_name) }, _cleanup_(interface_params_done) InterfaceParams p = {};
}, r = sd_json_dispatch(reply, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
SD_JSON_ALLOW_EXTENSIONS, if (r < 0)
/* userdata= */ NULL); return r;
if (ret_host_ifname) if (ret_host_ifname)
*ret_host_ifname = TAKE_PTR(host_interface_name); *ret_host_ifname = TAKE_PTR(p.host_interface_name);
if (ret_namespace_ifname) if (ret_namespace_ifname)
*ret_namespace_ifname = TAKE_PTR(namespace_interface_name); *ret_namespace_ifname = TAKE_PTR(p.namespace_interface_name);
return 1; return 1;
} }

View File

@ -281,6 +281,44 @@ static inline int run_test_table(void) {
} \ } \
}) })
#define ASSERT_OK_ZERO_ERRNO(expr) \
({ \
typeof(expr) _result = (expr); \
if (_result < 0) { \
log_error_errno(errno, "%s:%i: Assertion failed: expected \"%s\" to succeed but got the following error: %m", \
PROJECT_FILE, __LINE__, #expr); \
abort(); \
} \
if (_result != 0) { \
char _sexpr[DECIMAL_STR_MAX(typeof(expr))]; \
xsprintf(_sexpr, DECIMAL_STR_FMT(_result), _result); \
log_error("%s:%i: Assertion failed: expected \"%s\" to be zero, but it is %s.", \
PROJECT_FILE, __LINE__, #expr, _sexpr); \
abort(); \
} \
})
#define ASSERT_OK_EQ_ERRNO(expr1, expr2) \
({ \
typeof(expr1) _expr1 = (expr1); \
typeof(expr2) _expr2 = (expr2); \
if (_expr1 < 0) { \
log_error_errno(errno, "%s:%i: Assertion failed: expected \"%s\" to succeed but got the following error: %m", \
PROJECT_FILE, __LINE__, #expr1); \
abort(); \
} \
if (_expr1 != _expr2) { \
char _sexpr1[DECIMAL_STR_MAX(typeof(expr1))]; \
char _sexpr2[DECIMAL_STR_MAX(typeof(expr2))]; \
xsprintf(_sexpr1, DECIMAL_STR_FMT(_expr1), _expr1); \
xsprintf(_sexpr2, DECIMAL_STR_FMT(_expr2), _expr2); \
log_error("%s:%i: Assertion failed: expected \"%s == %s\", but %s != %s", \
PROJECT_FILE, __LINE__, #expr1, #expr2, _sexpr1, _sexpr2); \
abort(); \
} \
})
#define ASSERT_FAIL(expr) \ #define ASSERT_FAIL(expr) \
({ \ ({ \
typeof(expr) _result = (expr); \ typeof(expr) _result = (expr); \

View File

@ -3,6 +3,7 @@
#include <sys/file.h> #include <sys/file.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "ansi-color.h"
#include "constants.h" #include "constants.h"
#include "creds-util.h" #include "creds-util.h"
#include "cryptsetup-util.h" #include "cryptsetup-util.h"
@ -7872,11 +7873,11 @@ int tpm2_sym_mode_from_string(const char *mode) {
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown symmetric mode name '%s'", mode); return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown symmetric mode name '%s'", mode);
} }
Tpm2Support tpm2_support(void) { Tpm2Support tpm2_support_full(Tpm2Support mask) {
Tpm2Support support = TPM2_SUPPORT_NONE; Tpm2Support support = TPM2_SUPPORT_NONE;
int r; int r;
if (detect_container() <= 0) { if (((mask & (TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_DRIVER)) != 0) && detect_container() <= 0) {
/* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just /* Check if there's a /dev/tpmrm* device via sysfs. If we run in a container we likely just
* got the host sysfs mounted. Since devices are generally not virtualized for containers, * got the host sysfs mounted. Since devices are generally not virtualized for containers,
* let's assume containers never have a TPM, at least for now. */ * let's assume containers never have a TPM, at least for now. */
@ -7893,18 +7894,24 @@ Tpm2Support tpm2_support(void) {
support |= TPM2_SUPPORT_SUBSYSTEM; support |= TPM2_SUPPORT_SUBSYSTEM;
} }
if (efi_has_tpm2()) if (FLAGS_SET(mask, TPM2_SUPPORT_FIRMWARE) && efi_has_tpm2())
support |= TPM2_SUPPORT_FIRMWARE; support |= TPM2_SUPPORT_FIRMWARE;
#if HAVE_TPM2 #if HAVE_TPM2
support |= TPM2_SUPPORT_SYSTEM; support |= TPM2_SUPPORT_SYSTEM;
r = dlopen_tpm2(); if (FLAGS_SET(mask, TPM2_SUPPORT_LIBRARIES)) {
if (r >= 0) r = dlopen_tpm2();
support |= TPM2_SUPPORT_LIBRARIES; if (r >= 0)
support |= TPM2_SUPPORT_LIBRARIES;
}
#endif #endif
return support; return support & mask;
}
static void print_field(const char *s, bool supported) {
printf("%s%s%s%s\n", supported ? ansi_green() : ansi_red(), plus_minus(supported), s, ansi_normal());
} }
int verb_has_tpm2_generic(bool quiet) { int verb_has_tpm2_generic(bool quiet) {
@ -7914,22 +7921,17 @@ int verb_has_tpm2_generic(bool quiet) {
if (!quiet) { if (!quiet) {
if (s == TPM2_SUPPORT_FULL) if (s == TPM2_SUPPORT_FULL)
puts("yes"); printf("%syes%s\n", ansi_green(), ansi_normal());
else if (s == TPM2_SUPPORT_NONE) else if (s == TPM2_SUPPORT_NONE)
puts("no"); printf("%sno%s\n", ansi_red(), ansi_normal());
else else
puts("partial"); printf("%spartial%s\n", ansi_yellow(), ansi_normal());
printf("%sfirmware\n" print_field("firmware", FLAGS_SET(s, TPM2_SUPPORT_FIRMWARE));
"%sdriver\n" print_field("driver", FLAGS_SET(s, TPM2_SUPPORT_DRIVER));
"%ssystem\n" print_field("system", FLAGS_SET(s, TPM2_SUPPORT_SYSTEM));
"%ssubsystem\n" print_field("subsystem", FLAGS_SET(s, TPM2_SUPPORT_SUBSYSTEM));
"%slibraries\n", print_field("libraries", FLAGS_SET(s, TPM2_SUPPORT_LIBRARIES));
plus_minus(s & TPM2_SUPPORT_FIRMWARE),
plus_minus(s & TPM2_SUPPORT_DRIVER),
plus_minus(s & TPM2_SUPPORT_SYSTEM),
plus_minus(s & TPM2_SUPPORT_SUBSYSTEM),
plus_minus(s & TPM2_SUPPORT_LIBRARIES));
} }
/* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values /* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values

View File

@ -450,8 +450,8 @@ typedef struct {
} systemd_tpm2_plugin_params; } systemd_tpm2_plugin_params;
typedef enum Tpm2Support { typedef enum Tpm2Support {
/* NOTE! The systemd-creds tool returns these flags 1:1 as exit status. Hence these flags are pretty /* NOTE! The systemd-analyze has-tpm2 command returns these flags 1:1 as exit status. Hence these
* much ABI! Hence, be extra careful when changing/extending these definitions. */ * flags are pretty much ABI! Hence, be extra careful when changing/extending these definitions. */
TPM2_SUPPORT_NONE = 0, /* no support */ TPM2_SUPPORT_NONE = 0, /* no support */
TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */ TPM2_SUPPORT_FIRMWARE = 1 << 0, /* firmware reports TPM2 was used */
TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */ TPM2_SUPPORT_DRIVER = 1 << 1, /* the kernel has a driver loaded for it */
@ -461,7 +461,13 @@ typedef enum Tpm2Support {
TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM|TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_LIBRARIES, TPM2_SUPPORT_FULL = TPM2_SUPPORT_FIRMWARE|TPM2_SUPPORT_DRIVER|TPM2_SUPPORT_SYSTEM|TPM2_SUPPORT_SUBSYSTEM|TPM2_SUPPORT_LIBRARIES,
} Tpm2Support; } Tpm2Support;
Tpm2Support tpm2_support(void); Tpm2Support tpm2_support_full(Tpm2Support mask);
static inline Tpm2Support tpm2_support(void) {
return tpm2_support_full(TPM2_SUPPORT_FULL);
}
static inline bool tpm2_is_fully_supported(void) {
return tpm2_support() == TPM2_SUPPORT_FULL;
}
int verb_has_tpm2_generic(bool quiet); int verb_has_tpm2_generic(bool quiet);

View File

@ -161,12 +161,12 @@ static int process_machine(const char *machine, const char *port) {
uint32_t cid = VMADDR_CID_ANY; uint32_t cid = VMADDR_CID_ANY;
const sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "vSockCid", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint32, PTR_TO_SIZE(&cid), 0 }, { "vSockCid", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint32, 0, 0 },
{} {}
}; };
r = sd_json_dispatch(result, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, NULL); r = sd_json_dispatch(result, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &cid);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse Varlink reply: %m"); return log_error_errno(r, "Failed to parse Varlink reply: %m");

View File

@ -321,12 +321,27 @@ static int list_targets(sd_bus *bus) {
return table_print_with_pager(table, SD_JSON_FORMAT_OFF, arg_pager_flags, arg_legend); return table_print_with_pager(table, SD_JSON_FORMAT_OFF, arg_pager_flags, arg_legend);
} }
typedef struct DescribeParams {
Version v;
sd_json_variant *contents_json;
bool newest;
bool available;
bool installed;
bool obsolete;
bool protected;
bool incomplete;
} DescribeParams;
static void describe_params_done(DescribeParams *p) {
assert(p);
version_done(&p->v);
sd_json_variant_unref(p->contents_json);
}
static int parse_describe(sd_bus_message *reply, Version *ret) { static int parse_describe(sd_bus_message *reply, Version *ret) {
Version v = {};
char *version_json = NULL; char *version_json = NULL;
_cleanup_(sd_json_variant_unrefp) sd_json_variant *json = NULL, *contents_json = NULL; _cleanup_(sd_json_variant_unrefp) sd_json_variant *json = NULL;
bool newest = false, available = false, installed = false, obsolete = false, protected = false,
incomplete = false;
int r; int r;
assert(reply); assert(reply);
@ -342,36 +357,37 @@ static int parse_describe(sd_bus_message *reply, Version *ret) {
assert(sd_json_variant_is_object(json)); assert(sd_json_variant_is_object(json));
r = sd_json_dispatch(json, static const sd_json_dispatch_field dispatch_table[] = {
(const sd_json_dispatch_field[]) { { "version", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(DescribeParams, v.version), 0 },
{ "version", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, PTR_TO_SIZE(&v.version), 0 }, { "newest", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DescribeParams, newest), 0 },
{ "newest", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, PTR_TO_SIZE(&newest), 0 }, { "available", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DescribeParams, available), 0 },
{ "available", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, PTR_TO_SIZE(&available), 0 }, { "installed", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DescribeParams, installed), 0 },
{ "installed", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, PTR_TO_SIZE(&installed), 0 }, { "obsolete", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DescribeParams, obsolete), 0 },
{ "obsolete", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, PTR_TO_SIZE(&obsolete), 0 }, { "protected", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DescribeParams, protected), 0 },
{ "protected", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, PTR_TO_SIZE(&protected), 0 }, { "incomplete", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(DescribeParams, incomplete), 0 },
{ "incomplete", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, PTR_TO_SIZE(&incomplete), 0 }, { "changelog_urls", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, offsetof(DescribeParams, v.changelog), 0 },
{ "changelog_urls", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, PTR_TO_SIZE(&v.changelog), 0 }, { "contents", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, offsetof(DescribeParams, contents_json), 0 },
{ "contents", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_variant, PTR_TO_SIZE(&contents_json), 0 }, {},
{}, };
},
SD_JSON_ALLOW_EXTENSIONS, _cleanup_(describe_params_done) DescribeParams p = {};
/* userdata= */ NULL);
r = sd_json_dispatch(json, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse JSON: %m"); return log_error_errno(r, "Failed to parse JSON: %m");
SET_FLAG(v.flags, UPDATE_NEWEST, newest); SET_FLAG(p.v.flags, UPDATE_NEWEST, p.newest);
SET_FLAG(v.flags, UPDATE_AVAILABLE, available); SET_FLAG(p.v.flags, UPDATE_AVAILABLE, p.available);
SET_FLAG(v.flags, UPDATE_INSTALLED, installed); SET_FLAG(p.v.flags, UPDATE_INSTALLED, p.installed);
SET_FLAG(v.flags, UPDATE_OBSOLETE, obsolete); SET_FLAG(p.v.flags, UPDATE_OBSOLETE, p.obsolete);
SET_FLAG(v.flags, UPDATE_PROTECTED, protected); SET_FLAG(p.v.flags, UPDATE_PROTECTED, p.protected);
SET_FLAG(v.flags, UPDATE_INCOMPLETE, incomplete); SET_FLAG(p.v.flags, UPDATE_INCOMPLETE, p.incomplete);
r = sd_json_variant_format(contents_json, 0, &v.contents_json); r = sd_json_variant_format(p.contents_json, 0, &p.v.contents_json);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to format JSON for contents: %m"); return log_error_errno(r, "Failed to format JSON for contents: %m");
*ret = TAKE_STRUCT(v); *ret = TAKE_STRUCT(p.v);
return 0; return 0;
} }

View File

@ -1141,6 +1141,18 @@ TEST(ASSERT) {
ASSERT_SIGNAL(ASSERT_OK_ERRNO(-1), SIGABRT); ASSERT_SIGNAL(ASSERT_OK_ERRNO(-1), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_ERRNO(-ENOANO), SIGABRT); ASSERT_SIGNAL(ASSERT_OK_ERRNO(-ENOANO), SIGABRT);
ASSERT_OK_ZERO_ERRNO(0);
ASSERT_SIGNAL(ASSERT_OK_ZERO_ERRNO(1), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_ZERO_ERRNO(255), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_ZERO_ERRNO(-1), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_ZERO_ERRNO(-ENOANO), SIGABRT);
ASSERT_OK_EQ_ERRNO(0, 0);
ASSERT_SIGNAL(ASSERT_OK_EQ_ERRNO(1, 0), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_EQ_ERRNO(255, 5), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_EQ_ERRNO(-1, 0), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_EQ_ERRNO(-ENOANO, 0), SIGABRT);
ASSERT_FAIL(-ENOENT); ASSERT_FAIL(-ENOENT);
ASSERT_FAIL(-EPERM); ASSERT_FAIL(-EPERM);
ASSERT_SIGNAL(ASSERT_FAIL(0), SIGABRT); ASSERT_SIGNAL(ASSERT_FAIL(0), SIGABRT);

View File

@ -54,46 +54,51 @@ static void test_pid_get_comm_one(pid_t pid) {
xsprintf(path, "/proc/"PID_FMT"/comm", pid); xsprintf(path, "/proc/"PID_FMT"/comm", pid);
if (stat(path, &st) == 0) { if (stat(path, &st) == 0) {
assert_se(pid_get_comm(pid, &a) >= 0); ASSERT_OK(pid_get_comm(pid, &a));
log_info("PID"PID_FMT" comm: '%s'", pid, a); log_info("PID"PID_FMT" comm: '%s'", pid, a);
} else } else
log_warning("%s not exist.", path); log_warning("%s not exist.", path);
assert_se(pid_get_cmdline(pid, 0, PROCESS_CMDLINE_COMM_FALLBACK, &c) >= 0); ASSERT_OK(pid_get_cmdline(pid, 0, PROCESS_CMDLINE_COMM_FALLBACK, &c));
log_info("PID"PID_FMT" cmdline: '%s'", pid, c); log_info("PID"PID_FMT" cmdline: '%s'", pid, c);
assert_se(pid_get_cmdline(pid, 8, 0, &d) >= 0); ASSERT_OK(pid_get_cmdline(pid, 8, 0, &d));
log_info("PID"PID_FMT" cmdline truncated to 8: '%s'", pid, d); log_info("PID"PID_FMT" cmdline truncated to 8: '%s'", pid, d);
free(d); free(d);
assert_se(pid_get_cmdline(pid, 1, 0, &d) >= 0); ASSERT_OK(pid_get_cmdline(pid, 1, 0, &d));
log_info("PID"PID_FMT" cmdline truncated to 1: '%s'", pid, d); log_info("PID"PID_FMT" cmdline truncated to 1: '%s'", pid, d);
r = get_process_ppid(pid, &e); r = get_process_ppid(pid, &e);
assert_se(pid == 1 ? r == -EADDRNOTAVAIL : r >= 0); if (pid == 1)
ASSERT_ERROR(r, EADDRNOTAVAIL);
else
ASSERT_OK(r);
if (r >= 0) { if (r >= 0) {
log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e); log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e);
assert_se(e > 0); ASSERT_GT(e, 0);
} }
assert_se(pid_is_kernel_thread(pid) == 0 || pid != 1); ASSERT_TRUE(pid_is_kernel_thread(pid) == 0 || pid != 1);
r = get_process_exe(pid, &f); r = get_process_exe(pid, &f);
assert_se(r >= 0 || r == -EACCES); if (r != -EACCES)
ASSERT_OK(r);
log_info("PID"PID_FMT" exe: '%s'", pid, strna(f)); log_info("PID"PID_FMT" exe: '%s'", pid, strna(f));
assert_se(pid_get_uid(pid, &u) == 0); ASSERT_OK_ZERO(pid_get_uid(pid, &u));
log_info("PID"PID_FMT" UID: "UID_FMT, pid, u); log_info("PID"PID_FMT" UID: "UID_FMT, pid, u);
assert_se(get_process_gid(pid, &g) == 0); ASSERT_OK_ZERO(get_process_gid(pid, &g));
log_info("PID"PID_FMT" GID: "GID_FMT, pid, g); log_info("PID"PID_FMT" GID: "GID_FMT, pid, g);
r = get_process_environ(pid, &env); r = get_process_environ(pid, &env);
assert_se(r >= 0 || r == -EACCES); if (r != -EACCES)
ASSERT_OK(r);
log_info("PID"PID_FMT" strlen(environ): %zi", pid, env ? (ssize_t)strlen(env) : (ssize_t)-errno); log_info("PID"PID_FMT" strlen(environ): %zi", pid, env ? (ssize_t)strlen(env) : (ssize_t)-errno);
if (!detect_container()) if (!detect_container() && pid == 1)
assert_se(get_ctty_devnr(pid, &h) == -ENXIO || pid != 1); ASSERT_ERROR(get_ctty_devnr(pid, &h), ENXIO);
(void) getenv_for_pid(pid, "PATH", &i); (void) getenv_for_pid(pid, "PATH", &i);
log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i)); log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
@ -136,14 +141,14 @@ static void test_pid_get_cmdline_one(pid_t pid) {
r = pid_get_cmdline_strv(pid, 0, &strv_a); r = pid_get_cmdline_strv(pid, 0, &strv_a);
if (r >= 0) if (r >= 0)
assert_se(joined = strv_join(strv_a, "\", \"")); ASSERT_NOT_NULL(joined = strv_join(strv_a, "\", \""));
log_info(" \"%s\"", r >= 0 ? joined : errno_to_name(r)); log_info(" \"%s\"", r >= 0 ? joined : errno_to_name(r));
joined = mfree(joined); joined = mfree(joined);
r = pid_get_cmdline_strv(pid, PROCESS_CMDLINE_COMM_FALLBACK, &strv_b); r = pid_get_cmdline_strv(pid, PROCESS_CMDLINE_COMM_FALLBACK, &strv_b);
if (r >= 0) if (r >= 0)
assert_se(joined = strv_join(strv_b, "\", \"")); ASSERT_NOT_NULL(joined = strv_join(strv_b, "\", \""));
log_info(" \"%s\"", r >= 0 ? joined : errno_to_name(r)); log_info(" \"%s\"", r >= 0 ? joined : errno_to_name(r));
} }
@ -151,13 +156,13 @@ TEST(pid_get_cmdline) {
_cleanup_closedir_ DIR *d = NULL; _cleanup_closedir_ DIR *d = NULL;
int r; int r;
assert_se(proc_dir_open(&d) >= 0); ASSERT_OK(proc_dir_open(&d));
for (;;) { for (;;) {
pid_t pid; pid_t pid;
r = proc_dir_read(d, &pid); r = proc_dir_read(d, &pid);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) /* EOF */ if (r == 0) /* EOF */
break; break;
@ -171,8 +176,8 @@ static void test_pid_get_comm_escape_one(const char *input, const char *output)
log_debug("input: <%s> — output: <%s>", input, output); log_debug("input: <%s> — output: <%s>", input, output);
assert_se(prctl(PR_SET_NAME, input) >= 0); ASSERT_OK_ERRNO(prctl(PR_SET_NAME, input));
assert_se(pid_get_comm(0, &n) >= 0); ASSERT_OK(pid_get_comm(0, &n));
log_debug("got: <%s>", n); log_debug("got: <%s>", n);
@ -182,7 +187,7 @@ static void test_pid_get_comm_escape_one(const char *input, const char *output)
TEST(pid_get_comm_escape) { TEST(pid_get_comm_escape) {
_cleanup_free_ char *saved = NULL; _cleanup_free_ char *saved = NULL;
assert_se(pid_get_comm(0, &saved) >= 0); ASSERT_OK(pid_get_comm(0, &saved));
test_pid_get_comm_escape_one("", ""); test_pid_get_comm_escape_one("", "");
test_pid_get_comm_escape_one("foo", "foo"); test_pid_get_comm_escape_one("foo", "foo");
@ -195,62 +200,62 @@ TEST(pid_get_comm_escape) {
test_pid_get_comm_escape_one("xxxxäöüß", "xxxx\\303\\244\\303\\266\\303\\274\\303\\237"); test_pid_get_comm_escape_one("xxxxäöüß", "xxxx\\303\\244\\303\\266\\303\\274\\303\\237");
test_pid_get_comm_escape_one("xxxxxäöüß", "xxxxx\\303\\244\\303\\266\\303\\274\\303\\237"); test_pid_get_comm_escape_one("xxxxxäöüß", "xxxxx\\303\\244\\303\\266\\303\\274\\303\\237");
assert_se(prctl(PR_SET_NAME, saved) >= 0); ASSERT_OK_ERRNO(prctl(PR_SET_NAME, saved));
} }
TEST(pid_is_unwaited) { TEST(pid_is_unwaited) {
pid_t pid; pid_t pid;
pid = fork(); pid = fork();
assert_se(pid >= 0); ASSERT_OK_ERRNO(pid);
if (pid == 0) { if (pid == 0) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} else { } else {
int status; int status;
assert_se(waitpid(pid, &status, 0) == pid); ASSERT_OK_EQ_ERRNO(waitpid(pid, &status, 0), pid);
assert_se(pid_is_unwaited(pid) == 0); ASSERT_OK_ZERO(pid_is_unwaited(pid));
} }
assert_se(pid_is_unwaited(getpid_cached()) > 0); ASSERT_OK_POSITIVE(pid_is_unwaited(getpid_cached()));
assert_se(pid_is_unwaited(-1) < 0); ASSERT_FAIL(pid_is_unwaited(-1));
} }
TEST(pid_is_alive) { TEST(pid_is_alive) {
pid_t pid; pid_t pid;
pid = fork(); pid = fork();
assert_se(pid >= 0); ASSERT_OK_ERRNO(pid);
if (pid == 0) { if (pid == 0) {
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} else { } else {
int status; int status;
assert_se(waitpid(pid, &status, 0) == pid); ASSERT_OK_EQ_ERRNO(waitpid(pid, &status, 0), pid);
assert_se(pid_is_alive(pid) == 0); ASSERT_OK_ZERO(pid_is_alive(pid));
} }
assert_se(pid_is_alive(getpid_cached()) > 0); ASSERT_OK_POSITIVE(pid_is_alive(getpid_cached()));
assert_se(pid_is_alive(-1) < 0); ASSERT_FAIL(pid_is_alive(-1));
} }
TEST(personality) { TEST(personality) {
assert_se(personality_to_string(PER_LINUX)); ASSERT_NOT_NULL(personality_to_string(PER_LINUX));
assert_se(!personality_to_string(PERSONALITY_INVALID)); ASSERT_NULL(personality_to_string(PERSONALITY_INVALID));
ASSERT_STREQ(personality_to_string(PER_LINUX), architecture_to_string(native_architecture())); ASSERT_STREQ(personality_to_string(PER_LINUX), architecture_to_string(native_architecture()));
assert_se(personality_from_string(personality_to_string(PER_LINUX)) == PER_LINUX); ASSERT_EQ(personality_from_string(personality_to_string(PER_LINUX)), (unsigned long) PER_LINUX);
assert_se(personality_from_string(architecture_to_string(native_architecture())) == PER_LINUX); ASSERT_EQ(personality_from_string(architecture_to_string(native_architecture())), (unsigned long) PER_LINUX);
#ifdef __x86_64__ #ifdef __x86_64__
ASSERT_STREQ(personality_to_string(PER_LINUX), "x86-64"); ASSERT_STREQ(personality_to_string(PER_LINUX), "x86-64");
ASSERT_STREQ(personality_to_string(PER_LINUX32), "x86"); ASSERT_STREQ(personality_to_string(PER_LINUX32), "x86");
assert_se(personality_from_string("x86-64") == PER_LINUX); ASSERT_EQ(personality_from_string("x86-64"), (unsigned long) PER_LINUX);
assert_se(personality_from_string("x86") == PER_LINUX32); ASSERT_EQ(personality_from_string("x86"), (unsigned long) PER_LINUX32);
assert_se(personality_from_string("ia64") == PERSONALITY_INVALID); ASSERT_EQ(personality_from_string("ia64"), PERSONALITY_INVALID);
assert_se(personality_from_string(NULL) == PERSONALITY_INVALID); ASSERT_EQ(personality_from_string(NULL), PERSONALITY_INVALID);
assert_se(personality_from_string(personality_to_string(PER_LINUX32)) == PER_LINUX32); ASSERT_EQ(personality_from_string(personality_to_string(PER_LINUX32)), (unsigned long) PER_LINUX32);
#endif #endif
} }
@ -288,30 +293,31 @@ TEST(pid_get_cmdline_harder) {
(void) wait_for_terminate(pid, &si); (void) wait_for_terminate(pid, &si);
assert_se(si.si_code == CLD_EXITED); ASSERT_EQ(si.si_code, CLD_EXITED);
assert_se(si.si_status == 0); ASSERT_OK_ZERO(si.si_status);
return; return;
} }
assert_se(pid == 0); ASSERT_OK_ZERO(pid);
r = detach_mount_namespace(); r = detach_mount_namespace();
if (r < 0) { if (r < 0) {
log_warning_errno(r, "detach mount namespace failed: %m"); log_warning_errno(r, "detach mount namespace failed: %m");
assert_se(ERRNO_IS_PRIVILEGE(r)); if (!ERRNO_IS_PRIVILEGE(r))
ASSERT_OK(r);
return; return;
} }
fd = mkostemp(path, O_CLOEXEC); fd = mkostemp(path, O_CLOEXEC);
assert_se(fd >= 0); ASSERT_OK_ERRNO(fd);
/* Note that we don't unmount the following bind-mount at the end of the test because the kernel /* Note that we don't unmount the following bind-mount at the end of the test because the kernel
* will clear up its /proc/PID/ hierarchy automatically as soon as the test stops. */ * will clear up its /proc/PID/ hierarchy automatically as soon as the test stops. */
if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) { if (mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) < 0) {
/* This happens under selinux… Abort the test in this case. */ /* This happens under selinux… Abort the test in this case. */
log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m"); log_warning_errno(errno, "mount(..., \"/proc/self/cmdline\", \"bind\", ...) failed: %m");
assert_se(IN_SET(errno, EPERM, EACCES)); ASSERT_TRUE(IN_SET(errno, EPERM, EACCES));
return; return;
} }
@ -320,197 +326,197 @@ TEST(pid_get_cmdline_harder) {
if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0) if (setrlimit(RLIMIT_STACK, &RLIMIT_MAKE_CONST(RLIM_INFINITY)) < 0)
log_warning("Testing without RLIMIT_STACK=infinity"); log_warning("Testing without RLIMIT_STACK=infinity");
assert_se(unlink(path) >= 0); ASSERT_OK_ERRNO(unlink(path));
assert_se(prctl(PR_SET_NAME, "testa") >= 0); ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "testa"));
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) == -ENOENT); ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "[testa]"); ASSERT_STREQ(line, "[testa]");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "\"[testa]\""); /* quoting is enabled here */ ASSERT_STREQ(line, "\"[testa]\""); /* quoting is enabled here */
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 0, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, ""); ASSERT_STREQ(line, "");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, ""); ASSERT_STREQ(line, "");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[…"); ASSERT_STREQ(line, "[…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[t…"); ASSERT_STREQ(line, "[t…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[te…"); ASSERT_STREQ(line, "[te…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[tes…"); ASSERT_STREQ(line, "[tes…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[test…"); ASSERT_STREQ(line, "[test…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[testa]"); ASSERT_STREQ(line, "[testa]");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "[testa]"); ASSERT_STREQ(line, "[testa]");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0); ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
assert_se(strv_equal(args, STRV_MAKE("[testa]"))); ASSERT_TRUE(strv_equal(args, STRV_MAKE("[testa]")));
args = strv_free(args); args = strv_free(args);
/* Test with multiple arguments that don't require quoting */ /* Test with multiple arguments that don't require quoting */
assert_se(write(fd, "foo\0bar", 8) == 8); ASSERT_OK_EQ_ERRNO(write(fd, "foo\0bar", 8), 8);
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar"); ASSERT_STREQ(line, "foo bar");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
ASSERT_STREQ(line, "foo bar"); ASSERT_STREQ(line, "foo bar");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0); ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
assert_se(strv_equal(args, STRV_MAKE("foo", "bar"))); ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar")));
args = strv_free(args); args = strv_free(args);
assert_se(write(fd, "quux", 4) == 4); ASSERT_OK_EQ_ERRNO(write(fd, "quux", 4), 4);
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, 0, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar quux"); ASSERT_STREQ(line, "foo bar quux");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar quux"); ASSERT_STREQ(line, "foo bar quux");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 1, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, ""); ASSERT_STREQ(line, "");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 2, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "f…"); ASSERT_STREQ(line, "f…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 3, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "fo…"); ASSERT_STREQ(line, "fo…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 4, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo…"); ASSERT_STREQ(line, "foo…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 5, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo …"); ASSERT_STREQ(line, "foo …");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 6, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo b…"); ASSERT_STREQ(line, "foo b…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 7, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo ba…"); ASSERT_STREQ(line, "foo ba…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 8, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar…"); ASSERT_STREQ(line, "foo bar…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 9, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar …"); ASSERT_STREQ(line, "foo bar …");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar q…"); ASSERT_STREQ(line, "foo bar q…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar qu…"); ASSERT_STREQ(line, "foo bar qu…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar quux"); ASSERT_STREQ(line, "foo bar quux");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 13, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar quux"); ASSERT_STREQ(line, "foo bar quux");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 14, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar quux"); ASSERT_STREQ(line, "foo bar quux");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 1000, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "foo bar quux"); ASSERT_STREQ(line, "foo bar quux");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0); ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
assert_se(strv_equal(args, STRV_MAKE("foo", "bar", "quux"))); ASSERT_TRUE(strv_equal(args, STRV_MAKE("foo", "bar", "quux")));
args = strv_free(args); args = strv_free(args);
assert_se(ftruncate(fd, 0) >= 0); ASSERT_OK_ERRNO(ftruncate(fd, 0));
assert_se(prctl(PR_SET_NAME, "aaaa bbbb cccc") >= 0); ASSERT_OK_ERRNO(prctl(PR_SET_NAME, "aaaa bbbb cccc"));
assert_se(pid_get_cmdline(0, SIZE_MAX, 0, &line) == -ENOENT); ASSERT_ERROR(pid_get_cmdline(0, SIZE_MAX, 0, &line), ENOENT);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "[aaaa bbbb cccc]"); ASSERT_STREQ(line, "[aaaa bbbb cccc]");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 10, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "[aaaa bbb…"); ASSERT_STREQ(line, "[aaaa bbb…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 11, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "[aaaa bbbb…"); ASSERT_STREQ(line, "[aaaa bbbb…");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, 12, PROCESS_CMDLINE_COMM_FALLBACK, &line));
log_debug("'%s'", line); log_debug("'%s'", line);
ASSERT_STREQ(line, "[aaaa bbbb …"); ASSERT_STREQ(line, "[aaaa bbbb …");
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args) >= 0); ASSERT_OK(pid_get_cmdline_strv(0, PROCESS_CMDLINE_COMM_FALLBACK, &args));
assert_se(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]"))); ASSERT_TRUE(strv_equal(args, STRV_MAKE("[aaaa bbbb cccc]")));
args = strv_free(args); args = strv_free(args);
/* Test with multiple arguments that do require quoting */ /* Test with multiple arguments that do require quoting */
@ -520,24 +526,24 @@ TEST(pid_get_cmdline_harder) {
#define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'" #define EXPECT1p "foo $'\\'bar\\'' $'\"bar$\"' $'x y z' $'!``'"
#define EXPECT1v STRV_MAKE("foo", "'bar'", "\"bar$\"", "x y z", "!``") #define EXPECT1v STRV_MAKE("foo", "'bar'", "\"bar$\"", "x y z", "!``")
assert_se(lseek(fd, SEEK_SET, 0) == 0); ASSERT_OK_ZERO_ERRNO(lseek(fd, SEEK_SET, 0));
assert_se(write(fd, CMDLINE1, sizeof CMDLINE1) == sizeof CMDLINE1); ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE1, sizeof(CMDLINE1)), (ssize_t) sizeof(CMDLINE1));
assert_se(ftruncate(fd, sizeof CMDLINE1) == 0); ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof(CMDLINE1)));
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
log_debug("got: ==%s==", line); log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT1); log_debug("exp: ==%s==", EXPECT1);
ASSERT_STREQ(line, EXPECT1); ASSERT_STREQ(line, EXPECT1);
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
log_debug("got: ==%s==", line); log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT1p); log_debug("exp: ==%s==", EXPECT1p);
ASSERT_STREQ(line, EXPECT1p); ASSERT_STREQ(line, EXPECT1p);
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline_strv(0, 0, &args) >= 0); ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
assert_se(strv_equal(args, EXPECT1v)); ASSERT_TRUE(strv_equal(args, EXPECT1v));
args = strv_free(args); args = strv_free(args);
#define CMDLINE2 "foo\0\1\2\3\0\0" #define CMDLINE2 "foo\0\1\2\3\0\0"
@ -545,24 +551,24 @@ TEST(pid_get_cmdline_harder) {
#define EXPECT2p "foo $'\\001\\002\\003'" #define EXPECT2p "foo $'\\001\\002\\003'"
#define EXPECT2v STRV_MAKE("foo", "\1\2\3") #define EXPECT2v STRV_MAKE("foo", "\1\2\3")
assert_se(lseek(fd, SEEK_SET, 0) == 0); ASSERT_OK_ZERO_ERRNO(lseek(fd, SEEK_SET, 0));
assert_se(write(fd, CMDLINE2, sizeof CMDLINE2) == sizeof CMDLINE2); ASSERT_OK_EQ_ERRNO(write(fd, CMDLINE2, sizeof(CMDLINE2)), (ssize_t) sizeof(CMDLINE2));
assert_se(ftruncate(fd, sizeof CMDLINE2) == 0); ASSERT_OK_ZERO_ERRNO(ftruncate(fd, sizeof CMDLINE2));
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE, &line));
log_debug("got: ==%s==", line); log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT2); log_debug("exp: ==%s==", EXPECT2);
ASSERT_STREQ(line, EXPECT2); ASSERT_STREQ(line, EXPECT2);
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line) >= 0); ASSERT_OK(pid_get_cmdline(0, SIZE_MAX, PROCESS_CMDLINE_QUOTE_POSIX, &line));
log_debug("got: ==%s==", line); log_debug("got: ==%s==", line);
log_debug("exp: ==%s==", EXPECT2p); log_debug("exp: ==%s==", EXPECT2p);
ASSERT_STREQ(line, EXPECT2p); ASSERT_STREQ(line, EXPECT2p);
line = mfree(line); line = mfree(line);
assert_se(pid_get_cmdline_strv(0, 0, &args) >= 0); ASSERT_OK(pid_get_cmdline_strv(0, 0, &args));
assert_se(strv_equal(args, EXPECT2v)); ASSERT_TRUE(strv_equal(args, EXPECT2v));
args = strv_free(args); args = strv_free(args);
safe_close(fd); safe_close(fd);
@ -577,10 +583,11 @@ TEST(getpid_cached) {
b = getpid_cached(); b = getpid_cached();
c = getpid(); c = getpid();
assert_se(a == b && a == c); ASSERT_EQ(a, b);
ASSERT_EQ(a, c);
child = fork(); child = fork();
assert_se(child >= 0); ASSERT_OK_ERRNO(child);
if (child == 0) { if (child == 0) {
/* In child */ /* In child */
@ -588,7 +595,8 @@ TEST(getpid_cached) {
b = getpid_cached(); b = getpid_cached();
c = getpid(); c = getpid();
assert_se(a == b && a == c); ASSERT_EQ(a, b);
ASSERT_EQ(a, c);
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
@ -596,11 +604,13 @@ TEST(getpid_cached) {
e = getpid_cached(); e = getpid_cached();
f = getpid(); f = getpid();
assert_se(a == d && a == e && a == f); ASSERT_EQ(a, d);
ASSERT_EQ(a, e);
ASSERT_EQ(a, f);
assert_se(wait_for_terminate(child, &si) >= 0); ASSERT_OK(wait_for_terminate(child, &si));
assert_se(si.si_status == 0); ASSERT_EQ(si.si_status, 0);
assert_se(si.si_code == CLD_EXITED); ASSERT_EQ(si.si_code, CLD_EXITED);
} }
TEST(getpid_measure) { TEST(getpid_measure) {
@ -635,7 +645,7 @@ TEST(safe_fork) {
BLOCK_SIGNALS(SIGCHLD); BLOCK_SIGNALS(SIGCHLD);
r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid); r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
/* child */ /* child */
@ -644,43 +654,42 @@ TEST(safe_fork) {
_exit(88); _exit(88);
} }
assert_se(wait_for_terminate(pid, &status) >= 0); ASSERT_OK(wait_for_terminate(pid, &status));
assert_se(status.si_code == CLD_EXITED); ASSERT_EQ(status.si_code, CLD_EXITED);
assert_se(status.si_status == 88); ASSERT_EQ(status.si_status, 88);
} }
TEST(pid_to_ptr) { TEST(pid_to_ptr) {
assert_se(PTR_TO_PID(NULL) == 0); ASSERT_EQ(PTR_TO_PID(NULL), 0);
ASSERT_NULL(PID_TO_PTR(0)); ASSERT_NULL(PID_TO_PTR(0));
assert_se(PTR_TO_PID(PID_TO_PTR(1)) == 1); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(1)), 1);
assert_se(PTR_TO_PID(PID_TO_PTR(2)) == 2); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(2)), 2);
assert_se(PTR_TO_PID(PID_TO_PTR(-1)) == -1); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(-1)), -1);
assert_se(PTR_TO_PID(PID_TO_PTR(-2)) == -2); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(-2)), -2);
assert_se(PTR_TO_PID(PID_TO_PTR(INT16_MAX)) == INT16_MAX); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(INT16_MAX)), INT16_MAX);
assert_se(PTR_TO_PID(PID_TO_PTR(INT16_MIN)) == INT16_MIN); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(INT16_MIN)), INT16_MIN);
assert_se(PTR_TO_PID(PID_TO_PTR(INT32_MAX)) == INT32_MAX); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(INT32_MAX)), INT32_MAX);
assert_se(PTR_TO_PID(PID_TO_PTR(INT32_MIN)) == INT32_MIN); ASSERT_EQ(PTR_TO_PID(PID_TO_PTR(INT32_MIN)), INT32_MIN);
} }
static void test_ioprio_class_from_to_string_one(const char *val, int expected, int normalized) { static void test_ioprio_class_from_to_string_one(const char *val, int expected, int normalized) {
assert_se(ioprio_class_from_string(val) == expected); ASSERT_EQ(ioprio_class_from_string(val), expected);
if (expected >= 0) { if (expected >= 0) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
unsigned ret; unsigned ret;
int combined; int combined;
assert_se(ioprio_class_to_string_alloc(expected, &s) == 0); ASSERT_OK_ZERO(ioprio_class_to_string_alloc(expected, &s));
/* We sometimes get a class number and sometimes a name back */ /* We sometimes get a class number and sometimes a name back */
assert_se(streq(s, val) || ASSERT_TRUE(streq(s, val) || safe_atou(val, &ret) == 0);
safe_atou(val, &ret) == 0);
/* Make sure normalization works, i.e. NONE → BE gets normalized */ /* Make sure normalization works, i.e. NONE → BE gets normalized */
combined = ioprio_normalize(ioprio_prio_value(expected, 0)); combined = ioprio_normalize(ioprio_prio_value(expected, 0));
assert_se(ioprio_prio_class(combined) == normalized); ASSERT_EQ(ioprio_prio_class(combined), normalized);
assert_se(expected != IOPRIO_CLASS_NONE || ioprio_prio_data(combined) == 4); ASSERT_TRUE(expected != IOPRIO_CLASS_NONE || ioprio_prio_data(combined) == 4);
} }
} }
@ -701,8 +710,8 @@ TEST(setpriority_closest) {
int r; int r;
r = safe_fork("(test-setprio)", r = safe_fork("(test-setprio)",
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL); FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG, NULL);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
bool full_test; bool full_test;
@ -713,16 +722,21 @@ TEST(setpriority_closest) {
if (setrlimit(RLIMIT_NICE, &RLIMIT_MAKE_CONST(30)) < 0) { if (setrlimit(RLIMIT_NICE, &RLIMIT_MAKE_CONST(30)) < 0) {
/* If this fails we are probably unprivileged or in a userns of some kind, let's skip /* If this fails we are probably unprivileged or in a userns of some kind, let's skip
* the full test */ * the full test */
assert_se(ERRNO_IS_PRIVILEGE(errno)); if (!ERRNO_IS_PRIVILEGE(errno))
ASSERT_OK_ERRNO(-1);
full_test = false; full_test = false;
} else { } else {
/* However, if the hard limit was above 30, setrlimit would succeed unprivileged, so /* However, if the hard limit was above 30, setrlimit would succeed unprivileged, so
* check if the UID/GID can be changed before enabling the full test. */ * check if the UID/GID can be changed before enabling the full test. */
if (setresgid(GID_NOBODY, GID_NOBODY, GID_NOBODY) < 0) { if (setresgid(GID_NOBODY, GID_NOBODY, GID_NOBODY) < 0) {
assert_se(ERRNO_IS_PRIVILEGE(errno)); /* If the nobody user does not exist (user namespace) we get EINVAL. */
if (!ERRNO_IS_PRIVILEGE(errno) && errno != EINVAL)
ASSERT_OK_ERRNO(-1);
full_test = false; full_test = false;
} else if (setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY) < 0) { } else if (setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY) < 0) {
assert_se(ERRNO_IS_PRIVILEGE(errno)); /* If the nobody user does not exist (user namespace) we get EINVAL. */
if (!ERRNO_IS_PRIVILEGE(errno) && errno != EINVAL)
ASSERT_OK_ERRNO(-1);
full_test = false; full_test = false;
} else } else
full_test = true; full_test = true;
@ -730,61 +744,69 @@ TEST(setpriority_closest) {
errno = 0; errno = 0;
p = getpriority(PRIO_PROCESS, 0); p = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0); ASSERT_EQ(errno, 0);
/* It should always be possible to set our nice level to the current one */ /* It should always be possible to set our nice level to the current one */
assert_se(setpriority_closest(p) > 0); ASSERT_OK_POSITIVE(setpriority_closest(p));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && p == q); ASSERT_EQ(errno, 0);
ASSERT_EQ(p, q);
/* It should also be possible to set the nice level to one higher */ /* It should also be possible to set the nice level to one higher */
if (p < PRIO_MAX-1) { if (p < PRIO_MAX-1) {
assert_se(setpriority_closest(++p) > 0); ASSERT_OK_POSITIVE(setpriority_closest(++p));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && p == q); ASSERT_EQ(errno, 0);
ASSERT_EQ(p, q);
} }
/* It should also be possible to set the nice level to two higher */ /* It should also be possible to set the nice level to two higher */
if (p < PRIO_MAX-1) { if (p < PRIO_MAX-1) {
assert_se(setpriority_closest(++p) > 0); ASSERT_OK_POSITIVE(setpriority_closest(++p));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && p == q); ASSERT_EQ(errno, 0);
ASSERT_EQ(p, q);
} }
if (full_test) { if (full_test) {
/* These two should work, given the RLIMIT_NICE we set above */ /* These two should work, given the RLIMIT_NICE we set above */
assert_se(setpriority_closest(-10) > 0); ASSERT_OK_POSITIVE(setpriority_closest(-10));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && q == -10); ASSERT_EQ(errno, 0);
ASSERT_EQ(q, -10);
assert_se(setpriority_closest(-9) > 0); ASSERT_OK_POSITIVE(setpriority_closest(-9));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && q == -9); ASSERT_EQ(errno, 0);
ASSERT_EQ(q, -9);
/* This should succeed but should be clamped to the limit */ /* This should succeed but should be clamped to the limit */
assert_se(setpriority_closest(-11) == 0); ASSERT_OK_ZERO(setpriority_closest(-11));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && q == -10); ASSERT_EQ(errno, 0);
ASSERT_EQ(q, -10);
assert_se(setpriority_closest(-8) > 0); ASSERT_OK_POSITIVE(setpriority_closest(-8));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && q == -8); ASSERT_EQ(errno, 0);
ASSERT_EQ(q, -8);
/* This should succeed but should be clamped to the limit */ /* This should succeed but should be clamped to the limit */
assert_se(setpriority_closest(-12) == 0); ASSERT_OK_ZERO(setpriority_closest(-12));
errno = 0; errno = 0;
q = getpriority(PRIO_PROCESS, 0); q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && q == -10); ASSERT_EQ(errno, 0);
ASSERT_EQ(q, -10);
} }
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
@ -795,10 +817,10 @@ TEST(get_process_ppid) {
uint64_t limit; uint64_t limit;
int r; int r;
assert_se(get_process_ppid(1, NULL) == -EADDRNOTAVAIL); ASSERT_ERROR(get_process_ppid(1, NULL), EADDRNOTAVAIL);
/* the process with the PID above the global limit definitely doesn't exist. Verify that */ /* the process with the PID above the global limit definitely doesn't exist. Verify that */
assert_se(procfs_get_pid_max(&limit) >= 0); ASSERT_OK(procfs_get_pid_max(&limit));
log_debug("kernel.pid_max = %"PRIu64, limit); log_debug("kernel.pid_max = %"PRIu64, limit);
if (limit < INT_MAX) { if (limit < INT_MAX) {
@ -817,10 +839,10 @@ TEST(get_process_ppid) {
break; break;
} }
assert_se(r >= 0); ASSERT_OK(r);
assert_se(pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c1) >= 0); ASSERT_OK(pid_get_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c1));
assert_se(pid_get_cmdline(ppid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c2) >= 0); ASSERT_OK(pid_get_cmdline(ppid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &c2));
log_info("Parent of " PID_FMT " (%s) is " PID_FMT " (%s).", pid, c1, ppid, c2); log_info("Parent of " PID_FMT " (%s) is " PID_FMT " (%s).", pid, c1, ppid, c2);
@ -831,19 +853,20 @@ TEST(get_process_ppid) {
TEST(set_oom_score_adjust) { TEST(set_oom_score_adjust) {
int a, b, r; int a, b, r;
assert_se(get_oom_score_adjust(&a) >= 0); ASSERT_OK(get_oom_score_adjust(&a));
r = set_oom_score_adjust(OOM_SCORE_ADJ_MIN); r = set_oom_score_adjust(OOM_SCORE_ADJ_MIN);
assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r)); if (!ERRNO_IS_PRIVILEGE(r))
ASSERT_OK(r);
if (r >= 0) { if (r >= 0) {
assert_se(get_oom_score_adjust(&b) >= 0); ASSERT_OK(get_oom_score_adjust(&b));
assert_se(b == OOM_SCORE_ADJ_MIN); ASSERT_EQ(b, OOM_SCORE_ADJ_MIN);
} }
assert_se(set_oom_score_adjust(a) >= 0); ASSERT_OK(set_oom_score_adjust(a));
assert_se(get_oom_score_adjust(&b) >= 0); ASSERT_OK(get_oom_score_adjust(&b));
assert_se(b == a); ASSERT_EQ(b, a);
} }
static void* dummy_thread(void *p) { static void* dummy_thread(void *p) {
@ -851,10 +874,10 @@ static void* dummy_thread(void *p) {
char x; char x;
/* let main thread know we are ready */ /* let main thread know we are ready */
assert_se(write(fd, &(const char) { 'x' }, 1) == 1); ASSERT_OK_EQ_ERRNO(write(fd, &(const char) { 'x' }, 1), 1);
/* wait for the main thread to tell us to shut down */ /* wait for the main thread to tell us to shut down */
assert_se(read(fd, &x, 1) == 1); ASSERT_OK_EQ_ERRNO(read(fd, &x, 1), 1);
return NULL; return NULL;
} }
@ -862,38 +885,42 @@ TEST(get_process_threads) {
int r; int r;
/* Run this test in a child, so that we can guarantee there's exactly one thread around in the child */ /* Run this test in a child, so that we can guarantee there's exactly one thread around in the child */
r = safe_fork("(nthreads)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_WAIT|FORK_LOG, NULL); r = safe_fork("(nthreads)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
_cleanup_close_pair_ int pfd[2] = EBADF_PAIR, ppfd[2] = EBADF_PAIR; _cleanup_close_pair_ int pfd[2] = EBADF_PAIR, ppfd[2] = EBADF_PAIR;
pthread_t t, tt; pthread_t t, tt;
char x; char x;
assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, pfd) >= 0); ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, pfd));
assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, ppfd) >= 0); ASSERT_OK_ERRNO(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, ppfd));
assert_se(get_process_threads(0) == 1); ASSERT_OK_EQ(get_process_threads(0), 1);
assert_se(pthread_create(&t, NULL, &dummy_thread, FD_TO_PTR(pfd[0])) == 0); ASSERT_OK_ZERO_ERRNO(pthread_create(&t, NULL, &dummy_thread, FD_TO_PTR(pfd[0])));
assert_se(read(pfd[1], &x, 1) == 1); ASSERT_OK_EQ_ERRNO(read(pfd[1], &x, 1), 1);
assert_se(get_process_threads(0) == 2); ASSERT_OK_EQ(get_process_threads(0), 2);
assert_se(pthread_create(&tt, NULL, &dummy_thread, FD_TO_PTR(ppfd[0])) == 0); ASSERT_OK_ZERO_ERRNO(pthread_create(&tt, NULL, &dummy_thread, FD_TO_PTR(ppfd[0])));
assert_se(read(ppfd[1], &x, 1) == 1); ASSERT_OK_EQ_ERRNO(read(ppfd[1], &x, 1), 1);
assert_se(get_process_threads(0) == 3); ASSERT_OK_EQ(get_process_threads(0), 3);
assert_se(write(pfd[1], &(const char) { 'x' }, 1) == 1); ASSERT_OK_EQ_ERRNO(write(pfd[1], &(const char) { 'x' }, 1), 1);
assert_se(pthread_join(t, NULL) == 0); ASSERT_OK_ZERO_ERRNO(pthread_join(t, NULL));
/* the value reported via /proc/ is decreased asynchronously, and there appears to be no nice /* the value reported via /proc/ is decreased asynchronously, and there appears to be no nice
* way to sync on it. Hence we do the weak >= 2 check, even though == 2 is what we'd actually * way to sync on it. Hence we do the weak >= 2 check, even though == 2 is what we'd actually
* like to check here */ * like to check here */
assert_se(get_process_threads(0) >= 2); r = get_process_threads(0);
ASSERT_OK(r);
ASSERT_GE(r, 2);
assert_se(write(ppfd[1], &(const char) { 'x' }, 1) == 1); ASSERT_OK_EQ_ERRNO(write(ppfd[1], &(const char) { 'x' }, 1), 1);
assert_se(pthread_join(tt, NULL) == 0); ASSERT_OK_ZERO_ERRNO(pthread_join(tt, NULL));
/* similar here */ /* similar here */
assert_se(get_process_threads(0) >= 1); r = get_process_threads(0);
ASSERT_OK(r);
ASSERT_GE(r, 1);
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
@ -902,17 +929,17 @@ TEST(get_process_threads) {
TEST(is_reaper_process) { TEST(is_reaper_process) {
int r; int r;
r = safe_fork("(regular)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL); r = safe_fork("(regular)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
/* child */ /* child */
assert_se(is_reaper_process() == 0); ASSERT_OK_ZERO(is_reaper_process());
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
r = safe_fork("(newpid)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL); r = safe_fork("(newpid)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
/* child */ /* child */
@ -923,25 +950,25 @@ TEST(is_reaper_process) {
} }
} }
r = safe_fork("(newpid1)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL); r = safe_fork("(newpid1)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
/* grandchild, which is PID1 in a pidns */ /* grandchild, which is PID1 in a pidns */
assert_se(getpid_cached() == 1); ASSERT_OK_EQ(getpid_cached(), 1);
assert_se(is_reaper_process() > 0); ASSERT_OK_POSITIVE(is_reaper_process());
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_WAIT, NULL); r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_WAIT, NULL);
assert_se(r >= 0); ASSERT_OK(r);
if (r == 0) { if (r == 0) {
/* child */ /* child */
assert_se(make_reaper_process(true) >= 0); ASSERT_OK(make_reaper_process(true));
assert_se(is_reaper_process() > 0); ASSERT_OK_POSITIVE(is_reaper_process());
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);
} }
} }
@ -949,22 +976,22 @@ TEST(is_reaper_process) {
TEST(pid_get_start_time) { TEST(pid_get_start_time) {
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
assert_se(pidref_set_self(&pidref) >= 0); ASSERT_OK(pidref_set_self(&pidref));
usec_t start_time; usec_t start_time;
assert_se(pidref_get_start_time(&pidref, &start_time) >= 0); ASSERT_OK(pidref_get_start_time(&pidref, &start_time));
log_info("our starttime: " USEC_FMT, start_time); log_info("our starttime: " USEC_FMT, start_time);
_cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL; _cleanup_(pidref_done_sigkill_wait) PidRef child = PIDREF_NULL;
assert_se(pidref_safe_fork("(stub)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS, &child) >= 0); ASSERT_OK(pidref_safe_fork("(stub)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG, &child));
usec_t start_time2; usec_t start_time2;
assert_se(pidref_get_start_time(&child, &start_time2) >= 0); ASSERT_OK(pidref_get_start_time(&child, &start_time2));
log_info("child starttime: " USEC_FMT, start_time2); log_info("child starttime: " USEC_FMT, start_time2);
assert_se(start_time2 >= start_time); ASSERT_GE(start_time2, start_time);
} }
static int intro(void) { static int intro(void) {

View File

@ -259,7 +259,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0) if (r <= 0)
return r; return r;
if (arg_graceful && tpm2_support() != TPM2_SUPPORT_FULL) { if (arg_graceful && !tpm2_is_fully_supported()) {
log_notice("No complete TPM2 support detected, exiting gracefully."); log_notice("No complete TPM2 support detected, exiting gracefully.");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -288,7 +288,7 @@ static int verb_info(int argc, char *argv[], void *userdata) {
pager_open(arg_pager_flags); pager_open(arg_pager_flags);
if (FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) { if (FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF)) {
static const struct sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "vendor", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetInfoData, vendor), SD_JSON_MANDATORY }, { "vendor", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetInfoData, vendor), SD_JSON_MANDATORY },
{ "product", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetInfoData, product), SD_JSON_MANDATORY }, { "product", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetInfoData, product), SD_JSON_MANDATORY },
{ "version", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetInfoData, version), SD_JSON_MANDATORY }, { "version", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(GetInfoData, version), SD_JSON_MANDATORY },
@ -380,12 +380,12 @@ static int verb_introspect(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
const struct sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "interfaces", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, PTR_TO_SIZE(&auto_interfaces), SD_JSON_MANDATORY }, { "interfaces", SD_JSON_VARIANT_ARRAY, sd_json_dispatch_strv, 0, SD_JSON_MANDATORY },
{} {}
}; };
r = sd_json_dispatch(reply, dispatch_table, SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS, NULL); r = sd_json_dispatch(reply, dispatch_table, SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS, &auto_interfaces);
if (r < 0) if (r < 0)
return r; return r;
@ -412,7 +412,7 @@ static int verb_introspect(int argc, char *argv[], void *userdata) {
return r; return r;
if (FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF) || list_methods) { if (FLAGS_SET(arg_json_format_flags, SD_JSON_FORMAT_OFF) || list_methods) {
static const struct sd_json_dispatch_field dispatch_table[] = { static const sd_json_dispatch_field dispatch_table[] = {
{ "description", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY }, { "description", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY },
{} {}
}; };

View File

@ -4,5 +4,6 @@ integration_tests += [
integration_test_template + { integration_test_template + {
'name' : fs.name(meson.current_source_dir()), 'name' : fs.name(meson.current_source_dir()),
'storage': 'persistent', 'storage': 'persistent',
'vm' : true,
}, },
] ]

View File

@ -21,6 +21,9 @@ at_exit() {
trap at_exit EXIT trap at_exit EXIT
systemctl unmask systemd-networkd.service
systemctl start systemd-networkd.service
export NETWORK_NAME="10-networkctl-test-$RANDOM.network" export NETWORK_NAME="10-networkctl-test-$RANDOM.network"
export NETDEV_NAME="10-networkctl-test-$RANDOM.netdev" export NETDEV_NAME="10-networkctl-test-$RANDOM.netdev"
export LINK_NAME="10-networkctl-test-$RANDOM.link" export LINK_NAME="10-networkctl-test-$RANDOM.link"
@ -75,15 +78,6 @@ cmp "+4" "/etc/systemd/network/${NETWORK_NAME}.d/test.conf"
networkctl cat "$NETWORK_NAME" | grep '^# ' | networkctl cat "$NETWORK_NAME" | grep '^# ' |
cmp - <(printf '%s\n' "# /etc/systemd/network/$NETWORK_NAME" "# /etc/systemd/network/${NETWORK_NAME}.d/test.conf") cmp - <(printf '%s\n' "# /etc/systemd/network/$NETWORK_NAME" "# /etc/systemd/network/${NETWORK_NAME}.d/test.conf")
networkctl edit --stdin --runtime "$NETDEV_NAME" <<EOF
[NetDev]
Name=test2
Kind=dummy
EOF
networkctl cat "$NETDEV_NAME" | grep -v '^# ' |
cmp - <(printf '%s\n' "[NetDev]" "Name=test2" "Kind=dummy")
cat >"/usr/lib/systemd/network/$LINK_NAME" <<EOF cat >"/usr/lib/systemd/network/$LINK_NAME" <<EOF
[Match] [Match]
OriginalName=test2 OriginalName=test2
@ -95,13 +89,23 @@ EOF
SYSTEMD_LOG_LEVEL=debug EDITOR='true' script -ec 'networkctl edit "$LINK_NAME"' /dev/null SYSTEMD_LOG_LEVEL=debug EDITOR='true' script -ec 'networkctl edit "$LINK_NAME"' /dev/null
cmp "/usr/lib/systemd/network/$LINK_NAME" "/etc/systemd/network/$LINK_NAME" cmp "/usr/lib/systemd/network/$LINK_NAME" "/etc/systemd/network/$LINK_NAME"
# Test links # The interface test2 does not exist, hence the below do not work.
systemctl unmask systemd-networkd
systemctl stop systemd-networkd
(! networkctl cat @test2) (! networkctl cat @test2)
(! networkctl cat @test2:netdev) (! networkctl cat @test2:netdev)
(! networkctl cat @test2:link)
(! networkctl cat @test2:network)
systemctl start systemd-networkd # create .netdev file at last, otherwise, the .link file will not be applied to the interface.
networkctl edit --stdin --runtime "$NETDEV_NAME" <<EOF
[NetDev]
Name=test2
Kind=dummy
EOF
networkctl cat "$NETDEV_NAME" | grep -v '^# ' |
cmp - <(printf '%s\n' "[NetDev]" "Name=test2" "Kind=dummy")
# wait for the interface being created and configured.
SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/systemd-networkd-wait-online -i test2:carrier --timeout 20 SYSTEMD_LOG_LEVEL=debug /usr/lib/systemd/systemd-networkd-wait-online -i test2:carrier --timeout 20
networkctl cat @test2:network | cmp - <(networkctl cat "$NETWORK_NAME") networkctl cat @test2:network | cmp - <(networkctl cat "$NETWORK_NAME")