(eval . (c-set-offset 'arglist-intro '++))
(eval . (c-set-offset 'arglist-close 0))))
(nxml-mode . ((nxml-child-indent . 2)
- (fill-column . 119))))
+ (fill-column . 119)))
+ (meson-mode . ((meson-indent-basic . 8)))
+ (sh-mode . ((sh-basic-offset . 8)
+ (sh-indentation . 8)))
+ (awk-mode . ((c-basic-offset . 8))))
## Filing Issues
-* We use GitHub Issues **exclusively** for tracking **bugs** and **feature** **requests** of systemd. If you are looking for help, please contact our [mailing list](http://lists.freedesktop.org/mailman/listinfo/systemd-devel) instead.
+* We use GitHub Issues **exclusively** for tracking **bugs** and **feature** **requests** of systemd. If you are looking for help, please contact our [mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) instead.
* We only track bugs in the **two** **most** **recently** **released** **versions** of systemd in the GitHub Issue tracker. If you are using an older version of systemd, please contact your distribution's bug tracker instead.
* When filing an issue, specify the **systemd** **version** you are experiencing the issue with. Also, indicate which **distribution** you are using.
* Please include an explanation how to reproduce the issue you are pointing out.
Following these guidelines makes it easier for us to process your issue, and ensures we won't close your issue right-away for being misfiled.
+### Older downstream versions
+For older versions that are still supported by your distribution please use respective downstream tracker:
+* **Fedora** - [bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=systemd)
+* **RHEL-7/CentOS-7** - [bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Enterprise%20Linux%207&component=systemd) or [systemd-rhel github](https://github.com/lnykryn/systemd-rhel/issues)
+* **Debian** - [bugs.debian.org](https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=systemd)
+
+## Security vulnerability reports
+
+If you discover a security vulnerability, we'd appreciate a non-public disclosure. The issue tracker and mailing list listed above are fully public. If you need to reach systemd developers in a non-public way, report the issue in one of the "big" distributions using systemd: [Fedora](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=systemd) (be sure to check "Security Sensitive Bug" under "Show Advanced Fields"), [Ubuntu](https://launchpad.net/ubuntu/+source/systemd/+filebug) (be sure to change "This bug contains information that is" from "Public" to "Private Security"), or [Debian](mailto:security@debian.org). Various systemd developers are active distribution maintainers and will propagate the information about the bug to other parties.
+
## Posting Pull Requests
* Make sure to post PRs only relative to a very recent git master.
### Submission type
- - [ ] Bug report
- - [ ] Request for enhancement (RFE)
+<!-- Delete the inappropriate option below: -->
-*NOTE: Do not submit anything other than bug reports or RFEs via the issue tracker!*
+ - Bug report
+ - Request for enhancement (RFE)
+
+<!-- **NOTE:** Do not submit anything other than bug reports or RFEs via the issue tracker! -->
### systemd version the issue has been seen with
> …
-*NOTE: Do not submit bug reports about anything but the two most recently released systemd versions upstream!*
+<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released systemd versions upstream! -->
+<!-- For older version please use distribution trackers (see https://github.com/systemd/systemd/blob/master/.github/CONTRIBUTING.md#filing-issues). -->
### Used distribution
/TAGS
/ata_id
/bootctl
-/build-aux
+/build*
/busctl
/cdrom_id
/collect
/test-bus-server
/test-bus-signature
/test-bus-track
+/test-bus-vtable
+/test-bus-vtable-cc
/test-bus-zero-copy
/test-calendarspec
/test-cap-list
/test-process-util
/test-pty
/test-qcow2
+/test-random-util
/test-ratelimit
/test-replace-var
/test-resolve
/test-resolve-tables
+/test-resolved-packet
/test-ring
/test-rlimit-util
/test-sched-prio
+/test-sd-dhcp-lease
/test-seccomp
/test-selinux
/test-set
/test-tables
/test-terminal-util
/test-time
+/test-timesync
/test-tmpfiles
/test-udev
/test-uid-range
Karl Kraus <karl.kraus@tum.de> <laqueray@gmail.com>
Tibor Nagy <xnagytibor@gmail.com>
Stuart McLaren <stuart.mclaren@hp.com>
+John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> <glaubitz@suse.com>
+Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+Neil Brown <neil@brown.name>
+Michal Suchanek <msuchanek@suse.de> <hramrach@gmail.com>
+Michal Suchanek <msuchanek@suse.de>
+Bastien Nocera <hadess@hadess.net> <hadess@users.noreply.github.com>
+Umut Tezduyar Lindskog <umut@tezduyar.com>
+Alexander Kurtz <alexander@kurtz.be>
+Piotr Szydełko <wiertel@users.sourceforge.net>
+Łukasz Stelmach <l.stelmach@samsung.com> <stlman@poczta.fm>
+Krzysztof Jackiewicz <k.jackiewicz@samsung.com> <kjackiewicz@users.noreply.github.com>
+Marcus Cooper <marcusc@axis.com> <codekipper@gmail.com>
+Insun Pyo <insun.pyo@samsung.com> <iplayinsun@gmail.com>
+Ted Wood <ted.l.wood@gmail.com>
+Ted Wood <ted@mailchimp.com>
+Anthony Parsons <flussence@users.noreply.github.com>
+Federico Di Pierro <nierro92@gmail.com>
+Josef Andersson <josef.andersson@fripost.org>
+Josef Andersson <l10nl18nsweja@gmail.com>
+Hendrik Westerberg <hendrik@gestorf.com>
Cache=/var/cache/pacman/pkg/
BuildPackages=
acl
- autoconf
- automake
bzip2
cryptsetup
curl
kmod
libcap
libgcrypt
- libidn
+ libidn2
libmicrohttpd
libseccomp
libtool
libxkbcommon
libxslt
lz4
- make
+ meson
pam
pkgconfig
python
python-lxml
qrencode
xz
+
+Packages=
+ libidn2
[Packages]
BuildPackages=
acl
- autoconf
- automake
- diffutils
docbook-xml
docbook-xsl
gcc
libfdisk-dev
libgcrypt20-dev
libgnutls28-dev
- libidn11-dev
+ libidn2-0-dev
libkmod-dev
liblzma-dev
liblz4-dev
libsmartcols-dev
libtool
libxkbcommon-dev
- make
+ meson
pkg-config
python3
python3-lxml
Packages=
libqrencode3
locales
+ libidn2-0
[Distribution]
Distribution=fedora
-Release=25
+Release=26
[Output]
Format=raw_btrfs
[Packages]
BuildPackages=
audit-libs-devel
- autoconf
- automake
bzip2-devel
cryptsetup-devel
dbus-devel
libcap-devel
libcurl-devel
libgcrypt-devel
- libidn-devel
+ libidn2-devel
libmicrohttpd-devel
libmount-devel
libseccomp-devel
libtool
libxkbcommon-devel
libxslt
+ lz4
lz4-devel
- make
+ meson
pam-devel
pkgconfig
python3-devel
qrencode-devel
tree
xz-devel
+
+Packages=
+ libidn2
or:
- # qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -hda image.raw
+ # qemu-system-x86_64 -enable-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -hda image.raw
Every time you rerun the "mkosi" command a fresh image is built, incorporating
all current changes you made to the project tree.
man/bootup.7 \
man/busctl.1 \
man/daemon.7 \
- man/environment.d.5 \
man/file-hierarchy.7 \
man/halt.8 \
man/hostname.5 \
man/localtime.5 \
man/machine-id.5 \
man/machine-info.5 \
- man/nss-systemd.8 \
man/os-release.5 \
man/sd-bus-errors.3 \
man/sd-bus.3 \
man/systemd-debug-generator.8 \
man/systemd-delta.1 \
man/systemd-detect-virt.1 \
- man/systemd-environment-d-generator.8 \
man/systemd-escape.1 \
man/systemd-fsck@.service.8 \
man/systemd-fstab-generator.8 \
man/systemd-getty-generator.8 \
man/systemd-gpt-auto-generator.8 \
man/systemd-halt.service.8 \
- man/systemd-hibernate-resume-generator.8 \
- man/systemd-hibernate-resume@.service.8 \
man/systemd-inhibit.1 \
man/systemd-initctl.service.8 \
man/systemd-journald.service.8 \
man/systemd-nspawn.1 \
man/systemd-path.1 \
man/systemd-remount-fs.service.8 \
- man/systemd-resolve.1 \
man/systemd-run.1 \
man/systemd-sleep.conf.5 \
man/systemd-socket-activate.1 \
man/systemd.1 \
man/systemd.automount.5 \
man/systemd.device.5 \
- man/systemd.environment-generator.7 \
man/systemd.exec.5 \
man/systemd.generator.7 \
man/systemd.journal-fields.7 \
man/udev_new.3 \
man/udevadm.8
MANPAGES_ALIAS += \
- man/30-systemd-environment-d-generator.8 \
man/SD_ALERT.3 \
man/SD_BUS_ERROR_ACCESS_DENIED.3 \
man/SD_BUS_ERROR_ADDRESS_IN_USE.3 \
man/SD_WARNING.3 \
man/init.1 \
man/journald.conf.d.5 \
- man/libnss_systemd.so.2.8 \
man/poweroff.8 \
man/reboot.8 \
man/sd_bus_creds_get_audit_login_uid.3 \
man/sd_bus_message_append_array_space.3 \
man/sd_bus_message_append_string_iovec.3 \
man/sd_bus_message_append_string_space.3 \
+ man/sd_bus_message_appendv.3 \
man/sd_bus_message_get_realtime_usec.3 \
man/sd_bus_message_get_reply_cookie.3 \
man/sd_bus_message_get_seqnum.3 \
man/systemd-ask-password-wall.service.8 \
man/systemd-fsck-root.service.8 \
man/systemd-fsck.8 \
- man/systemd-hibernate-resume.8 \
man/systemd-hibernate.service.8 \
man/systemd-hybrid-sleep.service.8 \
man/systemd-initctl.8 \
man/udev_ref.3 \
man/udev_unref.3 \
man/user.conf.d.5
-man/30-systemd-environment-d-generator.8: man/systemd-environment-d-generator.8
man/SD_ALERT.3: man/sd-daemon.3
man/SD_BUS_ERROR_ACCESS_DENIED.3: man/sd-bus-errors.3
man/SD_BUS_ERROR_ADDRESS_IN_USE.3: man/sd-bus-errors.3
man/SD_WARNING.3: man/sd-daemon.3
man/init.1: man/systemd.1
man/journald.conf.d.5: man/journald.conf.5
-man/libnss_systemd.so.2.8: man/nss-systemd.8
man/poweroff.8: man/halt.8
man/reboot.8: man/halt.8
man/sd_bus_creds_get_audit_login_uid.3: man/sd_bus_creds_get_pid.3
man/sd_bus_message_append_array_space.3: man/sd_bus_message_append_array.3
man/sd_bus_message_append_string_iovec.3: man/sd_bus_message_append_string_memfd.3
man/sd_bus_message_append_string_space.3: man/sd_bus_message_append_string_memfd.3
+man/sd_bus_message_appendv.3: man/sd_bus_message_append.3
man/sd_bus_message_get_realtime_usec.3: man/sd_bus_message_get_monotonic_usec.3
man/sd_bus_message_get_reply_cookie.3: man/sd_bus_message_get_cookie.3
man/sd_bus_message_get_seqnum.3: man/sd_bus_message_get_monotonic_usec.3
man/systemd-ask-password-wall.service.8: man/systemd-ask-password-console.service.8
man/systemd-fsck-root.service.8: man/systemd-fsck@.service.8
man/systemd-fsck.8: man/systemd-fsck@.service.8
-man/systemd-hibernate-resume.8: man/systemd-hibernate-resume@.service.8
man/systemd-hibernate.service.8: man/systemd-suspend.service.8
man/systemd-hybrid-sleep.service.8: man/systemd-suspend.service.8
man/systemd-initctl.8: man/systemd-initctl.service.8
man/udev_ref.3: man/udev_new.3
man/udev_unref.3: man/udev_new.3
man/user.conf.d.5: man/systemd-system.conf.5
-man/30-systemd-environment-d-generator.html: man/systemd-environment-d-generator.html
- $(html-alias)
-
man/SD_ALERT.html: man/sd-daemon.html
$(html-alias)
man/journald.conf.d.html: man/journald.conf.html
$(html-alias)
-man/libnss_systemd.so.2.html: man/nss-systemd.html
- $(html-alias)
-
man/poweroff.html: man/halt.html
$(html-alias)
man/sd_bus_message_append_string_space.html: man/sd_bus_message_append_string_memfd.html
$(html-alias)
+man/sd_bus_message_appendv.html: man/sd_bus_message_append.html
+ $(html-alias)
+
man/sd_bus_message_get_realtime_usec.html: man/sd_bus_message_get_monotonic_usec.html
$(html-alias)
man/systemd-fsck.html: man/systemd-fsck@.service.html
$(html-alias)
-man/systemd-hibernate-resume.html: man/systemd-hibernate-resume@.service.html
- $(html-alias)
-
man/systemd-hibernate.service.html: man/systemd-suspend.service.html
$(html-alias)
endif
+if ENABLE_ENVIRONMENT_D
+MANPAGES += \
+ man/environment.d.5 \
+ man/systemd-environment-d-generator.8 \
+ man/systemd.environment-generator.7
+MANPAGES_ALIAS += \
+ man/30-systemd-environment-d-generator.8
+man/30-systemd-environment-d-generator.8: man/systemd-environment-d-generator.8
+man/30-systemd-environment-d-generator.html: man/systemd-environment-d-generator.html
+ $(html-alias)
+
+endif
+
if ENABLE_FIRSTBOOT
MANPAGES += \
man/systemd-firstboot.1
endif
+if ENABLE_HIBERNATE
+MANPAGES += \
+ man/systemd-hibernate-resume-generator.8 \
+ man/systemd-hibernate-resume@.service.8
+MANPAGES_ALIAS += \
+ man/systemd-hibernate-resume.8
+man/systemd-hibernate-resume.8: man/systemd-hibernate-resume@.service.8
+man/systemd-hibernate-resume.html: man/systemd-hibernate-resume@.service.html
+ $(html-alias)
+
+endif
+
if ENABLE_HOSTNAMED
MANPAGES += \
man/hostnamectl.1 \
endif
+if ENABLE_NSS_SYSTEMD
+MANPAGES += \
+ man/nss-systemd.8
+MANPAGES_ALIAS += \
+ man/libnss_systemd.so.2.8
+man/libnss_systemd.so.2.8: man/nss-systemd.8
+man/libnss_systemd.so.2.html: man/nss-systemd.html
+ $(html-alias)
+
+endif
+
if ENABLE_QUOTACHECK
MANPAGES += \
man/systemd-quotacheck.service.8
man/dnssec-trust-anchors.d.5 \
man/nss-resolve.8 \
man/resolved.conf.5 \
+ man/systemd-resolve.1 \
man/systemd-resolved.service.8
MANPAGES_ALIAS += \
man/libnss_resolve.so.2.8 \
LIBUDEV_REVISION=6
LIBUDEV_AGE=6
-LIBSYSTEMD_CURRENT=18
+LIBSYSTEMD_CURRENT=19
LIBSYSTEMD_REVISION=0
-LIBSYSTEMD_AGE=18
+LIBSYSTEMD_AGE=19
# Dirs of external packages
dbuspolicydir=@dbuspolicydir@
polkitpkladir=$(localstatedir)/lib/polkit-1/localauthority/10-vendor.d
bashcompletiondir=@bashcompletiondir@
zshcompletiondir=@zshcompletiondir@
-rpmmacrosdir=$(prefix)/lib/rpm/macros.d
+rpmmacrosdir=@rpmmacrosdir@
sysvinitdir=$(SYSTEM_SYSVINIT_PATH)
sysvrcnddir=$(SYSTEM_SYSVRCND_PATH)
varlogdir=$(localstatedir)/log
$(pkgconfiglib_DATA) \
$(nodist_bashcompletion_data) \
$(nodist_zshcompletion_data) \
+ $(nodist_rpmmacros_DATA) \
$(in_files:.in=) $(in_in_files:.in.in=) \
$(m4_files:.m4=)
SHUTDOWN_TARGET_WANTS =
LOCAL_FS_TARGET_WANTS =
+REMOTE_FS_TARGET_WANTS =
MULTI_USER_TARGET_WANTS =
GRAPHICAL_TARGET_WANTS =
+MACHINES_TARGET_WANTS =
RESCUE_TARGET_WANTS =
SYSINIT_TARGET_WANTS =
SOCKETS_TARGET_WANTS =
install-target-wants-hook:
what="$(SHUTDOWN_TARGET_WANTS)" && wants=shutdown.target && dir=$(systemunitdir) && $(add-wants)
what="$(LOCAL_FS_TARGET_WANTS)" && wants=local-fs.target && dir=$(systemunitdir) && $(add-wants)
+ what="$(REMOTE_FS_TARGET_WANTS)" && wants=remote-fs.target && dir=$(systemunitdir) && $(add-wants)
+ what="$(MACHINES_TARGET_WANTS)" && wants=machines.target && dir=$(systemunitdir) && $(add-wants)
what="$(MULTI_USER_TARGET_WANTS)" && wants=multi-user.target && dir=$(systemunitdir) && $(add-wants)
what="$(GRAPHICAL_TARGET_WANTS)" && wants=graphical.target && dir=$(systemunitdir) && $(add-wants)
what="$(RESCUE_TARGET_WANTS)" && wants=rescue.target && dir=$(systemunitdir) && $(add-wants)
30-systemd-environment-d-generator
endif
+rootlibexec_SCRIPTS = \
+ src/sulogin-shell/systemd-sulogin-shell
+
+EXTRA_DIST += \
+ src/sulogin-shell/systemd-sulogin-shell.in
+
dist_bashcompletion_data = \
shell-completion/bash/busctl \
shell-completion/bash/journalctl \
units/sys-kernel-debug.mount \
units/sys-fs-fuse-connections.mount \
units/tmp.mount \
- units/var-lib-machines.mount \
units/printer.target \
units/sound.target \
units/bluetooth.target \
units/initrd-switch-root.service.in \
units/systemd-nspawn@.service.in \
units/systemd-update-done.service.in \
- units/tmp.mount.m4
+ units/tmp.mount.m4
if HAVE_SYSV_COMPAT
nodist_systemunit_DATA += \
LICENSE.LGPL2.1 \
LICENSE.GPL2 \
DISTRO_PORTING \
- src/libsystemd/sd-bus/PORTING-DBUS1 \
- src/libsystemd/sd-bus/DIFFERENCES \
src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
EXTRA_DIST += \
$(AM_V_LN)$(LN_S) -f systemd.index.html $@
if HAVE_PYTHON
+if ENABLE_MANPAGES
noinst_DATA += \
man/index.html
endif
+endif
CLEANFILES += \
man/index.html
libbasic_la_LIBADD = \
$(SELINUX_LIBS) \
$(CAP_LIBS) \
- -lrt \
- -lm
+ -lrt
# -----------------------------------------------------------------------------
noinst_LTLIBRARIES += \
src/shared/output-mode.c \
src/shared/gpt.h \
src/shared/udev-util.h \
+ src/shared/udev-util.c \
src/shared/linux/auto_dev-ioctl.h \
+ src/shared/linux-3.13/dm-ioctl.h \
src/shared/initreq.h \
src/shared/dns-domain.c \
src/shared/dns-domain.h \
$(AM_CFLAGS) \
$(ACL_CFLAGS) \
$(LIBIDN_CFLAGS) \
+ $(LIBIDN2_CFLAGS) \
$(SECCOMP_CFLAGS) \
$(BLKID_CFLAGS) \
$(LIBCRYPTSETUP_CFLAGS)
libudev-internal.la \
$(ACL_LIBS) \
$(LIBIDN_LIBS) \
+ $(LIBIDN2_LIBS) \
$(SECCOMP_LIBS) \
$(BLKID_LIBS) \
$(LIBCRYPTSETUP_LIBS)
$(libudev_internal_la_CFLAGS) \
$(ACL_CFLAGS) \
$(LIBIDN_CFLAGS) \
+ $(LIBIDN2_CFLAGS) \
$(SECCOMP_CFLAGS) \
$(BLKID_CFLAGS) \
$(LIBCRYPTSETUP_CFLAGS) \
$(libudev_internal_la_LIBADD) \
$(ACL_LIBS) \
$(LIBIDN_LIBS) \
+ $(LIBIDN2_LIBS) \
$(SECCOMP_LIBS) \
$(BLKID_LIBS) \
$(LIBCRYPTSETUP_LIBS)
pkgconfigdata_DATA += \
src/core/systemd.pc
+if ENABLE_RPM_MACROS
nodist_rpmmacros_DATA = \
src/core/macros.systemd
+endif
BUILT_SOURCES += \
src/core/triggers.systemd
test-conf-parser \
test-capability \
test-async \
+ test-random-util \
test-ratelimit \
test-condition \
test-uid-range \
test/test-execute/exec-readonlypaths-mount-propagation.service \
test/test-execute/exec-readwritepaths-mount-propagation.service \
test/test-execute/exec-inaccessiblepaths-mount-propagation.service \
+ test/test-execute/exec-inaccessiblepaths-proc.service \
test/test-execute/exec-spec-interpolation.service \
test/test-execute/exec-systemcallerrornumber.service \
test/test-execute/exec-systemcallfilter-failing2.service \
test_fstab_util_LDADD = \
libsystemd-shared.la
+test_random_util_SOURCES = \
+ src/test/test-random-util.c
+
+test_random_util_LDADD = \
+ libsystemd-shared.la
+
test_ratelimit_SOURCES = \
src/test/test-ratelimit.c
test_seccomp_SOURCES = \
src/test/test-seccomp.c
+test_seccomp_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(SECCOMP_CFLAGS)
+
test_seccomp_LDADD = \
libsystemd-shared.la \
$(SECCOMP_LIBS)
test_sizeof_SOURCES = \
src/test/test-sizeof.c
-test_sizeof_LDADD = \
- libsystemd-shared.la
-
BUILT_SOURCES += \
src/test/test-hashmap-ordered.c
test_execute_CFLAGS = \
$(AM_CFLAGS) \
+ $(SECCOMP_CFLAGS) \
$(MOUNT_CFLAGS)
test_execute_LDADD = \
nodist_tmpfiles_DATA = \
tmpfiles.d/systemd.conf \
+ tmpfiles.d/var.conf \
tmpfiles.d/etc.conf
dist_tmpfiles_DATA = \
tmpfiles.d/systemd-nologin.conf \
tmpfiles.d/tmp.conf \
tmpfiles.d/x11.conf \
- tmpfiles.d/var.conf \
tmpfiles.d/home.conf \
tmpfiles.d/systemd-nspawn.conf \
tmpfiles.d/journal-nocow.conf
tmpfiles.d/legacy.conf
endif
+if HAVE_REMOTE
+nodist_tmpfiles_DATA += \
+ tmpfiles.d/systemd-remote.conf
+endif
+
SYSINIT_TARGET_WANTS += \
systemd-tmpfiles-setup-dev.service \
systemd-tmpfiles-setup.service
EXTRA_DIST += \
tmpfiles.d/systemd.conf.m4 \
+ tmpfiles.d/systemd-remote.conf.m4 \
tmpfiles.d/etc.conf.m4 \
+ tmpfiles.d/var.conf.m4 \
units/systemd-tmpfiles-setup-dev.service.in \
units/systemd-tmpfiles-setup.service.in \
units/systemd-tmpfiles-clean.service.in
systemd_detect_virt_LDADD = \
libsystemd-shared.la
-INSTALL_EXEC_HOOKS += \
- systemd-detect-virt-install-hook
-
# ------------------------------------------------------------------------------
systemd_delta_SOURCES = \
src/delta/delta.c
efi_ldflags += --defsym=EFI_SUBSYSTEM=0xa
EFI_FORMAT = -O binary
else
+if ARCH_ARM
+efi_ldflags += --defsym=EFI_SUBSYSTEM=0xa
+EFI_FORMAT = -O binary
+else
EFI_FORMAT = --target=efi-app-$(EFI_ARCH)
endif
endif
endif
+endif
# ------------------------------------------------------------------------------
-systemd_boot_headers = \
- src/boot/efi/util.h \
+efi_headers = \
src/boot/efi/console.h \
+ src/boot/efi/disk.h \
src/boot/efi/graphics.h \
- src/boot/efi/pefile.h \
+ src/boot/efi/linux.h \
src/boot/efi/measure.h \
- src/boot/efi/disk.h
+ src/boot/efi/pe.h \
+ src/boot/efi/splash.h \
+ src/boot/efi/util.h \
+ src/boot/efi/shim.h
systemd_boot_sources = \
- src/boot/efi/util.c \
+ src/boot/efi/boot.c \
src/boot/efi/console.c \
- src/boot/efi/graphics.c \
- src/boot/efi/pefile.c \
src/boot/efi/disk.c \
+ src/boot/efi/graphics.c \
src/boot/efi/measure.c \
- src/boot/efi/boot.c
+ src/boot/efi/pe.c \
+ src/boot/efi/util.c \
+ src/boot/efi/shim.c
EXTRA_DIST += $(systemd_boot_sources) $(systemd_boot_headers)
if HAVE_GNUEFI
bootlib_DATA = $(systemd_boot)
-$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(systemd_boot_headers))
+$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(efi_headers))
@$(MKDIR_P) $(top_builddir)/src/boot/efi/
$(AM_V_CC)$(EFI_CC) $(efi_cppflags) $(efi_cflags) -c $< -o $@
CLEANFILES += $(systemd_boot_objects) $(systemd_boot_solib) $(systemd_boot)
# ------------------------------------------------------------------------------
-stub_headers = \
- src/boot/efi/util.h \
- src/boot/efi/pefile.h \
- src/boot/efi/disk.h \
- src/boot/efi/graphics.h \
- src/boot/efi/splash.h \
- src/boot/efi/measure.h \
- src/boot/efi/linux.h
-
stub_sources = \
- src/boot/efi/util.c \
- src/boot/efi/pefile.c \
src/boot/efi/disk.c \
src/boot/efi/graphics.c \
- src/boot/efi/splash.c \
src/boot/efi/linux.c \
src/boot/efi/measure.c \
- src/boot/efi/stub.c
+ src/boot/efi/pe.c \
+ src/boot/efi/splash.c \
+ src/boot/efi/stub.c \
+ src/boot/efi/util.c
EXTRA_DIST += \
$(stub_sources) \
if HAVE_GNUEFI
bootlib_DATA += $(stub)
-$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(stub_headers))
- @$(MKDIR_P) $(top_builddir)/src/boot/efi/
- $(AM_V_CC)$(EFI_CC) $(efi_cppflags) $(efi_cflags) -c $< -o $@
-
$(stub_solib): $(stub_objects)
$(AM_V_CCLD)$(LD) $(efi_ldflags) $(stub_objects) \
-o $@ -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name); \
# ------------------------------------------------------------------------------
CLEANFILES += test-efi-disk.img
-test-efi-disk.img: $(systemd_boot) $(stub) test/test-efi-create-disk.sh
- $(AM_V_GEN)test/test-efi-create-disk.sh
+test-efi-disk.img: $(systemd_boot) $(stub) test/splash.bmp test/test-efi-create-disk.sh
+ $(AM_V_GEN)test/test-efi-create-disk.sh $@ $(systemd_boot) $(stub) test/splash.bmp
test-efi: test-efi-disk.img
$(QEMU) -machine accel=kvm -m 1024 -bios $(QEMU_BIOS) -snapshot test-efi-disk.img
EXTRA_DIST += \
src/libsystemd/libsystemd.pc.in \
- src/libsystemd/sd-bus/DIFFERENCES \
src/libsystemd/sd-bus/GVARIANT-SERIALIZATION
libsystemd_la_SOURCES =
test-bus-zero-copy \
test-bus-introspect \
test-bus-objects \
+ test-bus-vtable \
test-bus-error \
test-bus-creds \
test-bus-gvariant \
test_bus_objects_LDADD = \
libsystemd-shared.la
+test_bus_vtable_SOURCES = \
+ src/libsystemd/sd-bus/test-bus-vtable.c
+
+test_bus_vtable_LDADD = \
+ libsystemd-shared.la
+
test_bus_error_SOURCES = \
src/libsystemd/sd-bus/test-bus-error.c
libsystemd-shared.la
busctl_SOURCES = \
- src/libsystemd/sd-bus/busctl.c \
- src/libsystemd/sd-bus/busctl-introspect.c \
- src/libsystemd/sd-bus/busctl-introspect.h
+ src/busctl/busctl.c \
+ src/busctl/busctl-introspect.c \
+ src/busctl/busctl-introspect.h
busctl_LDADD = \
libsystemd-shared.la
src/systemd/sd-ipv4ll.h \
src/systemd/sd-ipv4acd.h \
src/systemd/sd-ndisc.h \
+ src/systemd/sd-radv.h \
src/systemd/sd-dhcp6-client.h \
src/systemd/sd-dhcp6-lease.h \
src/systemd/sd-lldp.h \
src/libsystemd-network/ndisc-internal.h \
src/libsystemd-network/ndisc-router.h \
src/libsystemd-network/ndisc-router.c \
+ src/libsystemd-network/sd-radv.c \
+ src/libsystemd-network/radv-internal.h \
src/libsystemd-network/icmp6-util.h \
src/libsystemd-network/icmp6-util.c \
src/libsystemd-network/sd-dhcp6-client.c \
libsystemd-network.la \
libsystemd-shared.la
+test_sd_dhcp_lease_SOURCES = \
+ src/libsystemd-network/dhcp-lease-internal.h \
+ src/libsystemd-network/test-sd-dhcp-lease.c
+
+test_sd_dhcp_lease_LDADD = \
+ libsystemd-network.la \
+ libsystemd-shared.la
+
test_dhcp_client_SOURCES = \
src/systemd/sd-dhcp-client.h \
src/libsystemd-network/dhcp-protocol.h \
libudev.la \
libsystemd-shared.la
+test_ndisc_ra_SOURCES = \
+ src/systemd/sd-ndisc.h \
+ src/libsystemd-network/icmp6-util.h \
+ src/libsystemd-network/test-ndisc-ra.c
+
+test_ndisc_ra_LDADD = \
+ libsystemd-network.la \
+ libudev.la \
+ libsystemd-shared.la
+
test_dhcp6_client_SOURCES = \
src/systemd/sd-dhcp6-client.h \
src/libsystemd-network/dhcp6-internal.h \
test-dhcp-option \
test-dhcp-client \
test-dhcp-server \
+ test-sd-dhcp-lease \
test-ipv4ll \
test-ndisc-rs \
+ test-ndisc-ra \
test-dhcp6-client \
test-lldp
network/80-container-vz.network
dist_udevrules_DATA += \
- rules/50-udev-default.rules \
rules/60-block.rules \
rules/60-drm.rules \
rules/60-evdev.rules \
+ rules/60-input-id.rules \
rules/60-persistent-storage-tape.rules \
rules/60-persistent-input.rules \
rules/60-persistent-alsa.rules \
rules/60-sensor.rules \
rules/60-serial.rules \
rules/64-btrfs.rules \
+ rules/70-joystick.rules \
rules/70-mouse.rules \
rules/70-touchpad.rules \
rules/75-net-description.rules \
rules/80-net-setup-link.rules
nodist_udevrules_DATA += \
+ rules/50-udev-default.rules \
rules/99-systemd.rules
udevconfdir = $(sysconfdir)/udev
src/udev/udev.pc
EXTRA_DIST += \
+ rules/50-udev-default.rules.in \
rules/99-systemd.rules.in \
src/udev/udev.pc.in
src/udev/keyboard-keys-list.txt:
$(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9K]/ { if ($$2 != "KEY_MAX") { print $$2 } }' > $@
+ $(AM_V_GEN)$(top_srcdir)/src/udev/generate-keyboard-keys-list.sh "$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)" > $@
src/udev/keyboard-keys-from-name.gperf: src/udev/keyboard-keys-list.txt
- $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print tolower(substr($$1 ,5)) ", " $$1 }' < $< > $@
+ $(AM_V_GEN)$(top_srcdir)/src/udev/generate-keyboard-keys-gperf.sh $< > $@
src/udev/keyboard-keys-from-name.h: src/udev/keyboard-keys-from-name.gperf
$(AM_V_GPERF)$(GPERF) -L ANSI-C -t -N keyboard_lookup_key -H hash_key_name -p -C < $< > $@
libudev_core_la_CFLAGS = \
$(AM_CFLAGS) \
$(BLKID_CFLAGS) \
- $(KMOD_CFLAGS)
+ $(KMOD_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
libudev_core_la_LIBADD = \
libsystemd-network.la \
systemd_udevd_SOURCES = \
src/udev/udevd.c
+systemd_udevd_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
systemd_udevd_LDADD = \
libudev-core.la \
libbasic.la
ata_id_SOURCES = \
src/udev/ata_id/ata_id.c
+ata_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
ata_id_LDADD = \
libshared.la
cdrom_id_SOURCES = \
src/udev/cdrom_id/cdrom_id.c
+cdrom_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
cdrom_id_LDADD = \
libshared.la
collect_SOURCES = \
src/udev/collect/collect.c
+collect_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
collect_LDADD = \
libshared.la
src/udev/scsi_id/scsi.h \
src/udev/scsi_id/scsi_id.h
+scsi_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
scsi_id_LDADD = \
libshared.la
v4l_id_SOURCES = \
src/udev/v4l_id/v4l_id.c
+v4l_id_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
v4l_id_LDADD = \
libshared.la
src/udev/mtd_probe/mtd_probe.h \
src/udev/mtd_probe/probe_smartmedia.c
+mtd_probe_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DLOG_REALM=LOG_REALM_UDEV
+
dist_udevrules_DATA += \
rules/75-probe_mtd.rules
systemd_journal_remote_LDADD += \
$(MICROHTTPD_LIBS)
-if ENABLE_TMPFILES
-dist_tmpfiles_DATA += \
- tmpfiles.d/systemd-remote.conf
-endif
-
if HAVE_GNUTLS
systemd_journal_remote_LDADD += \
$(GNUTLS_LIBS)
libsystemd_journal_internal_la_LIBADD += \
$(GCRYPT_LIBS)
-# fsprg.c is a drop-in file using void pointer arithmetic
libsystemd_journal_internal_la_CFLAGS += \
- $(GCRYPT_CFLAGS) \
- -Wno-pointer-arith
+ $(GCRYPT_CFLAGS)
endif
noinst_LTLIBRARIES += \
libsystemd-shared.la \
-ldl
-systemd_localed_CFLAGS = \
- $(AM_CFLAGS) \
- $(XKBCOMMON_CFLAGS)
-
nodist_systemunit_DATA += \
units/systemd-localed.service
shell-completion/zsh/_localectl
endif
-.PHONY: update-kbd-model-map
-
polkitpolicy_in_files += \
src/locale/org.freedesktop.locale1.policy.in
libsystemd-shared.la \
-lm
+test_timesync_SOURCES = \
+ src/timesync/test-timesync.c \
+ src/timesync/timesyncd-manager.c \
+ src/timesync/timesyncd-manager.h \
+ src/timesync/timesyncd-conf.c \
+ src/timesync/timesyncd-conf.h \
+ src/timesync/timesyncd-server.c \
+ src/timesync/timesyncd-server.h
+
+nodist_test_timesync_SOURCES = \
+ src/timesync/timesyncd-gperf.c
+
+test_timesync_LDADD = \
+ libsystemd-shared.la \
+ -lm
+
+tests += \
+ test-timesync
+
rootlibexec_PROGRAMS += \
systemd-timesyncd
test-nss
# ------------------------------------------------------------------------------
+if ENABLE_NSS_SYSTEMD
libnss_systemd_la_SOURCES = \
src/nss-systemd/nss-systemd.sym \
src/nss-systemd/nss-systemd.c
rootlib_LTLIBRARIES += \
libnss_systemd.la
+endif
# ------------------------------------------------------------------------------
if HAVE_MYHOSTNAME
# ------------------------------------------------------------------------------
if ENABLE_MACHINED
+
+dist_systemunit_DATA += \
+ units/var-lib-machines.mount
+
systemd_machined_SOURCES = \
src/machine/machined.c \
src/machine/machined.h
nodist_pkgsysconf_DATA += \
src/resolve/resolved.conf
+dist_rootlibexec_DATA += \
+ src/resolve/resolv.conf
+
libnss_resolve_la_SOURCES = \
src/nss-resolve/nss-resolve.sym \
src/nss-resolve/nss-resolve.c
libnss_resolve_la_LIBADD = \
libsystemd-internal.la \
- libbasic.la \
- -ldl
+ libbasic.la
rootlib_LTLIBRARIES += \
libnss_resolve.la
tests += \
test-dns-packet \
test-resolve-tables \
+ test-resolved-packet \
test-dnssec
manual_tests += \
$(GCRYPT_LIBS) \
-lm
+test_resolved_packet_SOURCES = \
+ src/resolve/test-resolved-packet.c \
+ $(basic_dns_sources)
+
+test_resolved_packet_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(GCRYPT_CFLAGS)
+
+test_resolved_packet_LDADD = \
+ libsystemd-shared.la \
+ $(GCRYPT_LIBS) \
+ -lm
+
test_dns_packet_SOURCES = \
src/resolve/test-dns-packet.c \
$(basic_dns_sources)
units/systemd-resolved.service.m4.in \
src/resolve/resolved.conf.in
-dist_rootlibexec_DATA += \
- src/resolve/resolv.conf
-
# ------------------------------------------------------------------------------
if ENABLE_NETWORKD
rootlibexec_PROGRAMS += \
src/network/netdev/veth.c \
src/network/netdev/vxlan.h \
src/network/netdev/vxlan.c \
+ src/network/netdev/geneve.h \
+ src/network/netdev/geneve.c \
src/network/netdev/vlan.h \
src/network/netdev/vlan.c \
src/network/netdev/macvlan.h \
src/network/networkd-dhcp4.c \
src/network/networkd-dhcp6.c \
src/network/networkd-ndisc.h \
+ src/network/networkd-radv.c \
+ src/network/networkd-radv.h \
src/network/networkd-ndisc.c \
src/network/networkd-network.h \
src/network/networkd-network.c \
src/network/networkd-network-bus.c \
src/network/networkd-address.h \
src/network/networkd-address.c \
+ src/network/networkd-address-label.h \
+ src/network/networkd-address-label.c \
src/network/networkd-route.h \
src/network/networkd-route.c \
src/network/networkd-fdb.h \
GENERAL_ALIASES += \
$(systemunitdir)/systemd-networkd.socket $(pkgsysconfdir)/system/sockets.target.wants/systemd-networkd.socket \
$(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-networkd.service \
- $(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service
-
-SYSTEM_UNIT_ALIASES += \
- systemd-networkd.service dbus-org.freedesktop.network1.service
+ $(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service \
+ $(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/dbus-org.freedesktop.network1.service
BUSNAMES_TARGET_WANTS += \
org.freedesktop.network1.busname
src/network/systemd-networkd.pkla \
units/systemd-networkd.service.m4.in \
units/systemd-networkd-wait-online.service.in \
- test/networkd-test.py
+ test/networkd-test.py \
+ test/test-exec-deserialization.py
# ------------------------------------------------------------------------------
if ENABLE_LOGIND
liblogind-core.la
manual_tests += \
- test-login \
test-inhibit
tests += \
+ test-login \
test-login-tables \
test-login-shared
'|exec_prefix=$(exec_prefix)|' \
'|libdir=$(libdir)|' \
'|includedir=$(includedir)|' \
- '|VERSION=$(VERSION)|' \
'|rootprefix=$(rootprefix)|' \
'|udevlibexecdir=$(udevlibexecdir)|' \
'|SUSHELL=$(SUSHELL)|' \
'|KILL_USER_PROCESSES=$(KILL_USER_PROCESSES)|' \
'|systemuidmax=$(SYSTEM_UID_MAX)|' \
'|systemgidmax=$(SYSTEM_GID_MAX)|' \
+ '|DEV_KVM_MODE=$(DEV_KVM_MODE)|' \
'|TTY_GID=$(TTY_GID)|' \
'|systemsleepdir=$(systemsleepdir)|' \
'|systemshutdowndir=$(systemshutdowndir)|' \
src/%.policy.in: src/%.policy.in.in
$(SED_PROCESS)
+src/sulogin-shell/%: src/sulogin-shell/%.in
+ $(SED_PROCESS)
+ $(AM_V_GEN)chmod +x $@
+
shell-completion/%: shell-completion/%.in
$(SED_PROCESS)
$(polkitpolicy_files) \
$(polkitpolicy_in_in_files:.policy.in.in=.policy)
polkitrules_DATA = $(polkitrules_files)
+if ENABLE_POLKIT_PKLA
polkitpkla_DATA = $(polkitpkla_files)
endif
+endif
EXTRA_DIST += \
$(polkitpolicy_in_files) \
--stringparam funcsynopsis.style ansi \
--stringparam man.authors.section.enabled 0 \
--stringparam man.copyright.section.enabled 0 \
- --stringparam systemd.version $(VERSION) \
+ --stringparam systemd.version $(PACKAGE_VERSION) \
--path '$(builddir)/man:$(srcdir)/man'
XSLT = $(if $(XSLTPROC), $(XSLTPROC), xsltproc)
LOCAL_FS_TARGET_WANTS += \
systemd-remount-fs.service \
- tmp.mount \
+ tmp.mount
+
+REMOTE_FS_TARGET_WANTS += \
var-lib-machines.mount
MULTI_USER_TARGET_WANTS += \
systemd-sysctl.service \
systemd-ask-password-console.path
+if ENABLE_MACHINED
+MACHINES_TARGET_WANTS += \
+ var-lib-machines.mount
+endif
+
if HAVE_SYSV_COMPAT
SYSTEM_UNIT_ALIASES += \
poweroff.target runlevel0.target \
--with-zshcompletiondir=$$dc_install_base/$(zshcompletiondir) \
--with-pamlibdir=$$dc_install_base/$(pamlibdir) \
--with-pamconfdir=$$dc_install_base/$(pamconfdir) \
+ --with-rpmmacrosdir=$$dc_install_base/$(rpmmacrosdir) \
--with-rootprefix=$$dc_install_base \
--enable-compat-libs
done; exit $$res
.PHONY: hwdb-update
-hwdb-update:
- ( cd $(top_srcdir)/hwdb && \
- wget -O usb.ids 'http://www.linux-usb.org/usb.ids' && \
- wget -O pci.ids 'http://pci-ids.ucw.cz/v2.2/pci.ids' && \
- wget -O ma-large.txt 'http://standards.ieee.org/develop/regauth/oui/oui.txt' && \
- wget -O ma-medium.txt 'http://standards.ieee.org/develop/regauth/oui28/mam.txt' && \
- wget -O ma-small.txt 'http://standards.ieee.org/develop/regauth/oui36/oui36.txt' && \
- wget -O pnp_id_registry.html 'http://www.uefi.org/uefi-pnp-export' && \
- wget -O acpi_id_registry.html 'http://www.uefi.org/uefi-acpi-export' && \
- ./ids-update.pl && \
- ./acpi-update.py > 20-acpi-vendor.hwdb.base && \
- patch -p0 -o- 20-acpi-vendor.hwdb.base < 20-acpi-vendor.hwdb.patch > 20-acpi-vendor.hwdb )
+hwdb-update: tools/meson-hwdb-update.sh
+ $< $(top_srcdir)/hwdb
.PHONY: built-sources
built-sources: $(BUILT_SOURCES)
.PHONY: git-tag
git-tag:
- git tag -s "v$(VERSION)" -m "systemd $(VERSION)"
+ git tag -s "v$(PACKAGE_VERSION)" -m "systemd $(PACKAGE_VERSION)"
.PHONY: git-tar
git-tar:
- git archive --format=tar --prefix=systemd-$(VERSION)/ HEAD | gzip > systemd-$(VERSION).tar.gz
+ git archive -o systemd-$(PACKAGE_VERSION).tar.gz --prefix=systemd-$(PACKAGE_VERSION)/ HEAD
+
+%.asc: %
+ gpg2 --detach-sign -a -o $@ $<
www_target = www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd
.PHONY: doc-sync
-doc-sync: all
+doc-sync: man
rsync -rlv --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ $(www_target)/man/
.PHONY: install-tree
print-%:
@echo $($*)
+.PHONY: git-contrib
git-contrib:
@git shortlog -s `git describe --abbrev=0`.. | cut -c8- | sed 's/ / /g' | awk '{ print $$0 "," }' | sort -u
EXTRA_DIST += \
tools/gdb-sd_dump_hashmaps.py
+.PHONY: list-keys
list-keys:
gpg --verbose --no-options --no-default-keyring --no-auto-key-locate --batch --trust-model=always --keyring=$(srcdir)/src/import/import-pubring.gpg --list-keys
+.PHONY: add-key
add-key:
gpg --verbose --no-options --no-default-keyring --no-auto-key-locate --batch --trust-model=always --keyring=$(srcdir)/src/import/import-pubring.gpg --import -
systemd System and Service Manager
+CHANGES WITH 234:
+
+ * Meson is now supported as build system in addition to Automake. It is
+ our plan to remove Automake in one of our next releases, so that
+ Meson becomes our exclusive build system. Hence, please start using
+ the Meson build system in your downstream packaging. There's plenty
+ of documentation around how to use Meson, the extremely brief
+ summary:
+
+ ./autogen.sh && ./configure && make && sudo make install
+
+ becomes:
+
+ meson build && ninja -C build && sudo ninja -C build install
+
+ * Unit files gained support for a new JobRunningTimeoutUSec= setting,
+ which permits configuring a timeout on the time a job is
+ running. This is particularly useful for setting timeouts on jobs for
+ .device units.
+
+ * Unit files gained two new options ConditionUser= and ConditionGroup=
+ for conditionalizing units based on the identity of the user/group
+ running a systemd user instance.
+
+ * systemd-networkd now understands a new FlowLabel= setting in the
+ [VXLAN] section of .network files, as well as a Priority= in
+ [Bridge], GVRP= + MVRP= + LooseBinding= + ReorderHeader= in [VLAN]
+ and GatewayOnlink= + IPv6Preference= + Protocol= in [Route]. It also
+ gained support for configuration of GENEVE links, and IPv6 address
+ labels. The [Network] section gained the new IPv6ProxyNDP= setting.
+
+ * .link files now understand a new Port= setting.
+
+ * systemd-networkd's DHCP support gained support for DHCP option 119
+ (domain search list).
+
+ * systemd-networkd gained support for serving IPv6 address ranges using
+ the Router Advertisment protocol. The new .network configuration
+ section [IPv6Prefix] may be used to configure the ranges to
+ serve. This is implemented based on a new, minimal, native server
+ implementation of RA.
+
+ * journalctl's --output= switch gained support for a new parameter
+ "short-iso-precise" for a mode where timestamps are shown as precise
+ ISO date values.
+
+ * systemd-udevd's "net_id" builtin may now generate stable network
+ interface names from IBM PowerVM VIO devices as well as ACPI platform
+ devices.
+
+ * MulticastDNS support in systemd-resolved may now be explicitly
+ enabled/disabled using the new MulticastDNS= configuration file
+ option.
+
+ * systemd-resolved may now optionally use libidn2 instead of the libidn
+ for processing internationalized domain names. Support for libidn2
+ should be considered experimental and should not be enabled by
+ default yet.
+
+ * "machinectl pull-tar" and related call may now do verification of
+ downloaded images using SUSE-style .sha256 checksum files in addition
+ to the already existing support for validating using Ubuntu-style
+ SHA256SUMS files.
+
+ * sd-bus gained support for a new sd_bus_message_appendv() call which
+ is va_list equivalent of sd_bus_message_append().
+
+ * sd-boot gained support for validating images using SHIM/MOK.
+
+ * The SMACK code learnt support for "onlycap".
+
+ * systemd-mount --umount is now much smarter in figuring out how to
+ properly unmount a device given its mount or device path.
+
+ * The code to call libnss_dns as a fallback from libnss_resolve when
+ the communication with systemd-resolved fails was removed. This
+ fallback was redundant and interfered with the [!UNAVAIL=return]
+ suffix. See nss-resolve(8) for the recommended configuration.
+
+ * systemd-logind may now be restarted without losing state. It stores
+ the file descriptors for devices it manages in the system manager
+ using the FDSTORE= mechanism. Please note that further changes in
+ other components may be required to make use of this (for example
+ Xorg has code to listen for stops of systemd-logind and terminate
+ itself when logind is stopped or restarted, in order to avoid using
+ stale file descriptors for graphical devices, which is now
+ counterproductive and must be reverted in order for restarts of
+ systemd-logind to be safe. See
+ https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101.)
+
+ * All kernel install plugins are called with the environment variable
+ KERNEL_INSTALL_MACHINE_ID which is set to the machine ID given by
+ /etc/machine-id. If the file is missing or empty, the variable is
+ empty and BOOT_DIR_ABS is the path of a temporary directory which is
+ removed after all the plugins exit. So, if KERNEL_INSTALL_MACHINE_ID
+ is empty, all plugins should not put anything in BOOT_DIR_ABS.
+
+ Contributions from: Adrian Heine né Lang, Aggelos Avgerinos, Alexander
+ Kurtz, Alexandros Frantzis, Alexey Brodkin, Alex Lu, Amir Pakdel, Amir
+ Yalon, Anchor Cat, Anthony Parsons, Bastien Nocera, Benjamin Gilbert,
+ Benjamin Robin, Boucman, Charles Plessy, Chris Chiu, Chris Lamb,
+ Christian Brauner, Christian Hesse, Colin Walters, Daniel Drake,
+ Danielle Church, Daniel Molkentin, Daniel Rusek, Daniel Wang, Davide
+ Cavalca, David Herrmann, David Michael, Dax Kelson, Dimitri John
+ Ledkov, Djalal Harouni, Dušan Kazik, Elias Probst, Evgeny Vereshchagin,
+ Federico Di Pierro, Felipe Sateler, Felix Zhang, Franck Bui, Gary
+ Tierney, George McCollister, Giedrius Statkevičius, Hans de Goede,
+ hecke, Hendrik Westerberg, Hristo Venev, Ian Wienand, Insun Pyo, Ivan
+ Shapovalov, James Cowgill, James Hemsing, Janne Heß, Jan Synacek, Jason
+ Reeder, João Paulo Rechi Vita, John Paul Adrian Glaubitz, Jörg
+ Thalheim, Josef Andersson, Josef Gajdusek, Julian Mehne, Kai Krakow,
+ Krzysztof Jackiewicz, Lars Karlitski, Lennart Poettering, Lluís Gili,
+ Lucas Werkmeister, Lukáš Nykrýn, Łukasz Stelmach, Mantas Mikulėnas,
+ Marcin Bachry, Marcus Cooper, Mark Stosberg, Martin Pitt, Matija Skala,
+ Matt Clarkson, Matthew Garrett, Matthias Greiner, Matthijs van Duin,
+ Max Resch, Michael Biebl, Michal Koutný, Michal Sekletar, Michal
+ Soltys, Michal Suchanek, Mike Gilbert, Nate Clark, Nathaniel R. Lewis,
+ Neil Brown, Nikolai Kondrashov, Pascal S. de Kloe, Pat Riehecky, Patrik
+ Flykt, Paul Kocialkowski, Peter Hutterer, Philip Withnall, Piotr
+ Szydełko, Rafael Fontenelle, Ray Strode, Richard Maw, Roelf Wichertjes,
+ Ronny Chevalier, Sarang S. Dalal, Sjoerd Simons, slodki, Stefan
+ Schweter, Susant Sahani, Ted Wood, Thomas Blume, Thomas Haller, Thomas
+ H. P. Andersen, Timothée Ravier, Tobias Jungel, Tobias Stoeckmann, Tom
+ Gundersen, Tom Yan, Torstein Husebø, Umut Tezduyar Lindskog,
+ userwithuid, Vito Caputo, Waldemar Brodkorb, WaLyong Cho, Yu, Li-Yu,
+ Yusuke Nojima, Yu Watanabe, Zbigniew Jędrzejewski-Szmek, Дамјан
+ Георгиевски
+
+ — Berlin, 2017-07-12
+
CHANGES WITH 233:
+ * This version requires at least gperf 3.1 for building, 3.0 is not
+ sufficient.
+
* The "hybrid" control group mode has been modified to improve
compatibility with "legacy" cgroups-v1 setups. Specifically, the
"hybrid" setup of /sys/fs/cgroup is now pretty much identical to
these NTP servers officially. We still recommend downstreams to
properly register an NTP pool with the NTP pool project though.
- * coredumpctl gained new new "--reverse" option for printing the list
+ * coredumpctl gained a new "--reverse" option for printing the list
of coredumps in reverse order.
* coredumpctl will now show additional information about truncated and
like Cockpit which register web clients as PAM sessions.
* timer units with at least one OnCalendar= setting will now
- be started only after timer-sync.target has been
+ be started only after time-sync.target has been
reached. This way they will not elapse before the system
clock has been corrected by a local NTP client or
similar. This is particular useful on RTC-less embedded
- except src/udev/* which is (currently still) GPLv2, GPLv2+
REQUIREMENTS:
- Linux kernel >= 3.12
+ Linux kernel >= 3.13
Linux kernel >= 4.2 for unified cgroup hierarchy support
Kernel Config Options:
glibc >= 2.16
libcap
libmount >= 2.27.1 (from util-linux)
- (util-linux *must* be built with --enable-libmount-force-mountinfo)
+ (util-linux < 2.29 *must* be built with --enable-libmount-force-mountinfo,
+ and later versions without --enable-libmount-support-mtab.)
libseccomp >= 2.3.1 (optional)
libblkid >= 2.24 (from util-linux) (optional)
libkmod >= 15 (optional)
libqrencode (optional)
libmicrohttpd (optional)
libpython (optional)
- libidn (optional)
+ libidn2 or libidn (optional)
elfutils >= 158 (optional)
make, gcc, and similar tools
dracut (optional)
PolicyKit (optional)
- When building from git, the following tools are needed:
+ Two build systems are supported: meson + ninja-build and autools + make.
+
+ The following tools are needed with both systems:
pkg-config
- docbook-xsl
- xsltproc
+ gperf >= 3.1
+ docbook-xsl (optional, required for documentation)
+ xsltproc (optional, required for documentation)
+ python-lxml (optional, required to build the indices)
+
+ When building with meson, python and ninja-build are required.
+
+ To build in directory build/:
+ meson build/ && ninja -C build
+
+ Any configuration options can be specfied as -Darg=value... arguments
+ to meson. After the build directory is initially configured, meson will
+ refuse to run again, and options must be changed with:
+ mesonconf -Darg=value...
+ mesonconf without any arguments will print out available options and
+ their current values.
+
+ Useful commands:
+ ninja -v some/target
+ ninja test
+ sudo ninja install
+ DESTDIR=... ninja install
+
+ When building with autotools, the following tools are needed:
+
automake
autoconf
libtool
intltool
- gperf
python (optional)
- python-lxml (optional, but required to build the indices)
- The build system is initialized with ./autogen.sh. A tar ball
- can be created with:
+ The build system is initialized with ./autogen.sh and the usual
+ ./configure && make
+ should be used.
+
+ A tar ball can be created with:
git archive --format=tar --prefix=systemd-222/ v222 | xz > systemd-222.tar.xz
When systemd-hostnamed is used, it is strongly recommended to
# systemd - System and Service Manager
+<a href="https://in.waw.pl/systemd-github-state/systemd-systemd-issues.svg"><img align="right" src="https://in.waw.pl/systemd-github-state/systemd-systemd-issues-small.svg" alt="Count of open issues over time"></a>
+<a href="https://in.waw.pl/systemd-github-state/systemd-systemd-pull-requests.svg"><img align="right" src="https://in.waw.pl/systemd-github-state/systemd-systemd-pull-requests-small.svg" alt="Count of open pull requests over time"></a>
[![Build Status](https://semaphoreci.com/api/v1/projects/28a5a3ca-3c56-4078-8b5e-7ed6ef912e14/443470/shields_badge.svg)](https://semaphoreci.com/systemd/systemd)<br/>
[![Coverity Scan Status](https://scan.coverity.com/projects/350/badge.svg)](https://scan.coverity.com/projects/350)
Features:
+* Add AddUser= setting to unit files, similar to DynamicUser=1 which however
+ creates a static, persistent user rather than a dynamic, transient user. We
+ can leverage code from sysusers.d for this.
+
+* add some optional flag to ReadWritePaths= and friends, that has the effect
+ that we create the dir in question when the service is started. Example:
+
+ ReadWritePaths=:/var/lib/foobar
+
* sort generated hwdb files alphabetically when we import them, so that git
diffs remain minimal (in particular: the OUI databases we import are not
sorted, and not stable)
--- /dev/null
+in_files = '''
+ systemd.bg.catalog
+ systemd.be.catalog
+ systemd.be@latin.catalog
+ systemd.fr.catalog
+ systemd.it.catalog
+ systemd.pl.catalog
+ systemd.pt_BR.catalog
+ systemd.ru.catalog
+ systemd.zh_CN.catalog
+ systemd.zh_TW.catalog
+ systemd.catalog
+'''.split()
+
+support_url = get_option('support-url')
+support_sed = 's~%SUPPORT_URL%~@0@~'.format(support_url)
+build_catalog_dir = meson.current_build_dir()
+
+foreach file : in_files
+ custom_target(
+ file,
+ input : file + '.in',
+ output: file,
+ command : [sed, support_sed, '@INPUT@'],
+ capture : true,
+ install : true,
+ install_dir : catalogdir)
+endforeach
AC_PREREQ([2.64])
AC_INIT([systemd],
- [233],
+ [234],
[https://github.com/systemd/systemd/issues],
[systemd],
[https://www.freedesktop.org/wiki/Software/systemd])
SET_ARCH(X86_64, x86_64*)
SET_ARCH(IA32, i*86*)
SET_ARCH(MIPS, mips*)
+SET_ARCH(ARM, arm*)
SET_ARCH(AARCH64, aarch64*)
# i18n stuff for the PolicyKit policy files, heck whether intltool can be found, disable NLS otherwise
pivot_root,
name_to_handle_at,
setns,
- getrandom,
renameat2,
kcmp,
keyctl,
#include <sched.h>
#include <string.h>
#include <linux/loop.h>
+]])
+
+AC_CHECK_DECLS([getrandom],
+ [AC_DEFINE([USE_SYS_RANDOM_H], [], [sys/random.h is usable])],
+ [AC_CHECK_DECLS([getrandom], [], [], [[
+#include <sys/random.h>
+]])], [[
#include <linux/random.h>
]])
IFLA_PHYS_PORT_ID,
IFLA_BOND_AD_INFO,
IFLA_VLAN_PROTOCOL,
- IFLA_VXLAN_REMCSUM_NOPARTIAL,
+ IFLA_VXLAN_GPE,
+ IFLA_GENEVE_LABEL,
IFLA_IPTUN_ENCAP_DPORT,
IFLA_GRE_ENCAP_DPORT,
IFLA_BRIDGE_VLAN_INFO,
[AC_MSG_ERROR([*** dbus-1 support requested but libraries not found])])])
AM_CONDITIONAL(HAVE_DBUS, [test "$have_dbus" = "yes"])
+# ------------------------------------------------------------------------------
+have_glib=no
+AC_ARG_ENABLE(glib, AS_HELP_STRING([--disable-glib], [disable usage of glib,gobject,gio in tests]))
+AS_IF([test "x$enable_glib" != "xno"], [
+ PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.22.0 gobject-2.0 >= 2.22.0 gio-2.0],
+ [AC_DEFINE(HAVE_GLIB, 1, [Define if glib,gobject,gio are available]) have_glib=yes],
+ [have_glib=no])
+ AS_IF([test "x$have_glib" = "xno" -a "x$enable_glib" = "xyes"],
+ [AC_MSG_ERROR([*** glib support requested but libraries not found])])])
+
# ------------------------------------------------------------------------------
have_utmp=yes
AC_ARG_ENABLE([utmp], AS_HELP_STRING([--disable-utmp], [disable utmp/wtmp log handling]),
[xyes], [have_utmp=yes],
[xno], [have_utmp=no],
AC_MSG_ERROR(bad value ${enableval} for --enable-utmp)))
-AS_IF([test "x$have_utmp" = "xyes"], [AC_DEFINE(HAVE_UTMP, 1, [Define if utmp/wtmp support is enabled])])
+AS_IF([test "x$have_utmp" = "xyes"], [
+ AC_DEFINE(HAVE_UTMP, 1, [Define if utmp/wtmp support is enabled])
+ have_utmp=yes
+ M4_DEFINES="$M4_DEFINES -DHAVE_UTMP"],
+ [have_utmp=no])
AM_CONDITIONAL([HAVE_UTMP], [test "x$have_utmp" = "xyes"])
# ------------------------------------------------------------------------------
fi
AM_CONDITIONAL(HAVE_LIBIDN, [test "$have_libidn" = "yes"])
+have_libidn2=no
+AC_ARG_ENABLE(libidn2, AS_HELP_STRING([--disable-libidn2], [disable optional LIBIDN2 support]))
+if test "$have_libidn" != "yes"; then
+ if test "x$enable_libidn2" != "xno"; then
+ PKG_CHECK_MODULES(LIBIDN2, [libidn2 >= 2.0.0],
+ [AC_DEFINE(HAVE_LIBIDN2, 1, [Define if libidn2 is available])
+ have_libidn2=yes
+ M4_DEFINES="$M4_DEFINES -DHAVE_LIBIDN2"],
+ [have_libidn2=no])
+ if test "x$have_libidn2" = "xno" -a "x$enable_libidn2" = "xyes"; then
+ AC_MSG_ERROR([*** libidn2 support requested but libraries not found])
+ fi
+ fi
+fi
+AM_CONDITIONAL(HAVE_LIBIDN2, [test "$have_libidn2" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_idn=no
+AC_ARG_ENABLE(idn, AS_HELP_STRING([--disable-idn], [disable IDN when printing host names]))
+if test "x$enable_idn" != "xno"; then
+ have_idn=yes
+ AC_DEFINE(ENABLE_IDN, [1], [IDN is enabled])
+fi
+AM_CONDITIONAL(ENABLE_IDN, [test "$have_idn" = "yes"])
+
+# ------------------------------------------------------------------------------
+have_nss_systemd=no
+AC_ARG_ENABLE(nss-systemd, AS_HELP_STRING([--disable-nss-systemd], [disable nss-systemd support]))
+if test "x$enable_nss_systemd" != "xno"; then
+ have_nss_systemd=yes
+ AC_DEFINE(ENABLE_NSS_SYSTEMD, [1], [nss-systemd is enabled])
+fi
+AM_CONDITIONAL(ENABLE_NSS_SYSTEMD, [test "$have_nss_systemd" = "yes"])
+
# ------------------------------------------------------------------------------
have_libiptc=no
AC_ARG_ENABLE(libiptc, AS_HELP_STRING([--disable-libiptc], [disable optional LIBIPTC support]))
fi
AM_CONDITIONAL(ENABLE_SYSUSERS, [test "$have_sysusers" = "yes"])
+AC_ARG_ENABLE(gshadow, AS_HELP_STRING([--disable-gshadow], [disable shadow group support]))
+AS_IF([test "x${enable_gshadow}" != "xno"], [
+ AC_DEFINE(ENABLE_GSHADOW, 1, [shadow group support is enabled])
+])
+
# ------------------------------------------------------------------------------
have_firstboot=no
AC_ARG_ENABLE(firstboot, AS_HELP_STRING([--disable-firstboot], [disable firstboot support]))
have_logind=yes
fi
AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"])
-AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ])
+AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(ENABLE_LOGIND, [1], [Logind support available]) ])
AC_ARG_WITH([kill-user-processes],
[AS_HELP_STRING([--without-kill-user-processes], [set logind's KillUserProcesses=no by default])])
AC_DEFINE_UNQUOTED(SYSTEM_GID_MAX, [$SYSTEM_GID_MAX], [Maximum System GID])
AC_SUBST(SYSTEM_GID_MAX)
+# ------------------------------------------------------------------------------
+
+AC_ARG_WITH(dev-kvm-mode,
+ AS_HELP_STRING([--with-dev-kvm-mode=MODE],
+ [/dev/kvm access mode, defaults to "0660"]),
+ [DEV_KVM_MODE="$withval"],
+ [DEV_KVM_MODE="0660"])
+
+AC_SUBST(DEV_KVM_MODE, [$DEV_KVM_MODE], [/dev/kvm access mode])
+
# ------------------------------------------------------------------------------
have_localed=no
AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon]))
if test "x$enable_polkit" != "xno"; then
AC_DEFINE(ENABLE_POLKIT, 1, [Define if PolicyKit support is to be enabled])
have_polkit=yes
+
+ # also enable support for *.pkla files on old polkit
+ PKG_CHECK_MODULES(POLKIT, [ polkit-gobject-1 < 0.106 ],
+ [polkit_pkla=yes],
+ [polkit_pkla=no])
fi
AM_CONDITIONAL(ENABLE_POLKIT, [test "x$have_polkit" = "xyes"])
+AM_CONDITIONAL(ENABLE_POLKIT_PKLA, [test "x$polkit_pkla" = "xyes"])
# ------------------------------------------------------------------------------
have_resolved=no
[DEFAULT_DNSSEC_MODE="$withval"],
[DEFAULT_DNSSEC_MODE="allow-downgrade"])
+if test "x$have_gcrypt" = xno -a "x${DEFAULT_DNSSEC_MODE}" != xno ; then
+ AC_MSG_WARN(default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.)
+ DEFAULT_DNSSEC_MODE="no"
+fi
+
AS_CASE("x${DEFAULT_DNSSEC_MODE}",
[xno], [mode=DNSSEC_NO],
[xyes], [mode=DNSSEC_YES],
AM_COND_IF(ARCH_X86_64, [
EFI_MACHINE_TYPE_NAME=x64])
+AM_COND_IF(ARCH_ARM, [
+ EFI_MACHINE_TYPE_NAME=arm])
+
AM_COND_IF(ARCH_AARCH64, [
EFI_MACHINE_TYPE_NAME=aa64])
have_gnuefi=no
AC_ARG_ENABLE(gnuefi, AS_HELP_STRING([--enable-gnuefi], [enable optional gnuefi support]))
AS_IF([test "x$enable_gnuefi" != "xno"], [
- AC_CHECK_HEADERS(efi/${EFI_ARCH}/efibind.h,
+ AC_ARG_WITH(efi-includedir,
+ AS_HELP_STRING([--with-efi-includedir=PATH], [path to EFI include directory]),
+ [EFI_INC_DIR="$withval"], [EFI_INC_DIR="/usr/include"]
+ )
+ AC_SUBST([EFI_INC_DIR])
+
+ AC_CHECK_HEADERS(${EFI_INC_DIR}/efi/${EFI_ARCH}/efibind.h,
[AC_DEFINE(HAVE_GNUEFI, 1, [Define if gnuefi is available])
have_gnuefi=yes],
[AS_IF([test "x$enable_gnuefi" = xyes],
[AS_IF([test "x$enable_gnuefi" = xyes],
[AC_MSG_ERROR([*** gnuefi support requested but files not found])],
[have_gnuefi=no])])
-
- AC_ARG_WITH(efi-includedir,
- AS_HELP_STRING([--with-efi-includedir=PATH], [path to EFI include directory]),
- [EFI_INC_DIR="$withval"], [EFI_INC_DIR="/usr/include"]
- )
- AC_SUBST([EFI_INC_DIR])
])
AM_CONDITIONAL(HAVE_GNUEFI, [test "x$have_gnuefi" = xyes])
AM_CONDITIONAL(ENABLE_PAM_CONFIG, [test "$with_pamconfdir" != "no"])
AX_NORMALIZE_PATH([with_pamconfdir])
+AC_ARG_WITH([rpmmacrosdir],
+ AS_HELP_STRING([--with-rpmmacrosdir=DIR], [directory to store macros for RPM]),
+ [], [with_rpmmacrosdir=\${prefix}/lib/rpm/macros.d])
+AM_CONDITIONAL(ENABLE_RPM_MACROS, [test "$with_rpmmacrosdir" != "no"])
+AX_NORMALIZE_PATH([with_rpmmacrosdir])
+
AC_ARG_ENABLE([split-usr],
AS_HELP_STRING([--enable-split-usr], [assume that /bin, /sbin aren't symlinks into /usr]),
[],
AC_SUBST([zshcompletiondir], [$with_zshcompletiondir])
AC_SUBST([pamlibdir], [$with_pamlibdir])
AC_SUBST([pamconfdir], [$with_pamconfdir])
+AC_SUBST([rpmmacrosdir], [$with_rpmmacrosdir])
AC_SUBST([rootprefix], [$with_rootprefix])
AC_SUBST([rootlibdir], [$with_rootlibdir])
AC_OUTPUT
AC_MSG_RESULT([
- $PACKAGE_NAME $VERSION
+ $PACKAGE_NAME $PACKAGE_VERSION
libcryptsetup: ${have_libcryptsetup}
PAM: ${have_pam}
MICROHTTPD: ${have_microhttpd}
GNUTLS: ${have_gnutls}
libcurl: ${have_libcurl}
+ libidn2: ${have_libidn2}
libidn: ${have_libidn}
+ IDN: ${have_idn}
libiptc: ${have_libiptc}
ELFUTILS: ${have_elfutils}
binfmt: ${have_binfmt}
default DNS servers: ${DNS_SERVERS}
default DNSSEC mode: ${DEFAULT_DNSSEC_MODE}
coredump: ${have_coredump}
- polkit: ${have_polkit}
+ polkit: ${have_polkit} (legacy pkla support: ${polkit_pkla})
efi: ${have_efi}
gnuefi: ${have_gnuefi}
efi arch: ${EFI_ARCH}
blkid: ${have_blkid}
libmount: ${have_libmount}
dbus: ${have_dbus}
+ glib: ${have_glib}
nss-myhostname: ${have_myhostname}
+ nss-systemd: ${have_nss_systemd}
hwdb: ${enable_hwdb}
tpm: ${have_tpm}
Python: ${have_python}
build Python: ${PYTHON}
PAM modules dir: ${with_pamlibdir}
PAM configuration dir: ${with_pamconfdir}
+ RPM macros dir: ${with_rpmmacrosdir}
D-Bus policy dir: ${with_dbuspolicydir}
D-Bus session dir: ${with_dbussessionservicedir}
D-Bus system dir: ${with_dbussystemservicedir}
TTY GID: ${TTY_GID}
maximum system UID: ${SYSTEM_UID_MAX}
maximum system GID: ${SYSTEM_GID_MAX}
+ /dev/kvm access mode: ${DEV_KVM_MODE}
certificate root: ${CERTIFICATEROOT}
support URL: ${SUPPORT_URL}
nobody user name: ${NOBODY_USER_NAME}
--- /dev/null
+file = configure_file(
+ input : 'README.in',
+ output : 'README',
+ configuration : substs)
+
+if conf.get('HAVE_SYSV_COMPAT', false)
+ install_data(file,
+ install_dir : sysvinit_path)
+endif
--- /dev/null
+file = configure_file(
+ input : 'README.in',
+ output : 'README',
+ configuration : substs)
+
+if conf.get('HAVE_SYSV_COMPAT', false)
+ install_data(file,
+ install_dir : varlogdir)
+endif
OUI:70B3D5EAE*
ID_OUI_FROM_DATABASE=Orlaco Products B.V.
-OUI:70B3D5066*
- ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
-
OUI:70B3D557D*
ID_OUI_FROM_DATABASE=WICOM1 GmbH
OUI:001BC5087*
ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC
-OUI:70B3D5720*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D56BF*
ID_OUI_FROM_DATABASE=Otto Bihler Maschinenfabrik GmbH & Co. KG
OUI:70B3D565A*
ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-OUI:70B3D5FFE*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D5721*
ID_OUI_FROM_DATABASE=Zoe Medical
OUI:70B3D5CF5*
ID_OUI_FROM_DATABASE=Petring Energietechnik GmbH
+OUI:70B3D5269*
+ ID_OUI_FROM_DATABASE=Gilbarco Veeder-Root
+
OUI:70B3D5FF7*
ID_OUI_FROM_DATABASE=Cybercom AB
OUI:70B3D5DCC*
ID_OUI_FROM_DATABASE=Eutron SPA
-OUI:70B3D5269*
- ID_OUI_FROM_DATABASE=Gilbarco Veeder-Root
+OUI:70B3D515C*
+ ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution
OUI:70B3D5173*
ID_OUI_FROM_DATABASE=National TeleConsultants LLC
-OUI:70B3D515C*
- ID_OUI_FROM_DATABASE=Woods Hole Oceanographic Institution
-
OUI:70B3D5CAE*
ID_OUI_FROM_DATABASE=THEMA
OUI:70B3D5FAF*
ID_OUI_FROM_DATABASE=Radig Hard & Software
-OUI:70B3D57A2*
- ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd.
-
OUI:70B3D50BC*
ID_OUI_FROM_DATABASE=Practical Software Studio LLC
+OUI:70B3D57A2*
+ ID_OUI_FROM_DATABASE=Alpha ESS Co., Ltd.
+
OUI:70B3D5724*
ID_OUI_FROM_DATABASE=Quan International Co., Ltd.
OUI:70B3D514C*
ID_OUI_FROM_DATABASE=CRDE
-OUI:70B3D5AB8*
- ID_OUI_FROM_DATABASE=HORIBA MEDICAL
-
OUI:70B3D5F9E*
ID_OUI_FROM_DATABASE=International Center for Elementary Particle Physics, The University of Tokyo
OUI:70B3D5495*
ID_OUI_FROM_DATABASE=Fiem Industries Ltd.
+OUI:70B3D5AD2*
+ ID_OUI_FROM_DATABASE=Wart-Elektronik
+
+OUI:70B3D52B4*
+ ID_OUI_FROM_DATABASE=Foerster-Technik GmbH
+
+OUI:70B3D5276*
+ ID_OUI_FROM_DATABASE=TELL Software Hungaria Kft.
+
+OUI:70B3D528C*
+ ID_OUI_FROM_DATABASE=Step Technica Co., Ltd.
+
+OUI:70B3D57E0*
+ ID_OUI_FROM_DATABASE=Sanko-sha,inc.
+
+OUI:70B3D5E50*
+ ID_OUI_FROM_DATABASE=Advanced Vision Technology Ltd
+
+OUI:70B3D58C1*
+ ID_OUI_FROM_DATABASE=Rievtech Electronic Co.,Ltd
+
+OUI:70B3D5F0C*
+ ID_OUI_FROM_DATABASE=ModulaTeam GmbH
+
+OUI:70B3D58AC*
+ ID_OUI_FROM_DATABASE=ASUNG TECHNO CO.,Ltd
+
+OUI:70B3D5CE1*
+ ID_OUI_FROM_DATABASE=EA Elektroautomatik GmbH & Co. KG
+
+OUI:70B3D5677*
+ ID_OUI_FROM_DATABASE=Fraunhofer-Institut IIS
+
+OUI:70B3D538B*
+ ID_OUI_FROM_DATABASE=Lookman Electroplast Industries Ltd
+
+OUI:70B3D59DC*
+ ID_OUI_FROM_DATABASE=Shanghai Daorech Industry Developmnet Co.,Ltd
+
+OUI:70B3D5888*
+ ID_OUI_FROM_DATABASE=Zetechtics Ltd
+
+OUI:70B3D5168*
+ ID_OUI_FROM_DATABASE=Biwave Technologies, Inc.
+
+OUI:70B3D5F25*
+ ID_OUI_FROM_DATABASE=JSC “Scientific Industrial Enterprise Rubin
+
+OUI:70B3D5A48*
+ ID_OUI_FROM_DATABASE=Applied Satellite Engineering
+
+OUI:70B3D546C*
+ ID_OUI_FROM_DATABASE=SHANGHAI CHENZHU INSTRUMENT CO., LTD.
+
+OUI:70B3D580B*
+ ID_OUI_FROM_DATABASE=Fischer Block, Inc.
+
+OUI:70B3D5FAD*
+ ID_OUI_FROM_DATABASE=ARC Technology Solutions, LLC
+
+OUI:70B3D5AB8*
+ ID_OUI_FROM_DATABASE=HORIBA ABX SAS
+
+OUI:70B3D5E6C*
+ ID_OUI_FROM_DATABASE=Fusar Technologies inc
+
+OUI:70B3D52B0*
+ ID_OUI_FROM_DATABASE=Beijing Zhongyi Yue Tai Technology Co., Ltd
+
+OUI:70B3D52E2*
+ ID_OUI_FROM_DATABASE=Spark Lasers
+
+OUI:70B3D5446*
+ ID_OUI_FROM_DATABASE=Santa Barbara Imaging Systems
+
+OUI:70B3D556B*
+ ID_OUI_FROM_DATABASE=S.E.I. CO.,LTD.
+
+OUI:70B3D5B48*
+ ID_OUI_FROM_DATABASE=DWQ Informatikai Tanacsado es Vezerlestechnikai KFT
+
+OUI:70B3D5A7E*
+ ID_OUI_FROM_DATABASE=QUICCO SOUND Corporation
+
+OUI:70B3D5878*
+ ID_OUI_FROM_DATABASE=Package Guard, Inc
+
+OUI:70B3D5245*
+ ID_OUI_FROM_DATABASE=Newtec A/S
+
+OUI:70B3D5FFE*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D53FE*
+ ID_OUI_FROM_DATABASE=Mentor Graphics
+
+OUI:70B3D574D*
+ ID_OUI_FROM_DATABASE=SPEECH TECHNOLOGY CENTER LIMITED
+
+OUI:70B3D55BF*
+ ID_OUI_FROM_DATABASE=Aton srl
+
+OUI:70B3D5EEA*
+ ID_OUI_FROM_DATABASE=Dameca a/s
+
+OUI:70B3D59B8*
+ ID_OUI_FROM_DATABASE=Loma Systems
+
+OUI:70B3D5BEA*
+ ID_OUI_FROM_DATABASE=Virtuosys Ltd
+
+OUI:70B3D5066*
+ ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
+
+OUI:70B3D52A1*
+ ID_OUI_FROM_DATABASE=Blink Services AB
+
+OUI:70B3D5591*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5133*
+ ID_OUI_FROM_DATABASE=Vidisys GmbH
+
+OUI:70B3D5720*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D51E6*
+ ID_OUI_FROM_DATABASE=Sanmina Israel
+
+OUI:70B3D5809*
+ ID_OUI_FROM_DATABASE=Tecnint HTE SRL
+
+OUI:70B3D52AB*
+ ID_OUI_FROM_DATABASE=NASA Johnson Space Center
+
+OUI:70B3D5254*
+ ID_OUI_FROM_DATABASE=Spectrum Brands
+
+OUI:70B3D57C9*
+ ID_OUI_FROM_DATABASE=Council Rock
+
+OUI:70B3D553A*
+ ID_OUI_FROM_DATABASE=Pano0ramic Power
+
+OUI:70B3D5E18*
+ ID_OUI_FROM_DATABASE=Plasmapp Co.,Ltd.
+
+OUI:70B3D5D44*
+ ID_OUI_FROM_DATABASE=ic-automation GmbH
+
+OUI:70B3D59D7*
+ ID_OUI_FROM_DATABASE=KM OptoElektronik GmbH
+
+OUI:70B3D561B*
+ ID_OUI_FROM_DATABASE=Nubewell Networks Pvt Ltd
+
OUI:70B3D5D60*
ID_OUI_FROM_DATABASE=Flintab AB
OUI:70B3D5166*
ID_OUI_FROM_DATABASE=SERIAL IMAGE INC.
-OUI:70B3D5E59*
- ID_OUI_FROM_DATABASE=FRACARRO SPA
-
OUI:70B3D576D*
ID_OUI_FROM_DATABASE=Trimble
OUI:001BC5050*
ID_OUI_FROM_DATABASE=TeliSwitch Solutions
-OUI:001BC5046*
- ID_OUI_FROM_DATABASE=Trans-European Research and Education Networking Association (TERENA)
-
OUI:001BC5040*
ID_OUI_FROM_DATABASE=OOO Actidata
OUI:70B3D5712*
ID_OUI_FROM_DATABASE=APG Cash Drawer, LLC
-OUI:70B3D5580*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D5776*
ID_OUI_FROM_DATABASE=Power Ltd.
OUI:70B3D5E9C*
ID_OUI_FROM_DATABASE=ATG UV Technology
-OUI:70B3D539E*
- ID_OUI_FROM_DATABASE=Lanmark Controls Inc.
-
OUI:70B3D5267*
ID_OUI_FROM_DATABASE=Zehntner Testing Instruments
+OUI:70B3D539E*
+ ID_OUI_FROM_DATABASE=Lanmark Controls Inc.
+
OUI:70B3D5C2E*
ID_OUI_FROM_DATABASE=Triax A/S
OUI:70B3D5B30*
ID_OUI_FROM_DATABASE=Systolé Hardware B.V.
-OUI:70B3D53BF*
- ID_OUI_FROM_DATABASE=Star Electronics GmbH & Co. KG
-
OUI:70B3D5745*
ID_OUI_FROM_DATABASE=TMSI LLC
+OUI:70B3D53BF*
+ ID_OUI_FROM_DATABASE=Star Electronics GmbH & Co. KG
+
OUI:70B3D5D1C*
ID_OUI_FROM_DATABASE=Specialised Imaging Limited
OUI:70B3D522C*
ID_OUI_FROM_DATABASE=Hiquel Elektronik- und Anlagenbau GmbH
-OUI:70B3D5DCE*
- ID_OUI_FROM_DATABASE=Stahl GmbH
-
OUI:70B3D52A2*
ID_OUI_FROM_DATABASE=Visualware, Inc.
+OUI:70B3D5DCE*
+ ID_OUI_FROM_DATABASE=Stahl GmbH
+
OUI:70B3D5D08*
ID_OUI_FROM_DATABASE=Veeco Instruments
OUI:70B3D5332*
ID_OUI_FROM_DATABASE=InnoSenT
+OUI:70B3D5A47*
+ ID_OUI_FROM_DATABASE=KANOA INC
+
+OUI:70B3D5F45*
+ ID_OUI_FROM_DATABASE=Norbit ODM AS
+
+OUI:70B3D5DEE*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5E59*
+ ID_OUI_FROM_DATABASE=Fracarro srl
+
+OUI:70B3D5127*
+ ID_OUI_FROM_DATABASE=VITEC
+
+OUI:001BC5046*
+ ID_OUI_FROM_DATABASE=GÉANT
+
+OUI:70B3D573A*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D59DE*
+ ID_OUI_FROM_DATABASE=System 11 Sp. z o.o.
+
+OUI:70B3D596D*
+ ID_OUI_FROM_DATABASE=MSB Elektronik und Gerätebau GmbH
+
+OUI:70B3D5C17*
+ ID_OUI_FROM_DATABASE=Potter Electric Signal Co. LLC
+
+OUI:70B3D5108*
+ ID_OUI_FROM_DATABASE=TEX COMPUTER SRL
+
+OUI:70B3D54E7*
+ ID_OUI_FROM_DATABASE=Digital Domain
+
+OUI:70B3D5007*
+ ID_OUI_FROM_DATABASE=SENSONEO
+
+OUI:70B3D5D10*
+ ID_OUI_FROM_DATABASE=Contec DTx
+
+OUI:70B3D57F3*
+ ID_OUI_FROM_DATABASE=Shenzhen Virtual Clusters Information Technology Co.,Ltd.
+
+OUI:70B3D5C8C*
+ ID_OUI_FROM_DATABASE=Rollogo Limited
+
+OUI:70B3D5D4C*
+ ID_OUI_FROM_DATABASE=Elystec Technology Co., Ltd
+
+OUI:70B3D596B*
+ ID_OUI_FROM_DATABASE=FOCAL-JMLab
+
+OUI:70B3D584D*
+ ID_OUI_FROM_DATABASE=Quantum Design Inc.
+
+OUI:70B3D5E57*
+ ID_OUI_FROM_DATABASE=Iradimed
+
+OUI:70B3D5125*
+ ID_OUI_FROM_DATABASE=Securolytics, Inc.
+
+OUI:70B3D5C6E*
+ ID_OUI_FROM_DATABASE=Orion Technologies, LLC
+
+OUI:70B3D5CC8*
+ ID_OUI_FROM_DATABASE=PROFEN COMMUNICATIONS
+
+OUI:70B3D5FDB*
+ ID_OUI_FROM_DATABASE=Design SHIFT
+
+OUI:70B3D5791*
+ ID_OUI_FROM_DATABASE=Romteck Australia
+
+OUI:70B3D569F*
+ ID_OUI_FROM_DATABASE=T+A elektroakustik GmbH & Co.KG
+
+OUI:70B3D5D20*
+ ID_OUI_FROM_DATABASE=Rheonics GmbH
+
+OUI:70B3D55FB*
+ ID_OUI_FROM_DATABASE=TELEPLATFORMS
+
+OUI:70B3D5768*
+ ID_OUI_FROM_DATABASE=Kazan Networks Corporation
+
+OUI:70B3D56B2*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D57F7*
+ ID_OUI_FROM_DATABASE=JASCO Applied Sciences Canada Ltd
+
+OUI:70B3D5F42*
+ ID_OUI_FROM_DATABASE=Matsuhisa Corporation
+
+OUI:70B3D5381*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5488*
+ ID_OUI_FROM_DATABASE=Cardinal Scale Mfg Co
+
+OUI:70B3D5273*
+ ID_OUI_FROM_DATABASE=WeVo Tech
+
+OUI:70B3D5379*
+ ID_OUI_FROM_DATABASE=Vensi, Inc.
+
+OUI:70B3D50B2*
+ ID_OUI_FROM_DATABASE=ndb technologies
+
+OUI:70B3D5CB3*
+ ID_OUI_FROM_DATABASE=KST technology
+
+OUI:70B3D530D*
+ ID_OUI_FROM_DATABASE=Fiberbase
+
+OUI:70B3D5842*
+ ID_OUI_FROM_DATABASE=PLUTO Solution co.,ltd.
+
+OUI:70B3D5EB9*
+ ID_OUI_FROM_DATABASE=Thiel Audio Products Company, LLC
+
+OUI:70B3D5031*
+ ID_OUI_FROM_DATABASE=SHENZHEN GAONA ELECTRONIC CO.LTD
+
+OUI:70B3D5548*
+ ID_OUI_FROM_DATABASE=DIGIVERV INC
+
+OUI:70B3D5284*
+ ID_OUI_FROM_DATABASE=Globalcom Engineering SPA
+
+OUI:70B3D5A4E*
+ ID_OUI_FROM_DATABASE=Array Technologies Inc.
+
+OUI:70B3D5580*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D52F2*
+ ID_OUI_FROM_DATABASE=Health Care Originals, Inc.
+
+OUI:70B3D5B98*
+ ID_OUI_FROM_DATABASE=GSF Corporation Pte Ltd
+
+OUI:70B3D5BA9*
+ ID_OUI_FROM_DATABASE=Alma
+
+OUI:70B3D50DE*
+ ID_OUI_FROM_DATABASE=Grossenbacher Systeme AG
+
+OUI:70B3D54B8*
+ ID_OUI_FROM_DATABASE=International Roll-Call Corporation
+
+OUI:70B3D5991*
+ ID_OUI_FROM_DATABASE=Javasparrow Inc.
+
+OUI:70B3D5894*
+ ID_OUI_FROM_DATABASE=UnI Systech Co.,Ltd
+
+OUI:70B3D516B*
+ ID_OUI_FROM_DATABASE=IOT Engineering
+
+OUI:70B3D53AA*
+ ID_OUI_FROM_DATABASE=RCATSONE
+
+OUI:70B3D5432*
+ ID_OUI_FROM_DATABASE=DEUTA-WERKE GmbH
+
+OUI:70B3D5086*
+ ID_OUI_FROM_DATABASE=Husty M.Styczen J.Hupert Sp.J.
+
+OUI:70B3D5E17*
+ ID_OUI_FROM_DATABASE=Private
+
OUI:70B3D5494*
ID_OUI_FROM_DATABASE=Schildknecht AG
OUI:70B3D531E*
ID_OUI_FROM_DATABASE=GILLAM-FEI S.A.
-OUI:70B3D54D5*
- ID_OUI_FROM_DATABASE=Morgan Rekofa GmbH
-
OUI:70B3D58C5*
ID_OUI_FROM_DATABASE=HMicro Inc
OUI:70B3D51FD*
ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
-OUI:70B3D5631*
- ID_OUI_FROM_DATABASE=SENSO2ME
-
OUI:70B3D5396*
ID_OUI_FROM_DATABASE=CTG sp. z o. o.
OUI:70B3D535F*
ID_OUI_FROM_DATABASE=Aplex Technology Inc.
-OUI:70B3D5FFF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:70B3D533E*
ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd.
OUI:70B3D59B2*
ID_OUI_FROM_DATABASE=CONTINENT, Ltd
+OUI:70B3D5365*
+ ID_OUI_FROM_DATABASE=CircuitMeter Inc.
+
+OUI:70B3D5805*
+ ID_OUI_FROM_DATABASE=Eurotronik Kranj d.o.o.
+
+OUI:70B3D5BF6*
+ ID_OUI_FROM_DATABASE=comtac AG
+
+OUI:70B3D50B4*
+ ID_OUI_FROM_DATABASE=AVER
+
+OUI:70B3D51B6*
+ ID_OUI_FROM_DATABASE=DACOM West GmbH
+
+OUI:70B3D59C1*
+ ID_OUI_FROM_DATABASE=Zeroplus Technology Co.,Ltd.
+
+OUI:70B3D5094*
+ ID_OUI_FROM_DATABASE=Circuitlink Pty Ltd
+
+OUI:70B3D5AA3*
+ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD.,
+
+OUI:70B3D5AEF*
+ ID_OUI_FROM_DATABASE=Baumtec GmbH
+
+OUI:70B3D5D92*
+ ID_OUI_FROM_DATABASE=Zamir Recognition Systems Ltd.
+
+OUI:70B3D5DA4*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5CC9*
+ ID_OUI_FROM_DATABASE=Rapiscan Systems
+
+OUI:70B3D52D0*
+ ID_OUI_FROM_DATABASE=ijin co.,ltd.
+
+OUI:70B3D50A0*
+ ID_OUI_FROM_DATABASE=Cominfo, Inc.
+
+OUI:70B3D520F*
+ ID_OUI_FROM_DATABASE=Tieline Research Pty Ltd
+
+OUI:70B3D5C20*
+ ID_OUI_FROM_DATABASE=Mipot S.p.a.
+
+OUI:70B3D54D5*
+ ID_OUI_FROM_DATABASE=Moog Rekofa GmbH
+
+OUI:70B3D5D3C*
+ ID_OUI_FROM_DATABASE=HRT
+
+OUI:70B3D5DDB*
+ ID_OUI_FROM_DATABASE=Intra Corporation
+
+OUI:70B3D58EE*
+ ID_OUI_FROM_DATABASE=Network Additions
+
+OUI:70B3D5445*
+ ID_OUI_FROM_DATABASE=Advanced Devices SpA
+
+OUI:70B3D5674*
+ ID_OUI_FROM_DATABASE=Fortress Cyber Security
+
+OUI:70B3D5FFF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5DB8*
+ ID_OUI_FROM_DATABASE=SISTEM SA
+
+OUI:70B3D5FBC*
+ ID_OUI_FROM_DATABASE=Twoway Communications, Inc.
+
+OUI:70B3D5969*
+ ID_OUI_FROM_DATABASE=Emtel System Sp. z o.o.
+
+OUI:70B3D5C33*
+ ID_OUI_FROM_DATABASE=Dandong Dongfang Measurement & Control Technology Co., Ltd.
+
+OUI:70B3D5B2E*
+ ID_OUI_FROM_DATABASE=Green Access Ltd
+
+OUI:70B3D558C*
+ ID_OUI_FROM_DATABASE=OPTSYS
+
+OUI:70B3D595B*
+ ID_OUI_FROM_DATABASE=SRS Group s.r.o.
+
+OUI:70B3D534E*
+ ID_OUI_FROM_DATABASE=Risk Expert sarl
+
+OUI:70B3D56AD*
+ ID_OUI_FROM_DATABASE=CONNIT
+
+OUI:70B3D5C14*
+ ID_OUI_FROM_DATABASE=Grupo Epelsa S.L.
+
+OUI:70B3D5631*
+ ID_OUI_FROM_DATABASE=SENSO2ME bvba
+
+OUI:70B3D5C53*
+ ID_OUI_FROM_DATABASE=S Labs sp. z o.o.
+
+OUI:70B3D5F24*
+ ID_OUI_FROM_DATABASE=Daavlin
+
+OUI:70B3D56E7*
+ ID_OUI_FROM_DATABASE=AML
+
+OUI:70B3D577B*
+ ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc.
+
+OUI:70B3D504E*
+ ID_OUI_FROM_DATABASE=HUGEL GmbH
+
+OUI:70B3D5319*
+ ID_OUI_FROM_DATABASE=ISO/TC 22/SC 31
+
+OUI:70B3D5844*
+ ID_OUI_FROM_DATABASE=SANSFIL Technologies
+
+OUI:70B3D5826*
+ ID_OUI_FROM_DATABASE=Elbit Systems of Amerixca
+
+OUI:70B3D5C42*
+ ID_OUI_FROM_DATABASE=CRDE
+
+OUI:70B3D5557*
+ ID_OUI_FROM_DATABASE=HEITEC AG
+
+OUI:70B3D568C*
+ ID_OUI_FROM_DATABASE=ND METER
+
+OUI:70B3D5727*
+ ID_OUI_FROM_DATABASE=LP Technologies Inc.
+
+OUI:70B3D549B*
+ ID_OUI_FROM_DATABASE=Algodue Elettronica Srl
+
+OUI:70B3D57F9*
+ ID_OUI_FROM_DATABASE=CSS Inc.
+
+OUI:70B3D592B*
+ ID_OUI_FROM_DATABASE=ENTEC Electric & Electronic Co., LTD.
+
+OUI:70B3D5B13*
+ ID_OUI_FROM_DATABASE=Omwave
+
+OUI:70B3D5EA7*
+ ID_OUI_FROM_DATABASE=S.I.C.E.S. srl
+
OUI:70B3D566B*
ID_OUI_FROM_DATABASE=Innitive B.V.
OUI:70B3D50CD*
ID_OUI_FROM_DATABASE=AML Oceanographic
-OUI:70B3D56E8*
- ID_OUI_FROM_DATABASE=BluWireless Technology Ltd
-
OUI:70B3D56B3*
ID_OUI_FROM_DATABASE=DuraComm Corporation
OUI:70B3D5B81*
ID_OUI_FROM_DATABASE=Instro Precision Limited
-OUI:70B3D5479*
- ID_OUI_FROM_DATABASE=LINEAGE POWER PVT. LTD.
-
OUI:70B3D5A66*
ID_OUI_FROM_DATABASE=Trapeze Software Group Inc
OUI:70B3D517A*
ID_OUI_FROM_DATABASE=Gencoa Ltd
+OUI:70B3D5C49*
+ ID_OUI_FROM_DATABASE=BTG Instruments AB
+
+OUI:70B3D530B*
+ ID_OUI_FROM_DATABASE=Ash Technologies
+
+OUI:70B3D56A6*
+ ID_OUI_FROM_DATABASE=WOW System
+
+OUI:70B3D5FEF*
+ ID_OUI_FROM_DATABASE=HANGZHOU HUALAN MICROELECTRONIQUE CO.,LTD
+
+OUI:70B3D5211*
+ ID_OUI_FROM_DATABASE=Fracarro srl
+
+OUI:70B3D560A*
+ ID_OUI_FROM_DATABASE=TATA POWER SED
+
+OUI:70B3D5129*
+ ID_OUI_FROM_DATABASE=OOO Microlink-Svyaz
+
+OUI:70B3D5479*
+ ID_OUI_FROM_DATABASE=LINEAGE POWER PVT LTD.,
+
+OUI:70B3D564C*
+ ID_OUI_FROM_DATABASE=ACEMIS FRANCE
+
+OUI:70B3D5763*
+ ID_OUI_FROM_DATABASE=A Trap, USA
+
+OUI:70B3D5175*
+ ID_OUI_FROM_DATABASE=Akribis Systems
+
+OUI:70B3D547F*
+ ID_OUI_FROM_DATABASE=ASE GmbH
+
+OUI:70B3D5DC9*
+ ID_OUI_FROM_DATABASE=Sensoterra BV
+
+OUI:70B3D5371*
+ ID_OUI_FROM_DATABASE=BEDEROV GmbH
+
+OUI:70B3D559C*
+ ID_OUI_FROM_DATABASE=DAVE SRL
+
+OUI:70B3D5C79*
+ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme
+
+OUI:70B3D5B04*
+ ID_OUI_FROM_DATABASE=Herrmann Datensysteme GmbH
+
+OUI:70B3D5229*
+ ID_OUI_FROM_DATABASE=CONTROL SYSTEMS Srl
+
+OUI:70B3D555E*
+ ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
+
+OUI:70B3D5EE3*
+ ID_OUI_FROM_DATABASE=Lithe Technology, LLC
+
+OUI:70B3D5D69*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific
+
+OUI:70B3D5FA0*
+ ID_OUI_FROM_DATABASE=TIAMA
+
+OUI:70B3D57DF*
+ ID_OUI_FROM_DATABASE=RDT Ltd
+
+OUI:70B3D508D*
+ ID_OUI_FROM_DATABASE=Clover Electronics Technology Co., Ltd.
+
+OUI:70B3D57D2*
+ ID_OUI_FROM_DATABASE=SDK Kristall
+
+OUI:70B3D5AF0*
+ ID_OUI_FROM_DATABASE=SEASON DESIGN TECHNOLOGY
+
+OUI:70B3D5D6C*
+ ID_OUI_FROM_DATABASE=GP Systems GmbH
+
+OUI:70B3D56AF*
+ ID_OUI_FROM_DATABASE=Sensorberg GmbH
+
+OUI:70B3D518E*
+ ID_OUI_FROM_DATABASE=NIPPON SEIKI CO., LTD.
+
+OUI:70B3D5C0C*
+ ID_OUI_FROM_DATABASE=Tech4Race
+
+OUI:70B3D55D8*
+ ID_OUI_FROM_DATABASE=LYNX Technik AG
+
+OUI:70B3D5374*
+ ID_OUI_FROM_DATABASE=OOO NPP Mars-Energo
+
+OUI:70B3D54A5*
+ ID_OUI_FROM_DATABASE=Intermind Inc.
+
+OUI:70B3D5C1D*
+ ID_OUI_FROM_DATABASE=Kranze Technology Solutions
+
+OUI:70B3D5CC3*
+ ID_OUI_FROM_DATABASE=Fidalia Networks Inc
+
+OUI:70B3D507F*
+ ID_OUI_FROM_DATABASE=Abalance Corporation
+
+OUI:70B3D56E8*
+ ID_OUI_FROM_DATABASE=Blu Wireless Technology Ltd
+
+OUI:70B3D5CD3*
+ ID_OUI_FROM_DATABASE=Controlrad
+
+OUI:70B3D54E5*
+ ID_OUI_FROM_DATABASE=viZaar industrial imaging AG
+
+OUI:70B3D5DE6*
+ ID_OUI_FROM_DATABASE=MB connect line GmbH Fernwartungssysteme
+
OUI:70B3D58AB*
ID_OUI_FROM_DATABASE=EMAC, Inc.
OUI:70B3D5EF9*
ID_OUI_FROM_DATABASE=Critical Link
-OUI:001BC50B2*
- ID_OUI_FROM_DATABASE=SKODA electric a.s.
-
OUI:001BC50B6*
ID_OUI_FROM_DATABASE=Veilux inc.
OUI:70B3D5D55*
ID_OUI_FROM_DATABASE=WM Design s.r.o
-OUI:70B3D5523*
- ID_OUI_FROM_DATABASE=Tibit Communications
-
OUI:70B3D5E67*
ID_OUI_FROM_DATABASE=APPLIED PROCESSING
+OUI:70B3D5523*
+ ID_OUI_FROM_DATABASE=Tibit Communications
+
OUI:70B3D5241*
ID_OUI_FROM_DATABASE=Bolide Technology Group, Inc.
OUI:70B3D5AA6*
ID_OUI_FROM_DATABASE=Proximus
+OUI:70B3D51D4*
+ ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH
+
OUI:70B3D55E5*
ID_OUI_FROM_DATABASE=HAIYANG OLIX CO.,LTD.
OUI:70B3D5E2C*
ID_OUI_FROM_DATABASE=Fourth Frontier Technologies Private Limited
-OUI:70B3D51D4*
- ID_OUI_FROM_DATABASE=Brinkmann Audio GmbH
-
OUI:70B3D55CA*
ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
OUI:70B3D53F0*
ID_OUI_FROM_DATABASE=Intervala
-OUI:70B3D5B1A*
- ID_OUI_FROM_DATABASE=Aaronia AG
-
OUI:70B3D5BD1*
ID_OUI_FROM_DATABASE=CableLabs
+OUI:70B3D5B1A*
+ ID_OUI_FROM_DATABASE=Aaronia AG
+
OUI:70B3D5F0D*
ID_OUI_FROM_DATABASE=MeQ Inc.
OUI:70B3D5C74*
ID_OUI_FROM_DATABASE=Qtechnology A/S
+OUI:70B3D5E16*
+ ID_OUI_FROM_DATABASE=China Entropy Co., Ltd.
+
+OUI:70B3D502E*
+ ID_OUI_FROM_DATABASE=Monnit Corporation
+
+OUI:70B3D5370*
+ ID_OUI_FROM_DATABASE=Inphi Corporation
+
+OUI:70B3D57E8*
+ ID_OUI_FROM_DATABASE=Mannkind Corporation
+
+OUI:70B3D53F3*
+ ID_OUI_FROM_DATABASE=SPEA SPA
+
+OUI:70B3D5549*
+ ID_OUI_FROM_DATABASE=Procon automatic systems GmbH
+
+OUI:70B3D5831*
+ ID_OUI_FROM_DATABASE=Arnouse Digital Devices Corp
+
+OUI:70B3D5D8E*
+ ID_OUI_FROM_DATABASE=Axatel SrL
+
+OUI:70B3D5A28*
+ ID_OUI_FROM_DATABASE=PEEK TRAFFIC
+
+OUI:70B3D5AC7*
+ ID_OUI_FROM_DATABASE=vivaMOS
+
+OUI:70B3D5DB2*
+ ID_OUI_FROM_DATABASE=Micro Electroninc Products
+
+OUI:70B3D5967*
+ ID_OUI_FROM_DATABASE=TATTILE SRL
+
+OUI:70B3D5C16*
+ ID_OUI_FROM_DATABASE=Southern Innovation
+
+OUI:70B3D590F*
+ ID_OUI_FROM_DATABASE=DTRON Communications (Pty) Ltd
+
+OUI:70B3D5E22*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:70B3D5408*
+ ID_OUI_FROM_DATABASE=Comrod AS
+
+OUI:70B3D5945*
+ ID_OUI_FROM_DATABASE=Symboticware Incorporated
+
+OUI:70B3D5D4D*
+ ID_OUI_FROM_DATABASE=The Morey Corporation
+
+OUI:70B3D5192*
+ ID_OUI_FROM_DATABASE=ASPT, INC.
+
+OUI:70B3D5807*
+ ID_OUI_FROM_DATABASE=Camsat Przemysław Gralak
+
+OUI:70B3D5DD1*
+ ID_OUI_FROM_DATABASE=em-tec GmbH
+
+OUI:70B3D5ED1*
+ ID_OUI_FROM_DATABASE=Przemyslowy Instytut Automatyki i Pomiarow
+
+OUI:70B3D514A*
+ ID_OUI_FROM_DATABASE=ExSens Technology (Pty) Ltd.
+
+OUI:70B3D5A69*
+ ID_OUI_FROM_DATABASE=Leviathan Solutions Ltd.
+
+OUI:70B3D5A9A*
+ ID_OUI_FROM_DATABASE=Amphenol Advanced Sensors
+
+OUI:70B3D5715*
+ ID_OUI_FROM_DATABASE=RIOT
+
+OUI:70B3D5FF8*
+ ID_OUI_FROM_DATABASE=Dutile, Glines and Higgins Corporation
+
+OUI:70B3D5413*
+ ID_OUI_FROM_DATABASE=Axess AG
+
+OUI:70B3D5E5E*
+ ID_OUI_FROM_DATABASE=Critical Link LLC
+
+OUI:70B3D5E7D*
+ ID_OUI_FROM_DATABASE=Nanjing Dandick Science&technology development co., LTD
+
+OUI:70B3D5D98*
+ ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
+
+OUI:70B3D5FA6*
+ ID_OUI_FROM_DATABASE=RFL Electronics, Inc.
+
+OUI:70B3D5D43*
+ ID_OUI_FROM_DATABASE=EZSYS Co., Ltd.
+
+OUI:70B3D5A35*
+ ID_OUI_FROM_DATABASE=Sicon srl
+
+OUI:70B3D5359*
+ ID_OUI_FROM_DATABASE=Boutronic
+
+OUI:70B3D5279*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:001BC50B2*
+ ID_OUI_FROM_DATABASE=SKODA ELECTRIC a.s.
+
+OUI:70B3D5035*
+ ID_OUI_FROM_DATABASE=HKW-Elektronik GmbH
+
+OUI:70B3D5DFA*
+ ID_OUI_FROM_DATABASE=Newtouch Electronics (Shanghai) Co.,Ltd.
+
+OUI:70B3D5EC7*
+ ID_OUI_FROM_DATABASE=Neoptix Inc.
+
+OUI:70B3D55B8*
+ ID_OUI_FROM_DATABASE=Hella Gutmann Solutions GmbH
+
+OUI:70B3D5203*
+ ID_OUI_FROM_DATABASE=WOOJIN Inc
+
+OUI:70B3D5845*
+ ID_OUI_FROM_DATABASE=Harborside Technology
+
+OUI:70B3D52F4*
+ ID_OUI_FROM_DATABASE=Radixon s.r.o.
+
OUI:1C8776D*
ID_OUI_FROM_DATABASE=Qivivo
OUI:E818635*
ID_OUI_FROM_DATABASE=WETEK ELECTRONICS LIMITED
-OUI:E818632*
- ID_OUI_FROM_DATABASE=AVCON Information Technology Co.,Ltd
-
OUI:B8D812D*
ID_OUI_FROM_DATABASE=Lam Research
OUI:D0D94F9*
ID_OUI_FROM_DATABASE=Hangzhou xiaoben technology co.,Ltd
-OUI:D0D94F7*
- ID_OUI_FROM_DATABASE=Private
-
OUI:D0D94F0*
ID_OUI_FROM_DATABASE=Perfant Technology Co., Ltd
OUI:CC1BE0F*
ID_OUI_FROM_DATABASE=Private
-OUI:F40E11F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:D07650F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:E81863F*
ID_OUI_FROM_DATABASE=Private
-OUI:F80278F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:9802D8F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:90C682F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:283638D*
ID_OUI_FROM_DATABASE=APPEAK Technology System Co.Ltd.
-OUI:1CCAE3F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836389*
ID_OUI_FROM_DATABASE=Shenzhen Zhi Hua Creative Technology Co., Ltd.
OUI:B0C5CA7*
ID_OUI_FROM_DATABASE=SHENZHEN KTC TECHNOLOGY GROUP
-OUI:283638E*
- ID_OUI_FROM_DATABASE=SCA Hygiene Products AB
-
OUI:F0ACD73*
ID_OUI_FROM_DATABASE=Med-Pat/Inn-Phone
OUI:40F3859*
ID_OUI_FROM_DATABASE=Fast Precision Technologies Co. Ltd.
-OUI:1CA0D32*
- ID_OUI_FROM_DATABASE=NovTech, Inc.
-
OUI:40F3850*
ID_OUI_FROM_DATABASE=SubPac
+OUI:1CA0D32*
+ ID_OUI_FROM_DATABASE=NovTech, Inc.
+
OUI:38FDFEC*
ID_OUI_FROM_DATABASE=New Garden Co., Ltd.
OUI:98AAFCC*
ID_OUI_FROM_DATABASE=dots Inc.
-OUI:08ED026*
- ID_OUI_FROM_DATABASE=SANGO ELECTRONICS CO
-
OUI:08ED023*
ID_OUI_FROM_DATABASE=Jiangsu Logread Network Technology Co., LTD.
+OUI:08ED026*
+ ID_OUI_FROM_DATABASE=SANGO ELECTRONICS CO
+
OUI:08ED024*
ID_OUI_FROM_DATABASE=Fio Corporation
OUI:8C147D0*
ID_OUI_FROM_DATABASE=Nio
+OUI:A0C5F26*
+ ID_OUI_FROM_DATABASE=ShenZhen JuWangShi Tech
+
+OUI:A0C5F22*
+ ID_OUI_FROM_DATABASE=Speedgoat GmbH
+
+OUI:A0C5F24*
+ ID_OUI_FROM_DATABASE=AiCare Corp.
+
+OUI:4C65A8A*
+ ID_OUI_FROM_DATABASE=Suzhou Embedded Electronic Technology Co., Ltd.
+
+OUI:F88A3C8*
+ ID_OUI_FROM_DATABASE=Cadmus Electronic Co.,Ltd.
+
+OUI:7CBACCB*
+ ID_OUI_FROM_DATABASE=Briowireless Inc.
+
+OUI:7CBACC3*
+ ID_OUI_FROM_DATABASE=Izkare
+
+OUI:F40E11F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:78D8001*
+ ID_OUI_FROM_DATABASE=Shenzhen Envicool Information Technology Co., Ltd
+
+OUI:78D8003*
+ ID_OUI_FROM_DATABASE=Shenzhen Scodeno Technology Co,. Ltd.
+
+OUI:78D8007*
+ ID_OUI_FROM_DATABASE=NimbeLink Corp
+
+OUI:78D800A*
+ ID_OUI_FROM_DATABASE=Insignal Co., Ltd.
+
+OUI:78D8008*
+ ID_OUI_FROM_DATABASE=Salunda Ltd
+
+OUI:78D800E*
+ ID_OUI_FROM_DATABASE=CL International
+
+OUI:28F5378*
+ ID_OUI_FROM_DATABASE=1MORE, INC.
+
+OUI:28F5379*
+ ID_OUI_FROM_DATABASE=Herbert Waldmann GmbH & Co. KG
+
+OUI:28F5375*
+ ID_OUI_FROM_DATABASE=Atomrock LLC
+
+OUI:1CCAE3F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:90C682F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:9802D8F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:F80278F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D07650F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F537C*
+ ID_OUI_FROM_DATABASE=Matricx Singapore Pte Ltd
+
+OUI:28F537B*
+ ID_OUI_FROM_DATABASE=LogiM GmbH Software und Entwicklung
+
+OUI:E818632*
+ ID_OUI_FROM_DATABASE=AVCON Information Technology Co.,Ltd
+
+OUI:34298F6*
+ ID_OUI_FROM_DATABASE=Bellman & Symfon
+
+OUI:34298F5*
+ ID_OUI_FROM_DATABASE=Highlite International B.V.
+
+OUI:34298FC*
+ ID_OUI_FROM_DATABASE=Albert Handtmann Maschinenfabrik GmbH&Co.KG
+
+OUI:34298F8*
+ ID_OUI_FROM_DATABASE=Nanjing Sandemarine Electric Co.,Ltd
+
+OUI:189BA5A*
+ ID_OUI_FROM_DATABASE=SHENZHEN FIONEXX TECHNOLOGIES LTD.
+
+OUI:189BA57*
+ ID_OUI_FROM_DATABASE=Beijing Xinertel Technology Co., Ltd.
+
+OUI:904E915*
+ ID_OUI_FROM_DATABASE=mcf88 SRL
+
+OUI:904E917*
+ ID_OUI_FROM_DATABASE=IBM
+
+OUI:904E916*
+ ID_OUI_FROM_DATABASE=Nuwa Robotics (HK) Limited Taiwan Branch
+
+OUI:904E910*
+ ID_OUI_FROM_DATABASE=Spirtech
+
+OUI:2C279ED*
+ ID_OUI_FROM_DATABASE=Jiangsu JianHu Science & Technology Co., Ltd.
+
+OUI:904E91E*
+ ID_OUI_FROM_DATABASE=Shenzhen Cloudynamo Internet Technologies Co.,LTD.
+
+OUI:2C279E0*
+ ID_OUI_FROM_DATABASE=Changzhou WEBO Weighing Device & System CO.,LTD
+
+OUI:904E91D*
+ ID_OUI_FROM_DATABASE=SKODA ELECTRIC a.s.
+
+OUI:2C279EC*
+ ID_OUI_FROM_DATABASE=WAYCOM Technology Co.,Ltd
+
+OUI:283638E*
+ ID_OUI_FROM_DATABASE=SCA Hygiene Products AB
+
+OUI:2C279E2*
+ ID_OUI_FROM_DATABASE=Kunyi electronic technology (Shanghai) Co., Ltd.
+
+OUI:2C279E9*
+ ID_OUI_FROM_DATABASE=octoScope, Inc.
+
+OUI:D0D94F7*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:CC2237C*
+ ID_OUI_FROM_DATABASE=Hebei ZHSF Technology Co.,Ltd.
+
+OUI:CC2237A*
+ ID_OUI_FROM_DATABASE=shenzhen zonglian network technology limited
+
+OUI:CC22375*
+ ID_OUI_FROM_DATABASE=Beijing Safesoft Greatmaker Co.,ltd
+
+OUI:CC22378*
+ ID_OUI_FROM_DATABASE=Safilo S.p.A.
+
+OUI:741AE00*
+ ID_OUI_FROM_DATABASE=Huano International Technology Limited
+
+OUI:741AE07*
+ ID_OUI_FROM_DATABASE=BÄR Bahnsicherung AG
+
+OUI:741AE01*
+ ID_OUI_FROM_DATABASE=Socionext Inc.
+
+OUI:741AE0A*
+ ID_OUI_FROM_DATABASE=SAIERCOM CORPORATION
+
OUI:1C8776C*
ID_OUI_FROM_DATABASE=Strone Technology
OUI:CC1BE07*
ID_OUI_FROM_DATABASE=Sichuan Dianjia network technology Co.Ltd.
-OUI:CC1BE00*
- ID_OUI_FROM_DATABASE=MICROTECH SYSTEM
-
OUI:DC44270*
ID_OUI_FROM_DATABASE=Suritel
OUI:C0D3912*
ID_OUI_FROM_DATABASE=Hofon Automation Co.,Ltd
-OUI:C0D391B*
- ID_OUI_FROM_DATABASE=Private
-
OUI:84E0F40*
ID_OUI_FROM_DATABASE=ShenZhen Panrich Technology Limited
OUI:100723F*
ID_OUI_FROM_DATABASE=Private
-OUI:B0C5CAF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836383*
ID_OUI_FROM_DATABASE=Sabinetek
OUI:8C192D7*
ID_OUI_FROM_DATABASE=SRETT
-OUI:7C70BCF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A43BFAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:B01F81F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0055DAF*
ID_OUI_FROM_DATABASE=Private
OUI:1CA0D35*
ID_OUI_FROM_DATABASE=Dynamic Connect (Suzhou) Hi-Tech Electronic Co.,Ltd.
-OUI:1CA0D33*
- ID_OUI_FROM_DATABASE=SAVELEC
-
OUI:1CA0D37*
ID_OUI_FROM_DATABASE=Private
OUI:A411634*
ID_OUI_FROM_DATABASE=AlterG, Inc.
+OUI:1CA0D33*
+ ID_OUI_FROM_DATABASE=SAVELEC
+
OUI:A411631*
ID_OUI_FROM_DATABASE=INTER CONTROL Hermann Köhler Elektrik GmbH & Co.KG
OUI:04714B1*
ID_OUI_FROM_DATABASE=uAvionix Corporation
-OUI:04714B2*
- ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
-
OUI:04714B8*
ID_OUI_FROM_DATABASE=Energport Inc
-OUI:8C147D5*
- ID_OUI_FROM_DATABASE=Unwired Networks
-
OUI:F023B94*
ID_OUI_FROM_DATABASE=EZVIS LIMITED
OUI:F023B9A*
ID_OUI_FROM_DATABASE=annapurnalabs
+OUI:8C147D5*
+ ID_OUI_FROM_DATABASE=Unwired Networks
+
OUI:8C147D2*
ID_OUI_FROM_DATABASE=Agilent S.p.A
+OUI:8C147DE*
+ ID_OUI_FROM_DATABASE=Electrical & Automation Larsen & Toubro Limited
+
+OUI:A0C5F29*
+ ID_OUI_FROM_DATABASE=Impulse Networks Pte Ltd
+
+OUI:A0C5F2B*
+ ID_OUI_FROM_DATABASE=Oray.com co., LTD.
+
+OUI:4C65A89*
+ ID_OUI_FROM_DATABASE=SHENZHEN LISAIER TRONICS CO.,LTD
+
+OUI:4C65A86*
+ ID_OUI_FROM_DATABASE=Nuviz Oy
+
+OUI:A0C5F23*
+ ID_OUI_FROM_DATABASE=Shenzhen Feima Robotics Technology Co.,Ltd
+
+OUI:7C70BCF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B01F81F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CBACC5*
+ ID_OUI_FROM_DATABASE=Fortem Technologies, Inc.
+
+OUI:78D8006*
+ ID_OUI_FROM_DATABASE=Alango Technologies Ltd
+
+OUI:78D800C*
+ ID_OUI_FROM_DATABASE=Shenzhen Chenzhuo Technology Co., Ltd.
+
+OUI:28F5374*
+ ID_OUI_FROM_DATABASE=Phyn LLC
+
+OUI:A43BFAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F5376*
+ ID_OUI_FROM_DATABASE=MyOmega Systems GmbH
+
+OUI:28F5377*
+ ID_OUI_FROM_DATABASE=Shenzhen Modern Cowboy Technology Co.,Ltd.
+
+OUI:28F537A*
+ ID_OUI_FROM_DATABASE=Honeywell Safety Products USA, Inc
+
+OUI:B0C5CAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34008A4*
+ ID_OUI_FROM_DATABASE=Fotonic i Norden AB
+
+OUI:34008A7*
+ ID_OUI_FROM_DATABASE=uberGARD Pte. Ltd.
+
+OUI:34008A8*
+ ID_OUI_FROM_DATABASE=Shenzhen Andakai Technologies Co., Ltd.
+
+OUI:34008A0*
+ ID_OUI_FROM_DATABASE=Angee Technologies Ltd.
+
+OUI:34008AC*
+ ID_OUI_FROM_DATABASE=Shenzhen Eternal Idea Tech Co.,Ltd
+
+OUI:34298F0*
+ ID_OUI_FROM_DATABASE=BlackEdge Capital
+
+OUI:34298F1*
+ ID_OUI_FROM_DATABASE=Chengdu Meross Technology Co., Ltd.
+
+OUI:CC1BE00*
+ ID_OUI_FROM_DATABASE=Microtech System,Inc
+
+OUI:189BA56*
+ ID_OUI_FROM_DATABASE=Mantra Softech India Pvt Ltd
+
+OUI:189BA52*
+ ID_OUI_FROM_DATABASE=Airprotec
+
+OUI:189BA50*
+ ID_OUI_FROM_DATABASE=Dectris Ltd.
+
+OUI:189BA5B*
+ ID_OUI_FROM_DATABASE=Eutron SPA
+
+OUI:189BA58*
+ ID_OUI_FROM_DATABASE=Shenzhen Tong Tai Yi information Technology Co.,Ltd
+
+OUI:C0D391B*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:904E918*
+ ID_OUI_FROM_DATABASE=CommandScape, Inc.
+
+OUI:2C279E6*
+ ID_OUI_FROM_DATABASE=Rutledge Omni Services Pte Ltd
+
+OUI:CC22372*
+ ID_OUI_FROM_DATABASE=Apeiron Data Systems
+
+OUI:04714B2*
+ ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
+
+OUI:741AE04*
+ ID_OUI_FROM_DATABASE=Revl Inc.
+
+OUI:741AE09*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:741AE0B*
+ ID_OUI_FROM_DATABASE=SHEN ZHEN YINGJIACHUANG ELECTRONICS TECHNOLOGY CO.,LTD.
+
+OUI:741AE05*
+ ID_OUI_FROM_DATABASE=FUJIAN TAILI COMMUNICATION TECHNOLOGY CO.,LTD
+
+OUI:741AE0C*
+ ID_OUI_FROM_DATABASE=bistos.co.ltd
+
OUI:1C87765*
ID_OUI_FROM_DATABASE=Zhuhai MYZR Technology Co.,Ltd
OUI:F80278D*
ID_OUI_FROM_DATABASE=Dueton Systems s.r.o.
-OUI:0CEFAFB*
- ID_OUI_FROM_DATABASE=Hubei Century Network Technology Co .Ltd
-
OUI:A44F291*
ID_OUI_FROM_DATABASE=Olssen B.V.
OUI:8C192D9*
ID_OUI_FROM_DATABASE=ViaWear, Inc.
-OUI:BC3400F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:7419F8F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:1C21D1F*
ID_OUI_FROM_DATABASE=Private
-OUI:DC4427F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:C88ED1F*
ID_OUI_FROM_DATABASE=Private
-OUI:80E4DAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:885D90F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836385*
ID_OUI_FROM_DATABASE=CHARGELIB
OUI:1CA0D3D*
ID_OUI_FROM_DATABASE=ERATO (HK) Corporation Limited
-OUI:1CA0D3A*
- ID_OUI_FROM_DATABASE=DSM Messtechnik GmbH
-
OUI:1CA0D38*
ID_OUI_FROM_DATABASE=Desarrollos y Soluciones Guinea I+D S.L.
+OUI:1CA0D3A*
+ ID_OUI_FROM_DATABASE=DSM Messtechnik GmbH
+
OUI:A411638*
ID_OUI_FROM_DATABASE=Dspread Technology (Beijing) Inc.
OUI:A41163A*
ID_OUI_FROM_DATABASE=ISE GmbH
-OUI:A411635*
- ID_OUI_FROM_DATABASE=Carbon, Inc.
-
OUI:4CE1731*
ID_OUI_FROM_DATABASE=Nexoforge Inc.
+OUI:A411635*
+ ID_OUI_FROM_DATABASE=Carbon, Inc.
+
OUI:144FD70*
ID_OUI_FROM_DATABASE=annapurnalabs
OUI:F023B91*
ID_OUI_FROM_DATABASE=Ubiant
+OUI:8C147D7*
+ ID_OUI_FROM_DATABASE=UrbanHello
+
+OUI:8C147D9*
+ ID_OUI_FROM_DATABASE=Anyware Solutions ApS
+
+OUI:A0C5F27*
+ ID_OUI_FROM_DATABASE=Viettronimex JSC
+
+OUI:A0C5F25*
+ ID_OUI_FROM_DATABASE=Tango Wave
+
+OUI:A0C5F2C*
+ ID_OUI_FROM_DATABASE=Glooko inc
+
+OUI:4C65A83*
+ ID_OUI_FROM_DATABASE=Roost
+
+OUI:4C65A8D*
+ ID_OUI_FROM_DATABASE=Qingping Technology (Beijing) Co., Ltd.
+
+OUI:F88A3C4*
+ ID_OUI_FROM_DATABASE=GO-LINK TECHNOLOGY CO., LTD.
+
+OUI:F88A3C0*
+ ID_OUI_FROM_DATABASE=ART SPA
+
+OUI:F88A3CE*
+ ID_OUI_FROM_DATABASE=Avateq Corp.
+
+OUI:F88A3CA*
+ ID_OUI_FROM_DATABASE=Protos GmbH
+
+OUI:7CBACC0*
+ ID_OUI_FROM_DATABASE=TGT Limited
+
+OUI:7CBACCA*
+ ID_OUI_FROM_DATABASE=annapurnalabs
+
+OUI:7CBACC4*
+ ID_OUI_FROM_DATABASE=Sun Asia Trade Co.
+
+OUI:885D90F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:BC3400F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F537D*
+ ID_OUI_FROM_DATABASE=Skyrockettoys LLC
+
+OUI:7419F8F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:80E4DAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F5373*
+ ID_OUI_FROM_DATABASE=PRIMETECH ENGINEERING CORP.
+
+OUI:34008A2*
+ ID_OUI_FROM_DATABASE=RPE Monitor
+
+OUI:0CEFAFB*
+ ID_OUI_FROM_DATABASE=Hubei Century Network Technology Co., Ltd
+
+OUI:34008AB*
+ ID_OUI_FROM_DATABASE=Project Engineering srl
+
+OUI:34298FA*
+ ID_OUI_FROM_DATABASE=Virtual Trunk Pte Ltd
+
+OUI:DC4427F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:189BA5C*
+ ID_OUI_FROM_DATABASE=Christ Electronic System GmbH
+
+OUI:189BA59*
+ ID_OUI_FROM_DATABASE=APANA Inc.
+
+OUI:189BA51*
+ ID_OUI_FROM_DATABASE=ChengDu Vantron Technology, Ltd.
+
+OUI:189BA5D*
+ ID_OUI_FROM_DATABASE=legendsky tech
+
+OUI:904E911*
+ ID_OUI_FROM_DATABASE=Apollo Video Technology
+
+OUI:904E91B*
+ ID_OUI_FROM_DATABASE=Shanghai JaWay Information Technology Co., Ltd.
+
+OUI:904E912*
+ ID_OUI_FROM_DATABASE=North Pole Engineering, Inc.
+
+OUI:2C279E3*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2C279EA*
+ ID_OUI_FROM_DATABASE=Exegy Inc
+
+OUI:2C279E1*
+ ID_OUI_FROM_DATABASE=Electronique Bluewave Inc.
+
+OUI:2C279E8*
+ ID_OUI_FROM_DATABASE=Institut Dr. Foerster GmbH & Co. KG
+
+OUI:CC2237D*
+ ID_OUI_FROM_DATABASE=SHENZHEN HOOENERGY TECHNOLOGY CO.,LTD
+
+OUI:CC22371*
+ ID_OUI_FROM_DATABASE=Terma Sp. z o.o.
+
+OUI:CC2237B*
+ ID_OUI_FROM_DATABASE=Tolomatic, Inc.
+
+OUI:AC1DDF6*
+ ID_OUI_FROM_DATABASE=Shenzheng SenseTime Technology Co. Ltd
+
+OUI:741AE02*
+ ID_OUI_FROM_DATABASE=NURA HOLDINGS PTY LTD
+
OUI:1C8776B*
ID_OUI_FROM_DATABASE=Hekatron Vertriebs GmbH
OUI:38B8EBA*
ID_OUI_FROM_DATABASE=SECAD SA
-OUI:38B8EB7*
- ID_OUI_FROM_DATABASE=Private
-
OUI:38FDFE6*
ID_OUI_FROM_DATABASE=Inspero Inc
OUI:F0ACD7E*
ID_OUI_FROM_DATABASE=Fiziico Co., Ltd.
-OUI:58E8760*
- ID_OUI_FROM_DATABASE=Private
-
OUI:58E8761*
ID_OUI_FROM_DATABASE=Beijing Perabytes IS Technology Co., Ltd
OUI:A03E6BF*
ID_OUI_FROM_DATABASE=Private
-OUI:58FCDBF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:283638C*
ID_OUI_FROM_DATABASE=Swisson AG
-OUI:E4956EF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:74F8DBF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:BC6641F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:74E14AF*
ID_OUI_FROM_DATABASE=Private
OUI:B8D812F*
ID_OUI_FROM_DATABASE=Private
-OUI:2C265FF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2C6A6FF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:64FB81F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:28FD80F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:A0BB3EF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:2CD141F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836388*
ID_OUI_FROM_DATABASE=Havells India Limited
OUI:8C147D1*
ID_OUI_FROM_DATABASE=Private
+OUI:8C147DB*
+ ID_OUI_FROM_DATABASE=Bausch Datacom NV/SA
+
+OUI:A0C5F2D*
+ ID_OUI_FROM_DATABASE=UnaliWear, Inc.
+
+OUI:A0C5F20*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A0C5F2E*
+ ID_OUI_FROM_DATABASE=Synapsys Solutions Ltd.
+
+OUI:4C65A88*
+ ID_OUI_FROM_DATABASE=Instant Byte, S.L.
+
+OUI:4C65A82*
+ ID_OUI_FROM_DATABASE=Orica Europe Pty Ltd & Co KG
+
+OUI:4C65A84*
+ ID_OUI_FROM_DATABASE=Plus One Japan Limited
+
+OUI:4C65A8C*
+ ID_OUI_FROM_DATABASE=Fuse
+
+OUI:F88A3C7*
+ ID_OUI_FROM_DATABASE=Josh.ai
+
+OUI:F88A3C1*
+ ID_OUI_FROM_DATABASE=Carefree of Colorado
+
+OUI:F88A3C5*
+ ID_OUI_FROM_DATABASE=KOKKIA INC
+
+OUI:F88A3C9*
+ ID_OUI_FROM_DATABASE=withus
+
+OUI:7CBACCC*
+ ID_OUI_FROM_DATABASE=Flying Loft Inc.
+
+OUI:7CBACCD*
+ ID_OUI_FROM_DATABASE=SIGMA-ELEKTRO GmbH
+
+OUI:7CBACC2*
+ ID_OUI_FROM_DATABASE=Maco Lighting Pty. Ltd.
+
+OUI:7CBACC9*
+ ID_OUI_FROM_DATABASE=Yongguan Electronic Technology (D.G)LTD
+
+OUI:74F8DBF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CBACCE*
+ ID_OUI_FROM_DATABASE=ALPHA TECHNOLOGIES, LLC
+
+OUI:78D8009*
+ ID_OUI_FROM_DATABASE=SightLine Applications
+
+OUI:78D8005*
+ ID_OUI_FROM_DATABASE=Björkviks Consulting AB
+
+OUI:78D8002*
+ ID_OUI_FROM_DATABASE=Shanghai Espacetime Technology Co.,Ltd.
+
+OUI:28F5372*
+ ID_OUI_FROM_DATABASE=Unicair Communication Tec Co., Ltd.
+
+OUI:78D8000*
+ ID_OUI_FROM_DATABASE=Kverneland Group Mechatronics
+
+OUI:28F5371*
+ ID_OUI_FROM_DATABASE=Umojo
+
+OUI:64FB81F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:58FCDBF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2C265FF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28FD80F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2CD141F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2C6A6FF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A0BB3EF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:BC6641F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34008AA*
+ ID_OUI_FROM_DATABASE=Hibertek International Limited
+
+OUI:34008A6*
+ ID_OUI_FROM_DATABASE=Sithon Technologies SAS
+
+OUI:34298FD*
+ ID_OUI_FROM_DATABASE=Keystone Electronic Solutions
+
+OUI:34298F7*
+ ID_OUI_FROM_DATABASE=Dongguan Kingtron Electronics Tech Co., Ltd
+
+OUI:58E8760*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34298FE*
+ ID_OUI_FROM_DATABASE=ARC Technology Co., Ltd
+
+OUI:189BA53*
+ ID_OUI_FROM_DATABASE=PHINETWORKS
+
+OUI:189BA55*
+ ID_OUI_FROM_DATABASE=Starfire Industries LLC
+
+OUI:E4956EF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:189BA5E*
+ ID_OUI_FROM_DATABASE=Taiwan Name Plate Co.,LTD
+
+OUI:904E914*
+ ID_OUI_FROM_DATABASE=Wrtnode technology Inc.
+
+OUI:2C279E4*
+ ID_OUI_FROM_DATABASE=Shijiazhuang King Transportation Equipment Co.,Ltd
+
+OUI:2C279E5*
+ ID_OUI_FROM_DATABASE=AudioNord Distribution A/S
+
+OUI:38B8EB7*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:CC22377*
+ ID_OUI_FROM_DATABASE=Shanghai Doit IOT Technology Co.,Ltd.
+
+OUI:34298FB*
+ ID_OUI_FROM_DATABASE=Schnick-Schnack-Systems GmbH
+
+OUI:741AE0D*
+ ID_OUI_FROM_DATABASE=Voltaware Services Limited
+
+OUI:741AE0E*
+ ID_OUI_FROM_DATABASE=ITS Partner (O.B.S) S.L.
+
+OUI:AC1DDF5*
+ ID_OUI_FROM_DATABASE=Shenzhen Ouzheng Electronic Tech Co,.Ltd
+
OUI:1C87740*
ID_OUI_FROM_DATABASE=Philips Personal Health Solutions
OUI:7C477CD*
ID_OUI_FROM_DATABASE=Speedifi Inc
-OUI:986D359*
- ID_OUI_FROM_DATABASE=Private
-
OUI:986D353*
ID_OUI_FROM_DATABASE=DH Mechatronic AG
OUI:800A80F*
ID_OUI_FROM_DATABASE=Private
-OUI:B437D1F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:0CEFAFF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:78C2C0F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:141FBAF*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:549A11F*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:807B85F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:2836386*
ID_OUI_FROM_DATABASE=Georg Neumann GmbH
OUI:8C147D4*
ID_OUI_FROM_DATABASE=Nanjing bilian information Technology Co.,Ltd.
+OUI:8C147D6*
+ ID_OUI_FROM_DATABASE=Shenzhen Meidou Technology Co, Ltd.
+
+OUI:8C147D8*
+ ID_OUI_FROM_DATABASE=V2 S.p.A.
+
+OUI:A0C5F28*
+ ID_OUI_FROM_DATABASE=CoolR Group Inc
+
+OUI:A0C5F2A*
+ ID_OUI_FROM_DATABASE=Serious Integrated, Inc.
+
+OUI:A0C5F21*
+ ID_OUI_FROM_DATABASE=KNS Group LLC (YADRO Company)
+
+OUI:4C65A81*
+ ID_OUI_FROM_DATABASE=Beijing Bluehalo Internet Inc.
+
+OUI:4C65A80*
+ ID_OUI_FROM_DATABASE=WELT Corporation
+
+OUI:4C65A87*
+ ID_OUI_FROM_DATABASE=Wuhan MoreQuick Network Technology Co., Ltd.
+
+OUI:4C65A85*
+ ID_OUI_FROM_DATABASE=TEL-Electronics Ltd
+
+OUI:4C65A8B*
+ ID_OUI_FROM_DATABASE=ZMIN Technologies
+
+OUI:F88A3CC*
+ ID_OUI_FROM_DATABASE=EXCETOP TECHNOLOGY (BEIJING) CO., LTD.
+
+OUI:F88A3C3*
+ ID_OUI_FROM_DATABASE=Shenzhen Shengyuan Tech Ltd.
+
+OUI:F88A3C6*
+ ID_OUI_FROM_DATABASE=Beijing Zhong Chuang Communication Technology Ltd.
+
+OUI:4C65A8E*
+ ID_OUI_FROM_DATABASE=High Infinity Germany
+
+OUI:F88A3C2*
+ ID_OUI_FROM_DATABASE=KLATU Networks Inc
+
+OUI:F88A3CD*
+ ID_OUI_FROM_DATABASE=THK Co.,LTD.
+
+OUI:F88A3CB*
+ ID_OUI_FROM_DATABASE=FARA AS
+
+OUI:7CBACC7*
+ ID_OUI_FROM_DATABASE=Virgin Orbit
+
+OUI:7CBACC1*
+ ID_OUI_FROM_DATABASE=Changsha SUNYE Electric Co., Ltd.
+
+OUI:807B85F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:549A11F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:141FBAF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B437D1F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:7CBACC8*
+ ID_OUI_FROM_DATABASE=Collinear Networks Inc.
+
+OUI:7CBACC6*
+ ID_OUI_FROM_DATABASE=Fossil Power Systems Inc
+
+OUI:78D8004*
+ ID_OUI_FROM_DATABASE=CS Instruments GmbH
+
+OUI:78D800D*
+ ID_OUI_FROM_DATABASE=Korea Micro Wireless Co.,Ltd.
+
+OUI:78D800B*
+ ID_OUI_FROM_DATABASE=Maddalena S.p.A.
+
+OUI:28F5370*
+ ID_OUI_FROM_DATABASE=Valeo Siemens eAutomotive Norway
+
+OUI:78C2C0F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:0CEFAFF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:28F537E*
+ ID_OUI_FROM_DATABASE=Performance Motion Devices
+
+OUI:34008A9*
+ ID_OUI_FROM_DATABASE=Keruyun Technoligies(Beijing) Corporation Limited
+
+OUI:986D359*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:34008A3*
+ ID_OUI_FROM_DATABASE=Globex 99 LTD
+
+OUI:34008AD*
+ ID_OUI_FROM_DATABASE=ChengDu HuiZhong Cloud Information Technology Co., Ltd.
+
+OUI:34008A1*
+ ID_OUI_FROM_DATABASE=ZQAM Communications
+
+OUI:34008A5*
+ ID_OUI_FROM_DATABASE=Federal Aviation Administration
+
+OUI:34298F2*
+ ID_OUI_FROM_DATABASE=Shenzhen Advance River System Technology Co., Ltd
+
+OUI:34008AE*
+ ID_OUI_FROM_DATABASE=SHENZHEN WXL ELECTRONICS CO., LTD.
+
+OUI:34298F9*
+ ID_OUI_FROM_DATABASE=Wiesheu GmbH
+
+OUI:34298F3*
+ ID_OUI_FROM_DATABASE=Beijing Vorx Telecommunications Co., Ltd.
+
+OUI:34298F4*
+ ID_OUI_FROM_DATABASE=ISRA Vision AG
+
+OUI:189BA54*
+ ID_OUI_FROM_DATABASE=Innominds Software Inc
+
+OUI:904E91C*
+ ID_OUI_FROM_DATABASE=Showtacle s.r.o.
+
+OUI:904E913*
+ ID_OUI_FROM_DATABASE=Teleepoch Ltd
+
+OUI:904E91A*
+ ID_OUI_FROM_DATABASE=Kaertech Limited
+
+OUI:904E919*
+ ID_OUI_FROM_DATABASE=CUTTER Systems spol. s r.o.
+
+OUI:2C279EE*
+ ID_OUI_FROM_DATABASE=Amaryllo International Inc.
+
+OUI:CC22374*
+ ID_OUI_FROM_DATABASE=SHANGHAI CARGOA M.&E.EQUIPMENT CO.LTD
+
+OUI:CC22376*
+ ID_OUI_FROM_DATABASE=Siemens AG Austria
+
+OUI:CC22370*
+ ID_OUI_FROM_DATABASE=MEDCOM sp. z o.o.
+
+OUI:CC22379*
+ ID_OUI_FROM_DATABASE=E Ink Corp
+
+OUI:CC22373*
+ ID_OUI_FROM_DATABASE=XConnect Professional Services
+
+OUI:CC2237E*
+ ID_OUI_FROM_DATABASE=MANUFACTURAS Y TRANSFORMADOS AB, S.L.
+
+OUI:741AE08*
+ ID_OUI_FROM_DATABASE=Broadcast Wireless Systems Ltd
+
+OUI:741AE06*
+ ID_OUI_FROM_DATABASE=Blocks Wearables Inc.
+
+OUI:741AE03*
+ ID_OUI_FROM_DATABASE=Philips Personal Health Solutions
+
OUI:E043DB*
ID_OUI_FROM_DATABASE=Shenzhen ViewAt Technology Co.,Ltd.
OUI:2405F5*
ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
-OUI:2C3033*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:3CD92B*
ID_OUI_FROM_DATABASE=Hewlett Packard
OUI:BCEC23*
ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
-OUI:8CE748*
- ID_OUI_FROM_DATABASE=Private
-
OUI:AC06C7*
ID_OUI_FROM_DATABASE=ServerNet S.r.l.
OUI:0007D8*
ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
-OUI:0012F2*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:001BED*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:002438*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:84742A*
ID_OUI_FROM_DATABASE=zte corporation
OUI:D848EE*
ID_OUI_FROM_DATABASE=Hangzhou Xueji Technology Co., Ltd.
-OUI:88947E*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:88C242*
ID_OUI_FROM_DATABASE=Poynt Co.
OUI:C49FF3*
ID_OUI_FROM_DATABASE=Mciao Technologies, Inc.
-OUI:80739F*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:7C2BE1*
ID_OUI_FROM_DATABASE=Shenzhen Ferex Electrical Co.,Ltd
OUI:FC335F*
ID_OUI_FROM_DATABASE=Polyera
-OUI:FCC233*
- ID_OUI_FROM_DATABASE=Private
-
OUI:A8C87F*
ID_OUI_FROM_DATABASE=Roqos, Inc.
OUI:3C3178*
ID_OUI_FROM_DATABASE=Qolsys Inc.
-OUI:F4573E*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:083A5C*
ID_OUI_FROM_DATABASE=Junilab, Inc.
OUI:082CB0*
ID_OUI_FROM_DATABASE=Network Instruments
-OUI:F0AB54*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
-
OUI:485073*
ID_OUI_FROM_DATABASE=Microsoft Corporation
OUI:3CA31A*
ID_OUI_FROM_DATABASE=Oilfind International LLC
-OUI:ACFD93*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-
OUI:A424DD*
ID_OUI_FROM_DATABASE=Cambrionix Ltd
OUI:60E6BC*
ID_OUI_FROM_DATABASE=Sino-Telecom Technology Co.,Ltd.
-OUI:1CA532*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:486EFB*
ID_OUI_FROM_DATABASE=Davit System Technology Co., Ltd.
OUI:F8E903*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:F0B052*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:6828F6*
ID_OUI_FROM_DATABASE=Vubiq Networks, Inc.
OUI:34F0CA*
ID_OUI_FROM_DATABASE=Shenzhen Linghangyuan Digital Technology Co.,Ltd.
-OUI:84183A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:30B5F1*
ID_OUI_FROM_DATABASE=Aitexin Technology Co., Ltd
OUI:20A787*
ID_OUI_FROM_DATABASE=Bointec Taiwan Corporation Limited
-OUI:6CAAB3*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:A481EE*
ID_OUI_FROM_DATABASE=Nokia Corporation
OUI:4C7F62*
ID_OUI_FROM_DATABASE=Nokia Corporation
-OUI:841766*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd
-
OUI:F03FF8*
ID_OUI_FROM_DATABASE=R L Drake
OUI:1C7B21*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
-OUI:BC9680*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:9C2840*
ID_OUI_FROM_DATABASE=Discovery Technology,LTD..
OUI:E8D4E0*
ID_OUI_FROM_DATABASE=Beijing BenyWave Technology Co., Ltd.
-OUI:3889DC*
- ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V.
-
OUI:681D64*
ID_OUI_FROM_DATABASE=Sunwave Communications Co., Ltd
OUI:E438F2*
ID_OUI_FROM_DATABASE=Advantage Controls
-OUI:24C9A1*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:C8F386*
ID_OUI_FROM_DATABASE=Shenzhen Xiaoniao Technology Co.,Ltd
OUI:C4393A*
ID_OUI_FROM_DATABASE=SMC Networks Inc
-OUI:C4017C*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D45C70*
ID_OUI_FROM_DATABASE=Wi-Fi Alliance
OUI:142DF5*
ID_OUI_FROM_DATABASE=Amphitech
-OUI:C08ADE*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:90F72F*
ID_OUI_FROM_DATABASE=Phillips Machine & Welding Co., Inc.
OUI:0C130B*
ID_OUI_FROM_DATABASE=Uniqoteq Ltd.
-OUI:14CF8D*
- ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO., LTD.
-
OUI:808698*
ID_OUI_FROM_DATABASE=Netronics Technologies Inc.
OUI:4C32D9*
ID_OUI_FROM_DATABASE=M Rutty Holdings Pty. Ltd.
-OUI:50A733*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:603FC5*
ID_OUI_FROM_DATABASE=COX CO., LTD
OUI:BC8199*
ID_OUI_FROM_DATABASE=BASIC Co.,Ltd.
-OUI:000726*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co., Ltd.
-
OUI:24470E*
ID_OUI_FROM_DATABASE=PentronicAB
OUI:CCBE71*
ID_OUI_FROM_DATABASE=OptiLogix BV
-OUI:D8B12A*
- ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd.
-
OUI:7CDD90*
ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co., Ltd.
OUI:A45055*
ID_OUI_FROM_DATABASE=busware.de
-OUI:2CD2E7*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:C89383*
ID_OUI_FROM_DATABASE=Embedded Automation, Inc.
OUI:0025E9*
ID_OUI_FROM_DATABASE=i-mate Development, Inc.
-OUI:0025DF*
- ID_OUI_FROM_DATABASE=Private
-
OUI:002690*
ID_OUI_FROM_DATABASE=I DO IT
OUI:002299*
ID_OUI_FROM_DATABASE=SeaMicro Inc.
-OUI:002294*
- ID_OUI_FROM_DATABASE=Kyocera Corporation
-
OUI:0021FA*
ID_OUI_FROM_DATABASE=A4SP Technologies Ltd.
OUI:001F42*
ID_OUI_FROM_DATABASE=Etherstack plc
-OUI:001F41*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:001F39*
ID_OUI_FROM_DATABASE=Construcciones y Auxiliar de Ferrocarriles, S.A.
OUI:001884*
ID_OUI_FROM_DATABASE=Fon Technology S.L.
-OUI:00187D*
- ID_OUI_FROM_DATABASE=Armorlink shanghai Co. Ltd
-
OUI:00187F*
ID_OUI_FROM_DATABASE=ZODIANET
OUI:0016A6*
ID_OUI_FROM_DATABASE=Dovado FZ-LLC
-OUI:0017C8*
- ID_OUI_FROM_DATABASE=KYOCERA Document Solutions Inc.
-
OUI:0017CF*
ID_OUI_FROM_DATABASE=iMCA-GmbH
OUI:001751*
ID_OUI_FROM_DATABASE=Online Corporation
-OUI:001753*
- ID_OUI_FROM_DATABASE=nFore Technology Inc.
-
OUI:001758*
ID_OUI_FROM_DATABASE=ThruVision Ltd
OUI:001538*
ID_OUI_FROM_DATABASE=RFID, Inc.
-OUI:00152A*
- ID_OUI_FROM_DATABASE=Nokia GmbH
-
OUI:00161D*
ID_OUI_FROM_DATABASE=Innovative Wireless Technologies, Inc.
OUI:00112D*
ID_OUI_FROM_DATABASE=iPulse Systems
-OUI:111111*
- ID_OUI_FROM_DATABASE=Private
-
OUI:001123*
ID_OUI_FROM_DATABASE=Appointech, Inc.
OUI:0004CB*
ID_OUI_FROM_DATABASE=Tdsoft Communication, Ltd.
-OUI:0004BF*
- ID_OUI_FROM_DATABASE=VersaLogic Corp.
-
OUI:0004C5*
ID_OUI_FROM_DATABASE=ASE Technologies, USA
OUI:000166*
ID_OUI_FROM_DATABASE=TC GROUP A/S
-OUI:00016D*
- ID_OUI_FROM_DATABASE=CarrierComm Inc.
-
OUI:00015F*
ID_OUI_FROM_DATABASE=DIGITAL DESIGN GmbH
OUI:080072*
ID_OUI_FROM_DATABASE=XEROX CORP UNIV GRANT PROGRAM
-OUI:080070*
- ID_OUI_FROM_DATABASE=MITSUBISHI ELECTRIC CORP.
-
OUI:080068*
ID_OUI_FROM_DATABASE=RIDGE COMPUTERS
OUI:00003B*
ID_OUI_FROM_DATABASE=i Controls, Inc.
-OUI:0000FE*
- ID_OUI_FROM_DATABASE=ANNAPOLIS MICRO SYSTEMS
-
OUI:080013*
ID_OUI_FROM_DATABASE=Exxon
OUI:E8BE81*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:28FAA0*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:3CA348*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:F42981*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:C4282D*
ID_OUI_FROM_DATABASE=Embedded Intellect Pty Ltd
OUI:541473*
ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited
-OUI:14144B*
- ID_OUI_FROM_DATABASE=FUJIAN STAR-NET COMMUNICATION CO.,LTD
-
OUI:001C50*
ID_OUI_FROM_DATABASE=TCL Technoly Electronics (Huizhou) Co., Ltd.
OUI:00138F*
ID_OUI_FROM_DATABASE=Asiarock Technology Limited
-OUI:2CB05D*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00146C*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:1C69A5*
ID_OUI_FROM_DATABASE=BlackBerry RTS
OUI:880355*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:A42B8C*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:04A151*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:28C68E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:5CDC96*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:504A6E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:D0D04B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
OUI:001D20*
ID_OUI_FROM_DATABASE=Comtrend Corporation
-OUI:6C38A1*
- ID_OUI_FROM_DATABASE=Ubee Interactive Corp.
-
OUI:140C76*
ID_OUI_FROM_DATABASE=FREEBOX SAS
OUI:30CBF8*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:2C4D79*
- ID_OUI_FROM_DATABASE=GoerTek Inc.
-
OUI:40D357*
ID_OUI_FROM_DATABASE=Ison Technology Co., Ltd.
OUI:24615A*
ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
-OUI:B0E2E5*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:AC0D1B*
ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
OUI:10BD55*
ID_OUI_FROM_DATABASE=Q-Lab Corporation
-OUI:C449BB*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
-
OUI:8C6D50*
ID_OUI_FROM_DATABASE=SHENZHEN MTC CO LTD
OUI:A09E1A*
ID_OUI_FROM_DATABASE=Polar Electro Oy
-OUI:3CB6B7*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:D0B2C4*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
OUI:CC79CF*
ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
-OUI:544E45*
- ID_OUI_FROM_DATABASE=Private
-
OUI:6CB9C5*
ID_OUI_FROM_DATABASE=Delta Networks, Inc.
OUI:24E43F*
ID_OUI_FROM_DATABASE=Wenzhou Kunmei Communication Technology Co.,Ltd.
-OUI:A00460*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:240AC4*
ID_OUI_FROM_DATABASE=Espressif Inc.
OUI:E0686D*
ID_OUI_FROM_DATABASE=Raybased AB
-OUI:A45385*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-
OUI:98B039*
ID_OUI_FROM_DATABASE=Nokia
OUI:04BA36*
ID_OUI_FROM_DATABASE=Li Seng Technology Ltd
-OUI:DCF090*
- ID_OUI_FROM_DATABASE=Private
-
OUI:4409B8*
ID_OUI_FROM_DATABASE=Salcomp (Shenzhen) CO., LTD.
OUI:F4B549*
ID_OUI_FROM_DATABASE=Xiamen Yeastar Information Technology Co., Ltd.
-OUI:9C3DCF*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:28EED3*
ID_OUI_FROM_DATABASE=Shenzhen Super D Technology Co., Ltd
OUI:40605A*
ID_OUI_FROM_DATABASE=Hawkeye Tech Co. Ltd
-OUI:5419C8*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:C0210D*
ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
OUI:9C50EE*
ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
-OUI:1077B0*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:F015B9*
ID_OUI_FROM_DATABASE=PlayFusion Limited
OUI:6CB4A7*
ID_OUI_FROM_DATABASE=Landauer, Inc.
-OUI:1C398A*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:F8A5C5*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:503A7D*
ID_OUI_FROM_DATABASE=AlphaTech PLC Int’l Co., Ltd.
-OUI:BC024A*
- ID_OUI_FROM_DATABASE=HMD Global Oy
-
OUI:9CFCD1*
ID_OUI_FROM_DATABASE=Aetheris Technology (Shanghai) Co., Ltd.
OUI:B01F29*
ID_OUI_FROM_DATABASE=Helvetia INC.
-OUI:CC0677*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:28070D*
ID_OUI_FROM_DATABASE=GUANGZHOU WINSOUND INFORMATION TECHNOLOGY CO.,LTD.
OUI:145BE1*
ID_OUI_FROM_DATABASE=nyantec UG (haftungsbeschränkt)
+OUI:00187D*
+ ID_OUI_FROM_DATABASE=Armorlink Co .Ltd
+
+OUI:F42981*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:3CA348*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:A40E2B*
+ ID_OUI_FROM_DATABASE=Facebook Inc
+
+OUI:28FAA0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:3CB6B7*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:5419C8*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F4B7B3*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:1C4D70*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E43A6E*
+ ID_OUI_FROM_DATABASE=Shenzhen Zeroone Technology CO.,LTD
+
+OUI:60DA83*
+ ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
+
+OUI:2C5731*
+ ID_OUI_FROM_DATABASE=Wingtech Group (HongKong)Limited
+
+OUI:F46BEF*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:085114*
+ ID_OUI_FROM_DATABASE=QINGDAO TOPSCOMM COMMUNICATION CO., LTD
+
+OUI:D05A00*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:70F11C*
+ ID_OUI_FROM_DATABASE=Shenzhen Ogemray Technology Co.,Ltd
+
+OUI:14144B*
+ ID_OUI_FROM_DATABASE=Ruijie Networks Co.,LTD
+
+OUI:70DF2F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:6447E0*
+ ID_OUI_FROM_DATABASE=Feitian Technologies Co., Ltd
+
+OUI:001753*
+ ID_OUI_FROM_DATABASE=nFore Technology Inc.
+
+OUI:58C583*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:E86D65*
+ ID_OUI_FROM_DATABASE=AUDIO MOBIL Elektronik GmbH
+
+OUI:E86FF2*
+ ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
+
+OUI:00016D*
+ ID_OUI_FROM_DATABASE=CarrierComm Inc.
+
+OUI:F0B052*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:84183A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:6CAAB3*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C4017C*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:70DEF9*
+ ID_OUI_FROM_DATABASE=FAI WAH INTERNATIONAL (HONG KONG) LIMITED
+
+OUI:001F41*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C08ADE*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:50A733*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:24C9A1*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:245880*
+ ID_OUI_FROM_DATABASE=VIZEO
+
+OUI:000726*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:BC9680*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:1CA532*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:0000FE*
+ ID_OUI_FROM_DATABASE=Annapolis Micro Systems, Inc.
+
+OUI:188090*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC024A*
+ ID_OUI_FROM_DATABASE=HMD Global Oy
+
+OUI:90A365*
+ ID_OUI_FROM_DATABASE=HMD Global Oy
+
+OUI:C444A0*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F83441*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:5C0339*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:044F4C*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:1C151F*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:544E45*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:DCEB53*
+ ID_OUI_FROM_DATABASE=Wuhan QianXiao Elecronic Technology CO.,LTD
+
+OUI:94E36D*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:74819A*
+ ID_OUI_FROM_DATABASE=PT. Hartono Istana Teknologi
+
+OUI:0835B2*
+ ID_OUI_FROM_DATABASE=CoreEdge Networks Co., Ltd
+
+OUI:6C38A1*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
+
+OUI:B40F3B*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:1062D0*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:7802B1*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:309935*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:94D9B3*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:409BCD*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:005C86*
+ ID_OUI_FROM_DATABASE=SHENZHEN FAST TECHNOLOGIES CO.,LTD
+
+OUI:1CAB34*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
+OUI:5C0979*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:002EC7*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:488EEF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:002438*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:001BED*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:0012F2*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:04A151*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A42B8C*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A00460*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:9C3DCF*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:2CB05D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:504A6E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:28C68E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:2C3033*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:00146C*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:ACFD93*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:A45385*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:2C4D79*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:841766*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:741C27*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:111111*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:FCC233*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:2830AC*
+ ID_OUI_FROM_DATABASE=Frontiir Co. Ltd.
+
+OUI:9050CA*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:0004BF*
+ ID_OUI_FROM_DATABASE=VersaLogic Corp.
+
+OUI:D8B12A*
+ ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co.,Ltd.
+
+OUI:64B5C6*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
+OUI:A41115*
+ ID_OUI_FROM_DATABASE=Robert Bosch Engineering and Business Solutions pvt. Ltd.
+
+OUI:EC0441*
+ ID_OUI_FROM_DATABASE=ShenZhen TIGO Semiconductor Co., Ltd.
+
+OUI:BC88C3*
+ ID_OUI_FROM_DATABASE=Ningbo Dooya Mechanic & Electronic Technology Co., Ltd
+
+OUI:A8BE27*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B8634D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:6C96CF*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:3035AD*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:681F40*
+ ID_OUI_FROM_DATABASE=Blu Wireless Technology Ltd
+
+OUI:48C58D*
+ ID_OUI_FROM_DATABASE=Lear Corporation GmbH
+
+OUI:90ADF7*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:982D68*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd
+
+OUI:2CD2E7*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:00152A*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:5CEA1D*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:A43412*
+ ID_OUI_FROM_DATABASE=Thales Alenia Space
+
+OUI:ECD09F*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:9C65EE*
+ ID_OUI_FROM_DATABASE=DASAN Network Solutions
+
+OUI:80739F*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:3889DC*
+ ID_OUI_FROM_DATABASE=Opticon Sensors Europe B.V.
+
+OUI:38E2DD*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:74E5F9*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:0017C8*
+ ID_OUI_FROM_DATABASE=KYOCERA Display Corporation
+
+OUI:002294*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:3C11B2*
+ ID_OUI_FROM_DATABASE=Fraunhofer FIT
+
+OUI:080070*
+ ID_OUI_FROM_DATABASE=Mitsubishi Precision Co.,LTd.
+
+OUI:DCF090*
+ ID_OUI_FROM_DATABASE=Nubia Technology Co.,Ltd.
+
+OUI:DC6AEA*
+ ID_OUI_FROM_DATABASE=Infinix mobility limited
+
+OUI:0025DF*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D8A01D*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:8CE38E*
+ ID_OUI_FROM_DATABASE=Toshiba Memory Corporation
+
+OUI:74EAC8*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
+OUI:A434F1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:C4F312*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:44EAD8*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:8C5F48*
+ ID_OUI_FROM_DATABASE=Continental Intelligent Transportation Systems LLC
+
+OUI:A0D86F*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:3890A5*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:4C1365*
+ ID_OUI_FROM_DATABASE=Emplus Technologies
+
+OUI:2054FA*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:989C57*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E4A7C5*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:104400*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:88DA1A*
+ ID_OUI_FROM_DATABASE=Redpine Signals, Inc.
+
+OUI:14CF8D*
+ ID_OUI_FROM_DATABASE=OHSUNG
+
+OUI:8CE748*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:48D35D*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:E446DA*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:500F80*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:F4F5DB*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:38A6CE*
+ ID_OUI_FROM_DATABASE=BSkyB Ltd
+
+OUI:1077B0*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:1C398A*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:CC0677*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:C84029*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:28BF89*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F4573E*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:88947E*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:B0E2E5*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F0AB54*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:C449BB*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:B430C0*
+ ID_OUI_FROM_DATABASE=York Instruments Ltd
+
+OUI:C468D0*
+ ID_OUI_FROM_DATABASE=VTech Telecommunications Ltd.
+
+OUI:48D6D5*
+ ID_OUI_FROM_DATABASE=Google, Inc.
+
+OUI:F0BD2E*
+ ID_OUI_FROM_DATABASE=H+S Polatis Ltd
+
+OUI:842C80*
+ ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
+
+OUI:182D98*
+ ID_OUI_FROM_DATABASE=Jinwoo Industrial system
+
+OUI:0C1C20*
+ ID_OUI_FROM_DATABASE=Kakao Corp
+
+OUI:40498A*
+ ID_OUI_FROM_DATABASE=Synapticon GmbH
+
+OUI:D80831*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:24F27F*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:00B69F*
+ ID_OUI_FROM_DATABASE=Latch
+
+OUI:A88200*
+ ID_OUI_FROM_DATABASE=Hisense Electric Co.,Ltd
+
+OUI:F449EF*
+ ID_OUI_FROM_DATABASE=EMSTONE
+
OUI:0C6F9C*
ID_OUI_FROM_DATABASE=Shaw Communications Inc.
OUI:F431C3*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:C4F57C*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:8C7CFF*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000CDB*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:006069*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:C87B5B*
ID_OUI_FROM_DATABASE=zte corporation
OUI:1CCDE5*
ID_OUI_FROM_DATABASE=Shanghai Wind Technologies Co.,Ltd
-OUI:20896F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:D494E8*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
OUI:3095E3*
ID_OUI_FROM_DATABASE=SHANGHAI SIMCOM LIMITED
-OUI:401B5F*
- ID_OUI_FROM_DATABASE=Weifang GoerTek Electronics Co., Ltd.
-
OUI:4040A7*
ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
OUI:68F956*
ID_OUI_FROM_DATABASE=Objetivos y Servicio de Valor Añadido
-OUI:58B633*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:F4E926*
ID_OUI_FROM_DATABASE=Tianjin Zanpu Technology Inc.
OUI:C4BAA3*
ID_OUI_FROM_DATABASE=Beijing Winicssec Technologies Co., Ltd.
-OUI:A013CB*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:20635F*
ID_OUI_FROM_DATABASE=Abeeway
OUI:18B169*
ID_OUI_FROM_DATABASE=Sonicwall
-OUI:D4684D*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:1CC72D*
ID_OUI_FROM_DATABASE=Shenzhen Huapu Digital CO.,Ltd
OUI:481842*
ID_OUI_FROM_DATABASE=Shanghai Winaas Co. Equipment Co. Ltd.
-OUI:E817FC*
- ID_OUI_FROM_DATABASE=NIFTY Corporation
-
OUI:D09C30*
ID_OUI_FROM_DATABASE=Foster Electric Company, Limited
OUI:507691*
ID_OUI_FROM_DATABASE=Tekpea, Inc.
-OUI:C421C8*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:A4C0C7*
ID_OUI_FROM_DATABASE=ShenZhen Hitom Communication Technology Co..LTD
OUI:540536*
ID_OUI_FROM_DATABASE=Vivago Oy
-OUI:2CE6CC*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:E0FAEC*
ID_OUI_FROM_DATABASE=Platan sp. z o.o. sp. k.
OUI:8C3330*
ID_OUI_FROM_DATABASE=EmFirst Co., Ltd.
-OUI:8C0C90*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:08E5DA*
ID_OUI_FROM_DATABASE=NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD.
OUI:48BE2D*
ID_OUI_FROM_DATABASE=Symanitron
-OUI:38E595*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:B86091*
ID_OUI_FROM_DATABASE=Onnet Technologies and Innovations LLC
OUI:0C565C*
ID_OUI_FROM_DATABASE=HyBroad Vision (Hong Kong) Technology Co Ltd
-OUI:647C34*
- ID_OUI_FROM_DATABASE=Ubee Interactive Corp.
-
OUI:649FF7*
ID_OUI_FROM_DATABASE=Kone OYj
OUI:702393*
ID_OUI_FROM_DATABASE=fos4X GmbH
-OUI:D8AFF1*
- ID_OUI_FROM_DATABASE=Panasonic Appliances Company
-
OUI:58ECE1*
ID_OUI_FROM_DATABASE=Newport Corporation
OUI:DC37D2*
ID_OUI_FROM_DATABASE=Hunan HKT Electronic Technology Co., Ltd
-OUI:048B42*
- ID_OUI_FROM_DATABASE=Skspruce Technology Limited
-
OUI:5076A6*
ID_OUI_FROM_DATABASE=Ecil Informatica Ind. Com. Ltda
OUI:DCF858*
ID_OUI_FROM_DATABASE=Lorent Networks, Inc.
-OUI:589396*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:A05E6B*
ID_OUI_FROM_DATABASE=MELPER Co., Ltd.
OUI:9CC0D2*
ID_OUI_FROM_DATABASE=Conductix-Wampfler GmbH
-OUI:408BF6*
- ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co; Ltd.
-
OUI:447E95*
ID_OUI_FROM_DATABASE=Alpha and Omega, Inc
OUI:C83EA7*
ID_OUI_FROM_DATABASE=KUNBUS GmbH
-OUI:A8D3C8*
- ID_OUI_FROM_DATABASE=Wachendorff Elektronik GmbH & Co. KG
-
OUI:E0CF2D*
ID_OUI_FROM_DATABASE=Gemintek Corporation
OUI:C4F464*
ID_OUI_FROM_DATABASE=Spica international
-OUI:74911A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:544A05*
ID_OUI_FROM_DATABASE=wenglor sensoric gmbh
OUI:00268C*
ID_OUI_FROM_DATABASE=StarLeaf Ltd.
-OUI:002692*
- ID_OUI_FROM_DATABASE=Mitsubishi Electric Co.
-
OUI:002686*
ID_OUI_FROM_DATABASE=Quantenna Communcations, Inc.
OUI:00248E*
ID_OUI_FROM_DATABASE=Infoware ZRt.
-OUI:002482*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:002476*
ID_OUI_FROM_DATABASE=TAP.tv
OUI:002284*
ID_OUI_FROM_DATABASE=DESAY A&V SCIENCE AND TECHNOLOGY CO.,LTD
-OUI:00227F*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:002277*
ID_OUI_FROM_DATABASE=NEC Australia Pty Ltd
OUI:00237E*
ID_OUI_FROM_DATABASE=ELSTER GMBH
-OUI:00237F*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:002379*
ID_OUI_FROM_DATABASE=Union Business Machines Co. Ltd.
OUI:001BDF*
ID_OUI_FROM_DATABASE=Iskra Sistemi d.d.
-OUI:001BD3*
- ID_OUI_FROM_DATABASE=Panasonic Corp. AVC Company
-
OUI:001BD8*
ID_OUI_FROM_DATABASE=DVTel LTD
OUI:001B12*
ID_OUI_FROM_DATABASE=Apprion
-OUI:001B17*
- ID_OUI_FROM_DATABASE=Palo Alto Networks
-
OUI:001B0B*
ID_OUI_FROM_DATABASE=Phidgets Inc.
OUI:001440*
ID_OUI_FROM_DATABASE=ATOMIC Corporation
-OUI:001439*
- ID_OUI_FROM_DATABASE=Blonder Tongue Laboratories, Inc.
-
OUI:001434*
ID_OUI_FROM_DATABASE=Keri Systems, Inc
OUI:0008FE*
ID_OUI_FROM_DATABASE=UNIK C&C Co.,Ltd.
-OUI:0008FA*
- ID_OUI_FROM_DATABASE=Karl E.Brinkmann GmbH
-
OUI:0008EE*
ID_OUI_FROM_DATABASE=Logic Product Development
OUI:0008C5*
ID_OUI_FROM_DATABASE=Liontech Co., Ltd.
-OUI:0008C9*
- ID_OUI_FROM_DATABASE=TechniSat Digital GmbH
-
OUI:0008CA*
ID_OUI_FROM_DATABASE=TwinHan Technology Co.,Ltd
OUI:003025*
ID_OUI_FROM_DATABASE=CHECKOUT COMPUTER SYSTEMS, LTD
-OUI:00D01F*
- ID_OUI_FROM_DATABASE=Senetas Security
-
OUI:003012*
ID_OUI_FROM_DATABASE=DIGITAL ENGINEERING LTD.
OUI:001025*
ID_OUI_FROM_DATABASE=Grayhill, Inc
-OUI:001009*
- ID_OUI_FROM_DATABASE=HORO QUARTZ
-
OUI:0010F8*
ID_OUI_FROM_DATABASE=TEXIO TECHNOLOGY CORPORATION
OUI:0060F8*
ID_OUI_FROM_DATABASE=Loran International Technologies Inc.
-OUI:006088*
- ID_OUI_FROM_DATABASE=WHITE MOUNTAIN DSP, INC.
-
OUI:00609A*
ID_OUI_FROM_DATABASE=NJK TECHNO CO.
OUI:00C0F6*
ID_OUI_FROM_DATABASE=CELAN TECHNOLOGY INC.
-OUI:00C08F*
- ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd.
-
OUI:00C012*
ID_OUI_FROM_DATABASE=NETSPAN CORPORATION
OUI:44E9DD*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:10F681*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:B888E3*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
OUI:F05C19*
ID_OUI_FROM_DATABASE=Aruba Networks
-OUI:C43DC7*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:000FB5*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00095B*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:F87394*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:70AAB2*
ID_OUI_FROM_DATABASE=BlackBerry RTS
OUI:7C1CF1*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:C0FFD4*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:405D82*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:803773*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:00264D*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
OUI:047E4A*
ID_OUI_FROM_DATABASE=moobox CO., Ltd.
-OUI:F01B6C*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:E0C767*
ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:D017C2*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:10DA43*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:001625*
ID_OUI_FROM_DATABASE=Impinj, Inc.
OUI:E4A471*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:60B617*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:18A3E8*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:741E93*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:00A0F4*
ID_OUI_FROM_DATABASE=GE
OUI:84FEDC*
ID_OUI_FROM_DATABASE=Borqs Beijing Ltd.
-OUI:F03E90*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D8D723*
ID_OUI_FROM_DATABASE=IDS, Inc
OUI:D8209F*
ID_OUI_FROM_DATABASE=Cubro Acronet GesmbH
-OUI:CC500A*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:A860B6*
ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:D8B02E*
ID_OUI_FROM_DATABASE=Guangzhou Zonerich Business Machine Co., LTD.
-OUI:DC1AC5*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:849D64*
ID_OUI_FROM_DATABASE=SMC Corporation
OUI:D49B5C*
ID_OUI_FROM_DATABASE=Chongqing Miedu Technology Co., Ltd.
-OUI:EC8CA2*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:C411E0*
ID_OUI_FROM_DATABASE=Bull Group Co., Ltd
OUI:001650*
ID_OUI_FROM_DATABASE=Kratos EPD
-OUI:9CFBD5*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:583112*
ID_OUI_FROM_DATABASE=DRUST
OUI:640DCE*
ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
-OUI:00A085*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:ACDE48*
- ID_OUI_FROM_DATABASE=Private
-
OUI:6063F9*
ID_OUI_FROM_DATABASE=Ciholas, Inc.
OUI:143365*
ID_OUI_FROM_DATABASE=TEM Mobile Limited
-OUI:205D47*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:C0F945*
ID_OUI_FROM_DATABASE=Toshiba Toko Meter Systems Co., LTD.
OUI:487B6B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:3087D9*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
-OUI:A8E705*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:9C62AB*
ID_OUI_FROM_DATABASE=Sumavision Technologies Co.,Ltd
OUI:6045CB*
ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
-OUI:74C9A3*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:84AFEC*
ID_OUI_FROM_DATABASE=BUFFALO.INC
OUI:B02628*
ID_OUI_FROM_DATABASE=Broadcom Limited
-OUI:24792A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:0080E7*
ID_OUI_FROM_DATABASE=Leonardo Tactical Systems.
OUI:90FB5B*
ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:3C0CDB*
+ ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
+
+OUI:C81FEA*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:10F681*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F01B6C*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:DC1AC5*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:205D47*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:9CFBD5*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:886AE3*
+ ID_OUI_FROM_DATABASE=Alpha Networks Inc.
+
+OUI:9061AE*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:A4F3E7*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:A0239F*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:D8DF7A*
+ ID_OUI_FROM_DATABASE=Quest Software, Inc.
+
+OUI:30B62D*
+ ID_OUI_FROM_DATABASE=Mojo Networks, Inc.
+
+OUI:001B17*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:9828A6*
+ ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
+
+OUI:B0EABC*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:94C691*
+ ID_OUI_FROM_DATABASE=EliteGroup Computer Systems Co., LTD
+
+OUI:9C6F52*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:A09D86*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
+OUI:E0CBBC*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:00D01F*
+ ID_OUI_FROM_DATABASE=Senetas Corporation Ltd
+
+OUI:A40450*
+ ID_OUI_FROM_DATABASE=nFore Technology Inc.
+
+OUI:4CB008*
+ ID_OUI_FROM_DATABASE=Shenzhen Gwelltimes Technology Co.,Ltd
+
+OUI:58B633*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:D4684D*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:2CE6CC*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:8C0C90*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:842096*
+ ID_OUI_FROM_DATABASE=SHENZHEN RF-LINK TECHNOLOGY CO.,LTD.
+
+OUI:3087D9*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:24792A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:589396*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:74911A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:00227F*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:002482*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:F03E90*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:EC8CA2*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:30F77F*
+ ID_OUI_FROM_DATABASE=S Mobile Devices Limited
+
+OUI:38E595*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:5C5181*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:389AF6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:E0AA96*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:507705*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:C4CB6B*
+ ID_OUI_FROM_DATABASE=Airista Flow, Inc.
+
+OUI:B05508*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:008BFC*
+ ID_OUI_FROM_DATABASE=mixi,Inc.
+
+OUI:2C4053*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:ACDE48*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:00A085*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D09466*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:F0EFD2*
+ ID_OUI_FROM_DATABASE=TF PAYMENT SERVICE CO., LTD
+
+OUI:30C01B*
+ ID_OUI_FROM_DATABASE=Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd
+
+OUI:647C34*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
+
+OUI:747D24*
+ ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd.
+
+OUI:E817FC*
+ ID_OUI_FROM_DATABASE=Fujitsu Cloud Technologies Limited
+
+OUI:001009*
+ ID_OUI_FROM_DATABASE=HORANET
+
+OUI:6432A8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:78BC1A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:E4F004*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:60F677*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:288CB8*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:0C72D9*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:602E20*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E472E2*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E86819*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:48BCA6*
+ ID_OUI_FROM_DATABASE=ASUNG TECHNO CO.,Ltd
+
+OUI:8C7CFF*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:C4F57C*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00237F*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:00095B*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:000FB5*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:006069*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000CDB*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:803773*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:405D82*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C0FFD4*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:10DA43*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:B03956*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C43DC7*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:F87394*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:401B5F*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:AC512C*
+ ID_OUI_FROM_DATABASE=Infinix mobility limited
+
+OUI:90B1E0*
+ ID_OUI_FROM_DATABASE=Beijing Nebula Link Technology Co., Ltd
+
+OUI:6C090A*
+ ID_OUI_FROM_DATABASE=GEMATICA SRL
+
+OUI:001439*
+ ID_OUI_FROM_DATABASE=Blonder Tongue Laboratories, Inc
+
+OUI:107B44*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:9C4FCF*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
+
+OUI:001BD3*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:00C08F*
+ ID_OUI_FROM_DATABASE=Panasonic Electric Works Co., Ltd.
+
+OUI:0008C9*
+ ID_OUI_FROM_DATABASE=TechniSat Digital GmbH Daun
+
+OUI:20A6CD*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:F4F3AA*
+ ID_OUI_FROM_DATABASE=JBL GmbH & Co. KG
+
+OUI:38CD07*
+ ID_OUI_FROM_DATABASE=Beijing FaceCam Technology Co., Ltd.
+
+OUI:B009DA*
+ ID_OUI_FROM_DATABASE=Ring Solutions
+
+OUI:444AB0*
+ ID_OUI_FROM_DATABASE=Zhejiang Moorgen Intelligence Technology Co., Ltd
+
+OUI:844167*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:B4F61C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:ECFA03*
+ ID_OUI_FROM_DATABASE=FCA
+
+OUI:78E103*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:90324B*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:78A6E1*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:F4D7B2*
+ ID_OUI_FROM_DATABASE=LGS Innovations, LLC
+
+OUI:20040F*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:2C7360*
+ ID_OUI_FROM_DATABASE=Earda Technologies co Ltd
+
+OUI:048B42*
+ ID_OUI_FROM_DATABASE=Skspruce Technologies
+
+OUI:C421C8*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:9C63ED*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:002692*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
+
+OUI:F03D03*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:006088*
+ ID_OUI_FROM_DATABASE=Analog Devices, Inc.
+
+OUI:084ACF*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:1CDDEA*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:ECEBB8*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:5CE8B7*
+ ID_OUI_FROM_DATABASE=Oraimo Technology Limited
+
+OUI:D89EF3*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:CC66B2*
+ ID_OUI_FROM_DATABASE=Nokia
+
+OUI:C0742B*
+ ID_OUI_FROM_DATABASE=SHENZHEN XUNLONG SOFTWARE CO.,LIMITED
+
+OUI:D8AFF1*
+ ID_OUI_FROM_DATABASE=Panasonic Appliances Company
+
+OUI:7086C1*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:A072E4*
+ ID_OUI_FROM_DATABASE=NJ SYSTEM CO.,LTD
+
+OUI:A8E824*
+ ID_OUI_FROM_DATABASE=INIM ELECTRONICS S.R.L.
+
+OUI:6CB749*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A0FE61*
+ ID_OUI_FROM_DATABASE=Vivint Wireless Inc.
+
+OUI:601803*
+ ID_OUI_FROM_DATABASE=Daikin Air-conditioning (Shanghai) Co., Ltd.
+
+OUI:08152F*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. ARTIK
+
+OUI:408BF6*
+ ID_OUI_FROM_DATABASE=Shenzhen TCL New Technology Co., Ltd
+
+OUI:F46E24*
+ ID_OUI_FROM_DATABASE=NEC Personal Computers, Ltd.
+
+OUI:888279*
+ ID_OUI_FROM_DATABASE=Shenzhen RB-LINK Intelligent Technology Co.Ltd
+
+OUI:78321B*
+ ID_OUI_FROM_DATABASE=D-Link International
+
+OUI:EC51BC*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:F079E8*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:741E93*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:18A3E8*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:60B617*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:CC500A*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:A8E705*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:74C9A3*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:A013CB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:20896F*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:D8A534*
+ ID_OUI_FROM_DATABASE=Spectronix Corporation
+
+OUI:583879*
+ ID_OUI_FROM_DATABASE=RICOH COMPANY, LTD.
+
+OUI:94282E*
+ ID_OUI_FROM_DATABASE=New H3C Technologies Co., Ltd
+
+OUI:887598*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D0B128*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:FCEEE6*
+ ID_OUI_FROM_DATABASE=FORMIKE ELECTRONIC CO., LTD
+
+OUI:D843ED*
+ ID_OUI_FROM_DATABASE=Suzuken
+
+OUI:2C431A*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:A8D3C8*
+ ID_OUI_FROM_DATABASE=Topcon Electronics GmbH & Co. KG
+
+OUI:389F5A*
+ ID_OUI_FROM_DATABASE=C-Kur TV Inc.
+
+OUI:24B209*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:24E124*
+ ID_OUI_FROM_DATABASE=Xiamen Ursaconn Technology Co. , Ltd.
+
+OUI:DC68EB*
+ ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
+
+OUI:9441C1*
+ ID_OUI_FROM_DATABASE=Mini-Cam Limited
+
+OUI:E8D819*
+ ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+
+OUI:0008FA*
+ ID_OUI_FROM_DATABASE=KEB Automation KG
+
+OUI:18396E*
+ ID_OUI_FROM_DATABASE=SUNSEA TELECOMMUNICATIONS CO.,LTD.
+
+OUI:E8DF70*
+ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
+
OUI:5846E1*
ID_OUI_FROM_DATABASE=Baxter International Inc
OUI:5C899A*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-OUI:E422A5*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:1C994C*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
OUI:0013E0*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-OUI:748EF8*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:00E052*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000480*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000088*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:344B50*
ID_OUI_FROM_DATABASE=zte corporation
OUI:E4AA5D*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:000389*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
-OUI:0CE0E4*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:B0AA77*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:B899B0*
ID_OUI_FROM_DATABASE=Cohere Technologies
-OUI:2CC5D3*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:80C5E6*
ID_OUI_FROM_DATABASE=Microsoft Corporation
OUI:A8827F*
ID_OUI_FROM_DATABASE=CIBN Oriental Network(Beijing) CO.,Ltd
-OUI:609C9F*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:900A39*
ID_OUI_FROM_DATABASE=Wiio, Inc.
OUI:74A34A*
ID_OUI_FROM_DATABASE=ZIMI CORPORATION
-OUI:98F5A9*
- ID_OUI_FROM_DATABASE=OHSUNG ELECTRONICS CO.,LTD.
-
OUI:D89341*
ID_OUI_FROM_DATABASE=General Electric Global Research
OUI:DCC622*
ID_OUI_FROM_DATABASE=BUHEUNG SYSTEM
-OUI:5C2BF5*
- ID_OUI_FROM_DATABASE=Vivint
-
OUI:D062A0*
ID_OUI_FROM_DATABASE=China Essence Technology (Zhumadian) Co., Ltd.
OUI:4C2C83*
ID_OUI_FROM_DATABASE=Zhejiang KaNong Network Technology Co.,Ltd.
-OUI:BCC342*
- ID_OUI_FROM_DATABASE=Panasonic System Networks Co., Ltd.
-
OUI:E89606*
ID_OUI_FROM_DATABASE=testo Instruments (Shenzhen) Co., Ltd.
OUI:7CCD11*
ID_OUI_FROM_DATABASE=MS-Magnet
-OUI:94FBB2*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:4CE1BB*
ID_OUI_FROM_DATABASE=Zhuhai HiFocus Technology Co., Ltd.
OUI:68692E*
ID_OUI_FROM_DATABASE=Zycoo Co.,Ltd
-OUI:A875E2*
- ID_OUI_FROM_DATABASE=Aventura Technologies, Inc.
-
OUI:38BF2F*
ID_OUI_FROM_DATABASE=Espec Corp.
OUI:7C8306*
ID_OUI_FROM_DATABASE=Glen Dimplex Nordic as
-OUI:84253F*
- ID_OUI_FROM_DATABASE=Silex Technology, Inc
-
OUI:907A0A*
ID_OUI_FROM_DATABASE=Gebr. Bode GmbH & Co KG
OUI:50B8A2*
ID_OUI_FROM_DATABASE=ImTech Technologies LLC,
-OUI:A41566*
- ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
-
OUI:B04C05*
ID_OUI_FROM_DATABASE=Fresenius Medical Care Deutschland GmbH
OUI:305D38*
ID_OUI_FROM_DATABASE=Beissbarth
-OUI:FCD6BD*
- ID_OUI_FROM_DATABASE=Robert Bosch GmbH
-
OUI:044A50*
ID_OUI_FROM_DATABASE=Ramaxel Technology (Shenzhen) limited company
OUI:7C6B52*
ID_OUI_FROM_DATABASE=Tigaro Wireless
-OUI:48C1AC*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:046D42*
ID_OUI_FROM_DATABASE=Bryston Ltd.
OUI:E84E06*
ID_OUI_FROM_DATABASE=EDUP INTERNATIONAL (HK) CO., LTD
-OUI:70B921*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:E8C320*
ID_OUI_FROM_DATABASE=Austco Communication Systems Pty Ltd
OUI:B42A39*
ID_OUI_FROM_DATABASE=ORBIT MERRET, spol. s r. o.
-OUI:B80B9D*
- ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH
-
OUI:18AEBB*
ID_OUI_FROM_DATABASE=Siemens Convergence Creators GmbH&Co.KG
OUI:205B2A*
ID_OUI_FROM_DATABASE=Private
-OUI:18B430*
- ID_OUI_FROM_DATABASE=Nest Labs Inc.
-
OUI:F8769B*
ID_OUI_FROM_DATABASE=Neopis Co., Ltd.
OUI:AC5E8C*
ID_OUI_FROM_DATABASE=Utillink
-OUI:CC7EE7*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-
OUI:BC99BC*
ID_OUI_FROM_DATABASE=FonSee Technology Inc.
OUI:EC836C*
ID_OUI_FROM_DATABASE=RM Tech Co., Ltd.
-OUI:C0C520*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:6083B2*
ID_OUI_FROM_DATABASE=GkWare e.K.
OUI:8C541D*
ID_OUI_FROM_DATABASE=LGE
-OUI:601283*
- ID_OUI_FROM_DATABASE=Soluciones Tecnologicas para la Salud y el Bienestar SA
-
OUI:003A9D*
ID_OUI_FROM_DATABASE=NEC Platforms, Ltd.
OUI:CC5076*
ID_OUI_FROM_DATABASE=Ocom Communications, Inc.
-OUI:705812*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-
OUI:7C2CF3*
ID_OUI_FROM_DATABASE=Secure Electrans Ltd
OUI:001DDF*
ID_OUI_FROM_DATABASE=Sunitec Enterprise Co., Ltd.
-OUI:001DCC*
- ID_OUI_FROM_DATABASE=Hetra Secure Solutions
-
OUI:001DC7*
ID_OUI_FROM_DATABASE=L-3 Communications Geneva Aerospace
OUI:001D01*
ID_OUI_FROM_DATABASE=Neptune Digital
-OUI:001CFA*
- ID_OUI_FROM_DATABASE=Alarm.com
-
OUI:001CEE*
ID_OUI_FROM_DATABASE=SHARP Corporation
OUI:001980*
ID_OUI_FROM_DATABASE=Gridpoint Systems
-OUI:001987*
- ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co., Ltd.
-
OUI:00197B*
ID_OUI_FROM_DATABASE=Picotest Corp.
OUI:001891*
ID_OUI_FROM_DATABASE=Zhongshan General K-mate Electronics Co., Ltd
-OUI:001885*
- ID_OUI_FROM_DATABASE=Avigilon Corporation
-
OUI:00188C*
ID_OUI_FROM_DATABASE=Mobile Action Technology Inc.
OUI:001733*
ID_OUI_FROM_DATABASE=SFR
-OUI:00173A*
- ID_OUI_FROM_DATABASE=Reach Systems Inc.
-
OUI:00172E*
ID_OUI_FROM_DATABASE=FXC Inc.
OUI:00151F*
ID_OUI_FROM_DATABASE=Multivision Intelligent Surveillance (Hong Kong) Ltd
-OUI:001526*
- ID_OUI_FROM_DATABASE=Remote Technologies Inc
-
OUI:00151A*
ID_OUI_FROM_DATABASE=Hunter Engineering Company
OUI:00133D*
ID_OUI_FROM_DATABASE=Micro Memory Curtiss Wright Co
-OUI:00139D*
- ID_OUI_FROM_DATABASE=Marvell Hispana S.L.
-
OUI:00138B*
ID_OUI_FROM_DATABASE=Phantom Technologies LLC
OUI:001212*
ID_OUI_FROM_DATABASE=PLUS Corporation
-OUI:001219*
- ID_OUI_FROM_DATABASE=Ahead Communication Systems Inc
-
OUI:0012D8*
ID_OUI_FROM_DATABASE=International Games System Co., Ltd.
OUI:005065*
ID_OUI_FROM_DATABASE=TDK-Lambda Corporation
-OUI:0050C7*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0050F4*
ID_OUI_FROM_DATABASE=SIGMATEK GMBH & CO. KG
OUI:00D04B*
ID_OUI_FROM_DATABASE=LA CIE GROUP S.A.
-OUI:00D060*
- ID_OUI_FROM_DATABASE=Panasonic Europe Ltd.
-
OUI:00D002*
ID_OUI_FROM_DATABASE=DITECH CORPORATION
OUI:00C005*
ID_OUI_FROM_DATABASE=LIVINGSTON ENTERPRISES, INC.
-OUI:00C064*
- ID_OUI_FROM_DATABASE=GENERAL DATACOMM IND. INC.
-
OUI:00C0C8*
ID_OUI_FROM_DATABASE=MICRO BYTE PTY. LTD.
OUI:00404C*
ID_OUI_FROM_DATABASE=HYPERTEC PTY LTD.
-OUI:00C0EE*
- ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
-
OUI:00C0CB*
ID_OUI_FROM_DATABASE=CONTROL TECHNOLOGY CORPORATION
OUI:08004F*
ID_OUI_FROM_DATABASE=CYGNET SYSTEMS
-OUI:F8E71E*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:00194B*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:90013B*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:ECDF3A*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:E45AA2*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:00235A*
ID_OUI_FROM_DATABASE=COMPAL INFORMATION (KUNSHAN) CO., LTD.
OUI:40BA61*
ID_OUI_FROM_DATABASE=ARIMA Communications Corp.
-OUI:841B5E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:204E7F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:A021B7*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:0024B2*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:C03F0E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:001F33*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:1883BF*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
OUI:001F3F*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:506A03*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:6CB0CE*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:100D7F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:0020D6*
ID_OUI_FROM_DATABASE=Breezecom, Ltd.
OUI:AC5F3E*
ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
-OUI:B07FB9*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:70661B*
ID_OUI_FROM_DATABASE=Sonova AG
OUI:10F005*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:BC9889*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:E42F26*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:344B3D*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:FCF647*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:1088CE*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:D463FE*
ID_OUI_FROM_DATABASE=Arcadyan Corporation
OUI:3C92DC*
ID_OUI_FROM_DATABASE=Octopod Technology Co. Ltd.
-OUI:74CC39*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:6038E0*
ID_OUI_FROM_DATABASE=Belkin International Inc.
OUI:F0FDA0*
ID_OUI_FROM_DATABASE=Acurix Networks Pty Ltd
-OUI:1CB9C4*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:3876D1*
ID_OUI_FROM_DATABASE=Euronda SpA
OUI:00A742*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:6CA858*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:001478*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
OUI:BC3F8F*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:E4A749*
- ID_OUI_FROM_DATABASE=Palo Alto Networks
-
OUI:04DEF2*
ID_OUI_FROM_DATABASE=Shenzhen ECOM Technology Co. Ltd
OUI:00D071*
ID_OUI_FROM_DATABASE=ECHELON CORP.
+OUI:504061*
+ ID_OUI_FROM_DATABASE=Nokia
+
OUI:0030C5*
ID_OUI_FROM_DATABASE=CADENCE DESIGN SYSTEMS, INC.
-OUI:504061*
- ID_OUI_FROM_DATABASE=Nokia
+OUI:54E3F6*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent
OUI:7467F7*
ID_OUI_FROM_DATABASE=Extreme Networks
+OUI:B0C205*
+ ID_OUI_FROM_DATABASE=BIONIME
+
+OUI:0C61CF*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
OUI:B4C799*
ID_OUI_FROM_DATABASE=Extreme Networks
-OUI:54E3F6*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent
-
OUI:5C0E8B*
ID_OUI_FROM_DATABASE=Extreme Networks
OUI:00E02B*
ID_OUI_FROM_DATABASE=Extreme Networks
-OUI:B0C205*
- ID_OUI_FROM_DATABASE=BIONIME
-
-OUI:0C61CF*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
OUI:7C2664*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-OUI:E47DEB*
- ID_OUI_FROM_DATABASE=Shanghai Notion Information Technology CO.,LTD.
-
OUI:A002DC*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
OUI:0C47C9*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
-OUI:28EF01*
- ID_OUI_FROM_DATABASE=Private
+OUI:E47DEB*
+ ID_OUI_FROM_DATABASE=Shanghai Notion Information Technology CO.,LTD.
OUI:747548*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
OUI:F49634*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:F470AB*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
-OUI:341A35*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:6C4B90*
ID_OUI_FROM_DATABASE=LiteON
-OUI:08028E*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:F8FF0B*
ID_OUI_FROM_DATABASE=Electronic Technology Inc.
OUI:00093A*
ID_OUI_FROM_DATABASE=Molex
+OUI:C8F86D*
+ ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
+
OUI:B8D50B*
ID_OUI_FROM_DATABASE=Sunitec Enterprise Co.,Ltd
OUI:28A6DB*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:C8F86D*
- ID_OUI_FROM_DATABASE=Alcatel-Lucent Shanghai Bell Co., Ltd
-
OUI:D45F25*
ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
OUI:BC8AE8*
ID_OUI_FROM_DATABASE=QING DAO HAIER TELECOM CO.,LTD.
+OUI:A81B5A*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:DC6DCD*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
OUI:440444*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
OUI:4C1A3D*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-OUI:A81B5A*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
-
-OUI:DC6DCD*
- ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+OUI:185207*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
OUI:70D379*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:7C4F7D*
ID_OUI_FROM_DATABASE=Sawwave
-OUI:185207*
- ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
-
OUI:9874DA*
ID_OUI_FROM_DATABASE=Infinix mobility limited
OUI:54FA3E*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:0C8910*
+OUI:B8BBAF*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:FCF136*
+OUI:60C5AD*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:981DFA*
+OUI:28395E*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:84A466*
+OUI:C4AE12*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:1867B0*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:10D07A*
+ ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
-OUI:CCB11A*
+OUI:0C8910*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:B8BBAF*
+OUI:FCF136*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:60C5AD*
+OUI:981DFA*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:28395E*
+OUI:84A466*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:C4AE12*
+OUI:1867B0*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:10D07A*
- ID_OUI_FROM_DATABASE=AMPAK Technology, Inc.
+OUI:CCB11A*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:80B234*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
OUI:B877C3*
ID_OUI_FROM_DATABASE=METER Group
-OUI:003676*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:84E058*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:F07485*
ID_OUI_FROM_DATABASE=NGD Systems, Inc.
-OUI:347A60*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:BC644B*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:E46449*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:C005C2*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:6455B1*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:203D66*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:D404CD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:446AB7*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:2C9924*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:001BDD*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:3CDFA9*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:105611*
+OUI:003676*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:2C3AE8*
- ID_OUI_FROM_DATABASE=Espressif Inc.
+OUI:84E058*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:347A60*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:C005C2*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:6455B1*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:203D66*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:D404CD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:446AB7*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:2C9924*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:105611*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:DC74A8*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:C087EB*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:2C3AE8*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:74F61C*
+ ID_OUI_FROM_DATABASE=HTC Corporation
+
OUI:E8B6C2*
ID_OUI_FROM_DATABASE=Juniper Networks
OUI:B0DAF9*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:74F61C*
- ID_OUI_FROM_DATABASE=HTC Corporation
-
OUI:3438B7*
ID_OUI_FROM_DATABASE=HUMAX Co., Ltd.
OUI:5C1A6F*
ID_OUI_FROM_DATABASE=Cambridge Industries(Group) Co.,Ltd.
+OUI:487D2E*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
OUI:B089C2*
ID_OUI_FROM_DATABASE=Zyptonite
OUI:F0D4F6*
ID_OUI_FROM_DATABASE=Lars Thrane A/S
-OUI:487D2E*
- ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
-
OUI:0403D6*
ID_OUI_FROM_DATABASE=Nintendo Co.,Ltd
OUI:AC4E2E*
ID_OUI_FROM_DATABASE=Shenzhen JingHanDa Electronics Co.Ltd
-OUI:B40016*
- ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS
-
OUI:0027E3*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:A0341B*
- ID_OUI_FROM_DATABASE=TrackR, Inc
+OUI:488D36*
+ ID_OUI_FROM_DATABASE=Arcadyan Corporation
+
+OUI:B40016*
+ ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS
OUI:FCA667*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
OUI:784501*
ID_OUI_FROM_DATABASE=Biamp Systems
-OUI:488D36*
- ID_OUI_FROM_DATABASE=Arcadyan Corporation
+OUI:A0341B*
+ ID_OUI_FROM_DATABASE=TrackR, Inc
OUI:986F60*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
OUI:4C189A*
ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+OUI:6CA849*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
+OUI:A4251B*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
OUI:E45D52*
ID_OUI_FROM_DATABASE=Avaya Inc
OUI:707C69*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:A47886*
+OUI:FC8399*
ID_OUI_FROM_DATABASE=Avaya Inc
OUI:44322A*
OUI:048A15*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:6CA849*
+OUI:00040D*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:A4251B*
+OUI:A47886*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:00040D*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:001CFA*
+ ID_OUI_FROM_DATABASE=Alarm.com
-OUI:FC8399*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:60313B*
+ ID_OUI_FROM_DATABASE=Sunnovo International Limited
+
+OUI:B4E62A*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
+OUI:E45AA2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:ECDF3A*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F470AB*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:50184C*
+ ID_OUI_FROM_DATABASE=Platina Systems Inc.
+
+OUI:E4A749*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:786D94*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:CC4639*
+ ID_OUI_FROM_DATABASE=WAAV, Inc.
+
+OUI:30B164*
+ ID_OUI_FROM_DATABASE=Power Electronics International Inc.
+
+OUI:18B430*
+ ID_OUI_FROM_DATABASE=Nest Labs Inc.
+
+OUI:3CF591*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:602101*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:604762*
+ ID_OUI_FROM_DATABASE=Beijing Sensoro Technology Co.,Ltd.
+
+OUI:7CE2CA*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:B0DFC1*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:70788B*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:001DCC*
+ ID_OUI_FROM_DATABASE=Ayon Cyber Security, Inc
+
+OUI:7065A3*
+ ID_OUI_FROM_DATABASE=Kandao lightforge Co., Ltd.
+
+OUI:706E6D*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:FC2F6B*
+ ID_OUI_FROM_DATABASE=Everspin Technologies, Inc.
+
+OUI:B4C170*
+ ID_OUI_FROM_DATABASE=Yi chip Microelectronics (Hangzhou) Co., Ltd
+
+OUI:540237*
+ ID_OUI_FROM_DATABASE=Teltronic AG
+
+OUI:2CC5D3*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:F8E71E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:1CB9C4*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C0C520*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:A89675*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:94F128*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:94FBB2*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:A47B9D*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:608E08*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:7C2EDD*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:3CF7A4*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:342D0D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:EC3DFD*
+ ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
+
+OUI:001885*
+ ID_OUI_FROM_DATABASE=Avigilon Corporation
+
+OUI:18742E*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:8886C2*
+ ID_OUI_FROM_DATABASE=STABILO International GmbH
+
+OUI:04FA3F*
+ ID_OUI_FROM_DATABASE=Opticore Inc.
+
+OUI:308454*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:FC7F56*
+ ID_OUI_FROM_DATABASE=CoSyst Control Systems GmbH
+
+OUI:8C2505*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:94D029*
+ ID_OUI_FROM_DATABASE=GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD
+
+OUI:4C49E3*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:28D436*
+ ID_OUI_FROM_DATABASE=Jiangsu dewosi electric co., LTD
+
+OUI:149346*
+ ID_OUI_FROM_DATABASE=PNI sensor corporation
+
+OUI:18B81F*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:00C064*
+ ID_OUI_FROM_DATABASE=General Datacomm LLC
+
+OUI:601283*
+ ID_OUI_FROM_DATABASE=TSB REAL TIME LOCATION SYSTEMS S.L.
+
+OUI:E06089*
+ ID_OUI_FROM_DATABASE=Cloudleaf, Inc.
+
+OUI:001219*
+ ID_OUI_FROM_DATABASE=General Datacomm LLC
+
+OUI:BC54FC*
+ ID_OUI_FROM_DATABASE=SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD.
+
+OUI:547595*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:18BC5A*
+ ID_OUI_FROM_DATABASE=Zhejiang Tmall Technology Co., Ltd.
+
+OUI:00869C*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:00139D*
+ ID_OUI_FROM_DATABASE=MaxLinear Hispania S.L.U.
+
+OUI:4C16FC*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:609C9F*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000088*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000480*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00E052*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:748EF8*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:48C1AC*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:0CE0E4*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:000389*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:E422A5*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:001F33*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C03F0E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:0024B2*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A021B7*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:204E7F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:841B5E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:100D7F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:6CB0CE*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:506A03*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:B07FB9*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:08028E*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:D8C497*
+ ID_OUI_FROM_DATABASE=Quanta Computer Inc.
+
+OUI:444E6D*
+ ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
+
+OUI:A41566*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:74E60F*
+ ID_OUI_FROM_DATABASE=TECNO MOBILE LIMITED
+
+OUI:0050C7*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:B80B9D*
+ ID_OUI_FROM_DATABASE=ROPEX Industrie-Elektronik GmbH
+
+OUI:001526*
+ ID_OUI_FROM_DATABASE=Remote Technologies Inc
+
+OUI:409922*
+ ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
+
+OUI:B8DB1C*
+ ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
+
+OUI:3C10E6*
+ ID_OUI_FROM_DATABASE=PHAZR Inc.
+
+OUI:001987*
+ ID_OUI_FROM_DATABASE=Panasonic Mobile Communications Co.,Ltd.
+
+OUI:BCC342*
+ ID_OUI_FROM_DATABASE=Panasonic Communications Co., Ltd.
+
+OUI:705812*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:CC7EE7*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:00D060*
+ ID_OUI_FROM_DATABASE=Panasonic Europe Ltd.
+
+OUI:84253F*
+ ID_OUI_FROM_DATABASE=silex technology, Inc.
+
+OUI:40017A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:40D63C*
+ ID_OUI_FROM_DATABASE=Equitech Industrial(DongGuan)Co.,Ltd
+
+OUI:A4E975*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:C0A53E*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:9800C6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:787B8A*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:3866F0*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:20EE28*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:08F4AB*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:8C8590*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:FC017C*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:2CB21A*
+ ID_OUI_FROM_DATABASE=Phicomm (Shanghai) Co., Ltd.
+
+OUI:00C0EE*
+ ID_OUI_FROM_DATABASE=KYOCERA Display Corporation
+
+OUI:28840E*
+ ID_OUI_FROM_DATABASE=silicon valley immigration service
+
+OUI:CC5A53*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC2E48*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:940006*
+ ID_OUI_FROM_DATABASE=jinyoung
+
+OUI:5C6776*
+ ID_OUI_FROM_DATABASE=IDS Imaging Development Systems GmbH
+
+OUI:28EF01*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:A875E2*
+ ID_OUI_FROM_DATABASE=Aventura Technologies, Inc.
+
+OUI:DC0C2D*
+ ID_OUI_FROM_DATABASE=WEIFANG GOERTEK ELECTRONICS CO.,LTD
+
+OUI:00173A*
+ ID_OUI_FROM_DATABASE=Cloudastructure Inc
+
+OUI:38D620*
+ ID_OUI_FROM_DATABASE=Limidea Concept Pte. Ltd.
+
+OUI:745C4B*
+ ID_OUI_FROM_DATABASE=GN Audio A/S
+
+OUI:64FB50*
+ ID_OUI_FROM_DATABASE=RoomReady/Zdi, Inc.
+
+OUI:940E6B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:38378B*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5C2BF5*
+ ID_OUI_FROM_DATABASE=Vivint Wireless Inc.
+
+OUI:00FC8B*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:10F163*
+ ID_OUI_FROM_DATABASE=TNK CO.,LTD
+
+OUI:98F5A9*
+ ID_OUI_FROM_DATABASE=OHSUNG
+
+OUI:5033F0*
+ ID_OUI_FROM_DATABASE=YICHEN (SHENZHEN) TECHNOLOGY CO.LTD
+
+OUI:50F722*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:90FD9F*
+ ID_OUI_FROM_DATABASE=Silicon Laboratories
+
+OUI:504EDC*
+ ID_OUI_FROM_DATABASE=Ping Communication
+
+OUI:344B3D*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:E42F26*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:BC9889*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:1088CE*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:FCF647*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:74CC39*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:6CA858*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:341A35*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:18D225*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:185282*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:BC4101*
+ ID_OUI_FROM_DATABASE=Shenzhen TINNO Mobile Technology Corp.
+
+OUI:5C8D2D*
+ ID_OUI_FROM_DATABASE=Shanghai Wellpay Information Technology Co., Ltd
+
+OUI:70B921*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:C850E9*
+ ID_OUI_FROM_DATABASE=Raisecom Technology CO., LTD
+
+OUI:BC825D*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:5CA176*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:C8E7F0*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:087808*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D03169*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:BC5451*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:24F5A2*
+ ID_OUI_FROM_DATABASE=Belkin International Inc.
+
+OUI:782D7E*
+ ID_OUI_FROM_DATABASE=TRENDnet, Inc.
+
+OUI:BCC31B*
+ ID_OUI_FROM_DATABASE=Kygo Life AS
+
+OUI:FCD6BD*
+ ID_OUI_FROM_DATABASE=Robert Bosch GmbH
+
+OUI:48BA4E*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:FC65DE*
+ ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
+
+OUI:B06EBF*
+ ID_OUI_FROM_DATABASE=ASUSTek COMPUTER INC.
+
+OUI:28AD3E*
+ ID_OUI_FROM_DATABASE=Shenzhen TONG BO WEI Technology CO.,LTD
+
+OUI:F092B4*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
OUI:D86CE9*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:1002B5*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:A468BC*
- ID_OUI_FROM_DATABASE=Private
-
OUI:441EA1*
ID_OUI_FROM_DATABASE=Hewlett Packard
OUI:E84DD0*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:D81FCC*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:140467*
ID_OUI_FROM_DATABASE=SNK Technologies Co.,Ltd.
OUI:688F84*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:889471*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:CC4E24*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:50EB1A*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:0027F8*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:000533*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:0060DF*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:4CAC0A*
ID_OUI_FROM_DATABASE=zte corporation
OUI:049645*
ID_OUI_FROM_DATABASE=WUXI SKY CHIP INTERCONNECTION TECHNOLOGY CO.,LTD.
-OUI:5CE3B6*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:9C88AD*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:C8C2C6*
ID_OUI_FROM_DATABASE=Shanghai Airm2m Communication Technology Co., Ltd
OUI:ACC51B*
ID_OUI_FROM_DATABASE=Zhuhai Pantum Electronics Co., Ltd.
-OUI:4473D6*
- ID_OUI_FROM_DATABASE=Logitech
-
OUI:E80734*
ID_OUI_FROM_DATABASE=Champion Optical Network Engineering, LLC
OUI:E435C8*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:38FF36*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D47208*
ID_OUI_FROM_DATABASE=Bragi GmbH
OUI:188EF9*
ID_OUI_FROM_DATABASE=G2C Co. Ltd.
-OUI:809FAB*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:D00492*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:F4E9D4*
ID_OUI_FROM_DATABASE=QLogic Corporation
OUI:902CC7*
ID_OUI_FROM_DATABASE=C-MAX Asia Limited
-OUI:1C965A*
- ID_OUI_FROM_DATABASE=Weifang goertek Electronics CO.,LTD
-
OUI:188219*
ID_OUI_FROM_DATABASE=Alibaba Cloud Computing Ltd.
OUI:84A783*
ID_OUI_FROM_DATABASE=Alcatel Lucent
-OUI:2C5D93*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:1CC11A*
ID_OUI_FROM_DATABASE=Wavetronix
OUI:20CEC4*
ID_OUI_FROM_DATABASE=Peraso Technologies
-OUI:04848A*
- ID_OUI_FROM_DATABASE=7INOVA TECHNOLOGY LIMITED
-
-OUI:20C6EB*
- ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
-
OUI:700FEC*
ID_OUI_FROM_DATABASE=Poindus Systems Corp.
OUI:FCDB96*
ID_OUI_FROM_DATABASE=ENERVALLEY CO., LTD
-OUI:FC8B97*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:882E5A*
ID_OUI_FROM_DATABASE=storONE
OUI:94756E*
ID_OUI_FROM_DATABASE=QinetiQ North America
-OUI:543D37*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:0C5521*
ID_OUI_FROM_DATABASE=Axiros GmbH
OUI:105CBF*
ID_OUI_FROM_DATABASE=DuroByte Inc
-OUI:88A3CC*
- ID_OUI_FROM_DATABASE=Amatis Controls
-
OUI:EC89F5*
ID_OUI_FROM_DATABASE=Lenovo Mobile Communication Technology Ltd.
OUI:B85810*
ID_OUI_FROM_DATABASE=NUMERA, INC.
-OUI:2CAB25*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
-OUI:AC6E1A*
- ID_OUI_FROM_DATABASE=Shenzhen Gongjin Electronics Co.,Ltd
-
OUI:9886B1*
ID_OUI_FROM_DATABASE=Flyaudio corporation (China)
OUI:A0DC04*
ID_OUI_FROM_DATABASE=Becker-Antriebe GmbH
-OUI:8CC121*
- ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
-
OUI:2CBE97*
ID_OUI_FROM_DATABASE=Ingenieurbuero Bickele und Buehler GmbH
OUI:48E1AF*
ID_OUI_FROM_DATABASE=Vity
-OUI:245FDF*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:C0A0DE*
ID_OUI_FROM_DATABASE=Multi Touch Oy
OUI:C0626B*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:74D0DC*
- ID_OUI_FROM_DATABASE=ERICSSON AB
-
OUI:B4B88D*
ID_OUI_FROM_DATABASE=Thuh Company
OUI:60F59C*
ID_OUI_FROM_DATABASE=CRU-Dataport
-OUI:C4108A*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:4C73A5*
ID_OUI_FROM_DATABASE=KOVE
OUI:3C7437*
ID_OUI_FROM_DATABASE=RIM
-OUI:04209A*
- ID_OUI_FROM_DATABASE=Panasonic AVC Networks Company
-
OUI:64DC01*
ID_OUI_FROM_DATABASE=Static Systems Group PLC
OUI:1CF5E7*
ID_OUI_FROM_DATABASE=Turtle Industry Co., Ltd.
-OUI:9C4A7B*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:2C8065*
ID_OUI_FROM_DATABASE=HARTING Inc. of North America
OUI:E0143E*
ID_OUI_FROM_DATABASE=Modoosis Inc.
-OUI:5C6984*
- ID_OUI_FROM_DATABASE=NUVICO
-
OUI:204AAA*
ID_OUI_FROM_DATABASE=Hanscan Spain S.A.
OUI:ACAB8D*
ID_OUI_FROM_DATABASE=Lyngso Marine A/S
-OUI:181456*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:E8995A*
ID_OUI_FROM_DATABASE=PiiGAB, Processinformation i Goteborg AB
OUI:D84606*
ID_OUI_FROM_DATABASE=Silicon Valley Global Marketing
-OUI:689234*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:D0E347*
ID_OUI_FROM_DATABASE=Yoga
OUI:AC5135*
ID_OUI_FROM_DATABASE=MPI TECH
-OUI:E4EC10*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:00D38D*
ID_OUI_FROM_DATABASE=Hotel Technology Next Generation
OUI:B4B5AF*
ID_OUI_FROM_DATABASE=Minsung Electronics
-OUI:044FAA*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:44568D*
ID_OUI_FROM_DATABASE=PNC Technologies Co., Ltd.
OUI:0025CB*
ID_OUI_FROM_DATABASE=Reiner SCT
-OUI:0025C4*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:0025BF*
ID_OUI_FROM_DATABASE=Wireless Cables Inc.
OUI:001F9E*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:001F92*
- ID_OUI_FROM_DATABASE=VideoIQ, Inc.
-
OUI:001F97*
ID_OUI_FROM_DATABASE=BERTANA srl
OUI:001D5D*
ID_OUI_FROM_DATABASE=Control Dynamics Pty. Ltd.
-OUI:001D2E*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:001D21*
ID_OUI_FROM_DATABASE=Alcad SL
OUI:0016E8*
ID_OUI_FROM_DATABASE=Sigma Designs, Inc.
-OUI:0016ED*
- ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc
-
OUI:0016DC*
ID_OUI_FROM_DATABASE=ARCHOS
OUI:0009D0*
ID_OUI_FROM_DATABASE=Solacom Technologies Inc.
-OUI:0009BC*
- ID_OUI_FROM_DATABASE=Digital Safety Technologies, Inc
-
OUI:0009C1*
ID_OUI_FROM_DATABASE=PROCES-DATA A/S
OUI:005001*
ID_OUI_FROM_DATABASE=YAMASHITA SYSTEMS CORP.
-OUI:0050B5*
- ID_OUI_FROM_DATABASE=FICHET-BAUCHE
-
OUI:0050B0*
ID_OUI_FROM_DATABASE=TECHNOLOGY ATLANTA CORPORATION
OUI:00A03E*
ID_OUI_FROM_DATABASE=ATM FORUM
-OUI:00A050*
- ID_OUI_FROM_DATABASE=CYPRESS SEMICONDUCTOR
-
OUI:00A098*
ID_OUI_FROM_DATABASE=NetApp
OUI:00023F*
ID_OUI_FROM_DATABASE=COMPAL ELECTRONICS, INC.
-OUI:C46699*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:383BC8*
ID_OUI_FROM_DATABASE=2Wire Inc
OUI:00150C*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:744401*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:E091F5*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:001B2F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00223F*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:E0469A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:F40B93*
ID_OUI_FROM_DATABASE=BlackBerry RTS
OUI:0896D7*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:008EF2*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:4494FC*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:20E52A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:9CD36D*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:C40415*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:08BD43*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:4C09D4*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
OUI:001A7F*
ID_OUI_FROM_DATABASE=GCI Science & Technology Co.,LTD
-OUI:00054F*
- ID_OUI_FROM_DATABASE=Private
-
OUI:D04D2C*
ID_OUI_FROM_DATABASE=Roku, Inc.
OUI:C88722*
ID_OUI_FROM_DATABASE=Lumenpulse
-OUI:FC1A11*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:30A9DE*
ID_OUI_FROM_DATABASE=LG Innotek
OUI:FC084A*
ID_OUI_FROM_DATABASE=FUJITSU LIMITED
-OUI:D4AD2D*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:48555F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:847BEB*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:F8C96C*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:34BF90*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:D467E7*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
-OUI:04C1B9*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:689361*
ID_OUI_FROM_DATABASE=Integrated Device Technology (Malaysia) Sdn. Bhd.
OUI:346AC2*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:8CD2E9*
- ID_OUI_FROM_DATABASE=NIPPON SMT Co.Ltd
-
OUI:C83DFC*
ID_OUI_FROM_DATABASE=Pioneer DJ Corporation
OUI:0004A3*
ID_OUI_FROM_DATABASE=Microchip Technology Inc.
-OUI:E0DDC0*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:982F3C*
ID_OUI_FROM_DATABASE=Sichuan Changhong Electric Ltd.
OUI:002A10*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:886AB1*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:44D6E1*
ID_OUI_FROM_DATABASE=Snuza International Pty. Ltd.
OUI:CCA260*
ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO.,LTD
-OUI:0015FF*
- ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc.
-
OUI:203CAE*
ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:A03BE3*
ID_OUI_FROM_DATABASE=Apple, Inc.
-OUI:18E29F*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:886B0F*
ID_OUI_FROM_DATABASE=Bluegiga Technologies OY
OUI:AC587B*
ID_OUI_FROM_DATABASE=JCT Healthcare
-OUI:B0B98A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:30E171*
ID_OUI_FROM_DATABASE=Hewlett Packard
-OUI:D490E0*
- ID_OUI_FROM_DATABASE=Wachendorff Automation GmbH & Co KG
-
OUI:8C3C4A*
ID_OUI_FROM_DATABASE=NAKAYO Inc
OUI:9CA3A9*
ID_OUI_FROM_DATABASE=Guangzhou Juan Optical and Electronical Tech Joint Stock Co., Ltd
-OUI:1100AA*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:002067*
- ID_OUI_FROM_DATABASE=Private
-
OUI:9893CC*
ID_OUI_FROM_DATABASE=LG ELECTRONICS INC
OUI:341E6B*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:48F97C*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:B47447*
ID_OUI_FROM_DATABASE=CoreOS
OUI:3CF862*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:0823B2*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:88C3B3*
ID_OUI_FROM_DATABASE=SOVICO
OUI:3034D2*
ID_OUI_FROM_DATABASE=Availink, Inc.
+OUI:40B034*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
OUI:CCCE1E*
ID_OUI_FROM_DATABASE=AVM Audiovisuelles Marketing und Computersysteme GmbH
OUI:501E2D*
ID_OUI_FROM_DATABASE=StreamUnlimited Engineering GmbH
-OUI:40B034*
- ID_OUI_FROM_DATABASE=Hewlett Packard
-
OUI:FC0A81*
ID_OUI_FROM_DATABASE=Extreme Networks
OUI:88E628*
ID_OUI_FROM_DATABASE=Shenzhen Kezhonglong Optoelectronic Technology Co.,Ltd
-OUI:6091F3*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:9CDA3E*
ID_OUI_FROM_DATABASE=Intel Corporate
OUI:D8325A*
ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+OUI:F04F7C*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:10AE60*
+ ID_OUI_FROM_DATABASE=Private
+
OUI:44650D*
ID_OUI_FROM_DATABASE=Amazon Technologies Inc.
OUI:2C86D2*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:F04F7C*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:10AE60*
- ID_OUI_FROM_DATABASE=Private
-
OUI:802689*
ID_OUI_FROM_DATABASE=D-Link International
-OUI:BC2F3D*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:409F38*
ID_OUI_FROM_DATABASE=AzureWave Technology Inc.
OUI:58821D*
ID_OUI_FROM_DATABASE=H. Schomäcker GmbH
+OUI:B8D7AF*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:3096FB*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
OUI:CCBE59*
ID_OUI_FROM_DATABASE=Calix Inc.
OUI:000631*
ID_OUI_FROM_DATABASE=Calix Inc.
-OUI:B8D7AF*
- ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
-
-OUI:3096FB*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:F0EE10*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:A8A198*
- ID_OUI_FROM_DATABASE=TCT mobile ltd
-
OUI:107D1A*
ID_OUI_FROM_DATABASE=Dell Inc.
-OUI:C0D012*
- ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:A8A198*
+ ID_OUI_FROM_DATABASE=TCT mobile ltd
OUI:D4DCCD*
ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:14BD61*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:C0D012*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
OUI:0827CE*
ID_OUI_FROM_DATABASE=NAGANO KEIKI CO., LTD.
OUI:F8BE0D*
ID_OUI_FROM_DATABASE=A2UICT Co.,Ltd.
+OUI:5CC6E9*
+ ID_OUI_FROM_DATABASE=Edifier International
+
OUI:08EA40*
ID_OUI_FROM_DATABASE=SHENZHEN BILIAN ELECTRONIC CO.,LTD
OUI:00E0DA*
ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
-OUI:5CC6E9*
- ID_OUI_FROM_DATABASE=Edifier International
+OUI:1868CB*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
OUI:E8C1D7*
ID_OUI_FROM_DATABASE=Philips
-OUI:1868CB*
- ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
-
OUI:F80BCB*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:24EA40*
+ ID_OUI_FROM_DATABASE=Helmholz GmbH & Co. KG
+
OUI:9CC8AE*
ID_OUI_FROM_DATABASE=Becton, Dickinson and Company
OUI:B0359F*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:24EA40*
- ID_OUI_FROM_DATABASE=Helmholz GmbH & Co. KG
-
OUI:84A9C4*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
OUI:9CAF6F*
ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
-OUI:105887*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+OUI:907065*
+ ID_OUI_FROM_DATABASE=Texas Instruments
OUI:9C061B*
ID_OUI_FROM_DATABASE=Hangzhou H3C Technologies Co., Limited
-OUI:907065*
- ID_OUI_FROM_DATABASE=Texas Instruments
-
-OUI:C4ABB2*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+OUI:A08E78*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:B8FFB3*
ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
-OUI:A08E78*
- ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
-
OUI:E0D55E*
ID_OUI_FROM_DATABASE=GIGA-BYTE TECHNOLOGY CO.,LTD.
OUI:78BDBC*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:20F452*
- ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd
-
OUI:D47AE2*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:20F452*
+ ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd
+
OUI:88D274*
ID_OUI_FROM_DATABASE=zte corporation
OUI:986DC8*
ID_OUI_FROM_DATABASE=TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION
-OUI:982DBA*
- ID_OUI_FROM_DATABASE=Fibergate Inc.
-
OUI:0040AA*
ID_OUI_FROM_DATABASE=Valmet Automation
+OUI:982DBA*
+ ID_OUI_FROM_DATABASE=Fibergate Inc.
+
OUI:0080C2*
ID_OUI_FROM_DATABASE=IEEE 802.1 Working Group
OUI:6CC1D2*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:D82522*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:70B14E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:14D4FE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:707630*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:90C792*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:789684*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:CC65AD*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:986B3D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:5CE30E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:7823AE*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
OUI:F80BBE*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:5C571A*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:D82522*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:70B14E*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:14D4FE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:002374*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
OUI:E8ED05*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:707630*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:90C792*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:789684*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:CC65AD*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:986B3D*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
-OUI:5CE30E*
+OUI:2C7E81*
ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-OUI:7823AE*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+OUI:84C0EF*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:447F77*
ID_OUI_FROM_DATABASE=Connected Home
-OUI:2C7E81*
- ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
-
OUI:009AD2*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
-OUI:84C0EF*
- ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-
OUI:7C1C68*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:88B111*
ID_OUI_FROM_DATABASE=Intel Corporate
-OUI:54D751*
- ID_OUI_FROM_DATABASE=Proximus
-
OUI:D8F1F0*
ID_OUI_FROM_DATABASE=Pepxim International Limited
OUI:0019F0*
ID_OUI_FROM_DATABASE=UNIONMAN TECHNOLOGY CO.,LTD
+OUI:54D751*
+ ID_OUI_FROM_DATABASE=Proximus
+
OUI:506E92*
ID_OUI_FROM_DATABASE=Innocent Technology Co., Ltd.
OUI:CC03D9*
ID_OUI_FROM_DATABASE=Cisco Meraki
+OUI:BCADAB*
+ ID_OUI_FROM_DATABASE=Avaya Inc
+
OUI:506184*
ID_OUI_FROM_DATABASE=Avaya Inc
OUI:A01290*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:B4A95A*
+OUI:3C3A73*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:BCADAB*
+OUI:B4A95A*
ID_OUI_FROM_DATABASE=Avaya Inc
-OUI:3C3A73*
- ID_OUI_FROM_DATABASE=Avaya Inc
+OUI:6CB227*
+ ID_OUI_FROM_DATABASE=Sony Video & Sound Products Inc.
OUI:60271C*
ID_OUI_FROM_DATABASE=VIDEOR E. Hartig GmbH
+OUI:C46699*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:FC1A11*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:E0DDC0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:886AB1*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:18E29F*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F81D90*
+ ID_OUI_FROM_DATABASE=Solidwintech
+
+OUI:0823B2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:6091F3*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:BC2F3D*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:C4ABB2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:C8DB26*
+ ID_OUI_FROM_DATABASE=Logitech
+
+OUI:4473D6*
+ ID_OUI_FROM_DATABASE=Logitech
+
+OUI:70F35A*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:EC42B4*
+ ID_OUI_FROM_DATABASE=ADC Corporation
+
+OUI:10CDB6*
+ ID_OUI_FROM_DATABASE=Essential Products, Inc.
+
+OUI:08306B*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:6CF9D2*
+ ID_OUI_FROM_DATABASE=Chengdu Goods for the Road Electronic Technology C
+
+OUI:641666*
+ ID_OUI_FROM_DATABASE=Nest Labs Inc.
+
+OUI:3817E1*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:94147A*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:74D0DC*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:88A3CC*
+ ID_OUI_FROM_DATABASE=Amatis Controls
+
+OUI:8C9F3B*
+ ID_OUI_FROM_DATABASE=Qingdao Hisense Communications Co.,Ltd.
+
+OUI:404229*
+ ID_OUI_FROM_DATABASE=Layer3TV, Inc
+
+OUI:B090D4*
+ ID_OUI_FROM_DATABASE=Shenzhen Hoin Internet Technology Co., Ltd
+
+OUI:348F27*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001D2E*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:689234*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:044FAA*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:0025C4*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:38FF36*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:2C5D93*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:543D37*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:C4108A*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:D463C6*
+ ID_OUI_FROM_DATABASE=Motorola Mobility LLC, a Lenovo Company
+
+OUI:00A050*
+ ID_OUI_FROM_DATABASE=CYPRESS SEMICONDUCTOR
+
+OUI:54666C*
+ ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+
+OUI:A44CC8*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
+OUI:0840F3*
+ ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
+
+OUI:103034*
+ ID_OUI_FROM_DATABASE=Cara Systems
+
+OUI:FC8B97*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:2CAB25*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:AC6E1A*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:24A534*
+ ID_OUI_FROM_DATABASE=SynTrust Tech International Ltd.
+
+OUI:F844E3*
+ ID_OUI_FROM_DATABASE=Taicang T&W Electronics
+
+OUI:001F92*
+ ID_OUI_FROM_DATABASE=Avigilon Corporation
+
+OUI:0C8FFF*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:54B121*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:786256*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A80C63*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5CC307*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:08A8A1*
+ ID_OUI_FROM_DATABASE=Cyclotronics Power Concepts, Inc
+
+OUI:887A31*
+ ID_OUI_FROM_DATABASE=Velankani Electronics Pvt. Ltd.
+
+OUI:8C0F6F*
+ ID_OUI_FROM_DATABASE=PEGATRON CORPORATION
+
+OUI:283545*
+ ID_OUI_FROM_DATABASE=SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD
+
+OUI:A82BB5*
+ ID_OUI_FROM_DATABASE=Edgecore Networks Corporation
+
+OUI:88365F*
+ ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+
+OUI:0015FF*
+ ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc.
+
+OUI:788C4D*
+ ID_OUI_FROM_DATABASE=Indyme Solutions, LLC
+
+OUI:A8B2DA*
+ ID_OUI_FROM_DATABASE=FUJITSU LIMITED
+
+OUI:0CB937*
+ ID_OUI_FROM_DATABASE=Ubee Interactive Co., Limited
+
+OUI:2880A2*
+ ID_OUI_FROM_DATABASE=Novatel Wireless Solutions, Inc.
+
+OUI:0CB459*
+ ID_OUI_FROM_DATABASE=Marketech International Corp.
+
+OUI:84AA9C*
+ ID_OUI_FROM_DATABASE=MitraStar Technology Corp.
+
+OUI:0C4B54*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:C47154*
+ ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+
+OUI:44EA4B*
+ ID_OUI_FROM_DATABASE=Actlas Inc.
+
+OUI:5C6984*
+ ID_OUI_FROM_DATABASE=NUVICO
+
+OUI:F86EEE*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:E4FB5D*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:5C546D*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:508F4C*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:0027F8*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:50EB1A*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:CC4E24*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:889471*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:D81FCC*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:002067*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:0060DF*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:000533*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00223F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:001B2F*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E091F5*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:744401*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E0469A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:08BD43*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:C40415*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:9CD36D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:20E52A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:4494FC*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:008EF2*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:B0B98A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:1100AA*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:1C965A*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:104E89*
+ ID_OUI_FROM_DATABASE=Garmin International
+
+OUI:30053F*
+ ID_OUI_FROM_DATABASE=JTI Co.,Ltd.
+
+OUI:0050B5*
+ ID_OUI_FROM_DATABASE=FICHET SECURITE ELECTRONIQUE
+
+OUI:04209A*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:8CC121*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:20C6EB*
+ ID_OUI_FROM_DATABASE=Panasonic Corporation AVC Networks Company
+
+OUI:B0350B*
+ ID_OUI_FROM_DATABASE=MOBIWIRE MOBILES (NINGBO) CO.,LTD
+
+OUI:28A6AC*
+ ID_OUI_FROM_DATABASE=seca gmbh & co. kg
+
+OUI:00054F*
+ ID_OUI_FROM_DATABASE=Garmin International
+
+OUI:40CE24*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:24C42F*
+ ID_OUI_FROM_DATABASE=Philips Lifeline
+
+OUI:E048D3*
+ ID_OUI_FROM_DATABASE=MOBIWIRE MOBILES (NINGBO) CO.,LTD
+
+OUI:B8EE0E*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:78886D*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:A85C2C*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:00DB70*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:181456*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:E4EC10*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:9C4A7B*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:386EA2*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:58B42D*
+ ID_OUI_FROM_DATABASE=YSTen Technology Co.,Ltd
+
+OUI:48EC5B*
+ ID_OUI_FROM_DATABASE=Nokia
+
+OUI:D86162*
+ ID_OUI_FROM_DATABASE=Wistron Neweb Corporation
+
+OUI:80615F*
+ ID_OUI_FROM_DATABASE=Beijing Sinead Technology Co., Ltd.
+
+OUI:0009BC*
+ ID_OUI_FROM_DATABASE=Utility, Inc
+
+OUI:0016ED*
+ ID_OUI_FROM_DATABASE=Utility, Inc
+
+OUI:74F661*
+ ID_OUI_FROM_DATABASE=Schneider Electric Fire & Security Oy
+
+OUI:245FDF*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:885DFB*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:608CE6*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:8CD2E9*
+ ID_OUI_FROM_DATABASE=YOKOTE SEIKO CO., LTD.
+
+OUI:186024*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:74F91A*
+ ID_OUI_FROM_DATABASE=Onface
+
+OUI:706BB9*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:6CC147*
+ ID_OUI_FROM_DATABASE=Xiamen Hanin Electronic Technology Co., Ltd
+
+OUI:8CFEB4*
+ ID_OUI_FROM_DATABASE=VSOONTECH ELECTRONICS CO., LIMITED
+
+OUI:CCF957*
+ ID_OUI_FROM_DATABASE=u-blox AG
+
+OUI:74373B*
+ ID_OUI_FROM_DATABASE=UNINET Co.,Ltd.
+
+OUI:7C6456*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:448F17*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co., Ltd. ARTIK
+
+OUI:0076B1*
+ ID_OUI_FROM_DATABASE=Somfy-Protect By Myfox SAS
+
+OUI:D0666D*
+ ID_OUI_FROM_DATABASE=Shenzhen Bus-Lan Technology Co., Ltd.
+
+OUI:B8D94D*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:10FCB6*
+ ID_OUI_FROM_DATABASE=mirusystems CO.,LTD
+
+OUI:04D6AA*
+ ID_OUI_FROM_DATABASE=SAMSUNG ELECTRO-MECHANICS(THAILAND)
+
+OUI:08661F*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:0C5842*
+ ID_OUI_FROM_DATABASE=DME Micro
+
+OUI:A468BC*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:80C755*
+ ID_OUI_FROM_DATABASE=Panasonic Appliances Company
+
+OUI:A0648F*
+ ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
+
+OUI:D467E7*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:34BF90*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F8C96C*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:48555F*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:D4AD2D*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:D00492*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:809FAB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:9C88AD*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:48F97C*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:105887*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:5CE3B6*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:04C1B9*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:04848A*
+ ID_OUI_FROM_DATABASE=7INOVA TECHNOLOGY LIMITED
+
+OUI:E81DA8*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:3CC079*
+ ID_OUI_FROM_DATABASE=Shenzhen One-Nine Intelligent Electronic Science and Technology Co., Ltd
+
+OUI:746EE4*
+ ID_OUI_FROM_DATABASE=Asia Vital Components Co.,Ltd.
+
+OUI:F44C70*
+ ID_OUI_FROM_DATABASE=Skyworth Digital Technology(Shenzhen) Co.,Ltd
+
+OUI:98C5DB*
+ ID_OUI_FROM_DATABASE=Ericsson AB
+
+OUI:043A0D*
+ ID_OUI_FROM_DATABASE=SM Optics S.r.l.
+
+OUI:9CE063*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:9C9C40*
+ ID_OUI_FROM_DATABASE=SICHUAN TIANYI COMHEART TELECOMCO., LTD
+
+OUI:D490E0*
+ ID_OUI_FROM_DATABASE=Topcon Electronics GmbH & Co. KG
+
+OUI:E8361D*
+ ID_OUI_FROM_DATABASE=Sense Labs, Inc.
+
+OUI:EC7D11*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
OUI:2C3996*
ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
OUI:1C7839*
ID_OUI_FROM_DATABASE=Shenzhen Tencent Computer System Co., Ltd.
-OUI:D837BE*
- ID_OUI_FROM_DATABASE=Shanghai Gongjing Telecom Technology Co,LTD
-
OUI:A4516F*
ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
OUI:9CC172*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
-OUI:0014C9*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:00010F*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:080088*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
-OUI:00051E*
- ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
-
OUI:384608*
ID_OUI_FROM_DATABASE=zte corporation
OUI:D0C0BF*
ID_OUI_FROM_DATABASE=Actions Microelectronics Co., Ltd
-OUI:94F665*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:E04B45*
ID_OUI_FROM_DATABASE=Hi-P Electronics Pte Ltd
OUI:8C7967*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:D083D4*
- ID_OUI_FROM_DATABASE=XTel ApS
-
OUI:78F944*
ID_OUI_FROM_DATABASE=Private
OUI:70FF5C*
ID_OUI_FROM_DATABASE=Cheerzing Communication(Xiamen)Technology Co.,Ltd
-OUI:E0107F*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:08115E*
ID_OUI_FROM_DATABASE=Bitel Co., Ltd.
OUI:20A99B*
ID_OUI_FROM_DATABASE=Microsoft Corporation
-OUI:6C7660*
- ID_OUI_FROM_DATABASE=KYOCERA Corporation
-
OUI:A0A3E2*
ID_OUI_FROM_DATABASE=Actiontec Electronics, Inc
OUI:8C5D60*
ID_OUI_FROM_DATABASE=UCI Corporation Co.,Ltd.
-OUI:104B46*
- ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
-
OUI:4C0BBE*
ID_OUI_FROM_DATABASE=Microsoft
OUI:481A84*
ID_OUI_FROM_DATABASE=Pointer Telocation Ltd
-OUI:E4F4C6*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:DC663A*
ID_OUI_FROM_DATABASE=Apacer Technology Inc.
OUI:B06971*
ID_OUI_FROM_DATABASE=DEI Sales, Inc.
-OUI:58493B*
- ID_OUI_FROM_DATABASE=Palo Alto Networks
-
OUI:580528*
ID_OUI_FROM_DATABASE=LABRIS NETWORKS
OUI:AC3CB4*
ID_OUI_FROM_DATABASE=Nilan A/S
-OUI:A830AD*
- ID_OUI_FROM_DATABASE=Wei Fang Goertek Electronics Co.,Ltd
-
OUI:8007A2*
ID_OUI_FROM_DATABASE=Esson Technology Inc.
OUI:18421D*
ID_OUI_FROM_DATABASE=Private
-OUI:78617C*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD
-
OUI:C401B1*
ID_OUI_FROM_DATABASE=SeekTech INC
OUI:58E808*
ID_OUI_FROM_DATABASE=AUTONICS CORPORATION
-OUI:B8C716*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:8058C5*
ID_OUI_FROM_DATABASE=NovaTec Kommunikationstechnik GmbH
OUI:144C1A*
ID_OUI_FROM_DATABASE=Max Communication GmbH
-OUI:FCE557*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:BC6E76*
ID_OUI_FROM_DATABASE=Green Energy Options Ltd
OUI:48C8B6*
ID_OUI_FROM_DATABASE=SysTec GmbH
-OUI:303855*
- ID_OUI_FROM_DATABASE=Nokia Corporation
-
OUI:9C4563*
ID_OUI_FROM_DATABASE=DIMEP Sistemas
OUI:34A183*
ID_OUI_FROM_DATABASE=AWare, Inc
-OUI:740ABC*
- ID_OUI_FROM_DATABASE=JSJS Designs (Europe) Limited
-
OUI:588D09*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
OUI:B45861*
ID_OUI_FROM_DATABASE=CRemote, LLC
-OUI:AC6706*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:B8653B*
ID_OUI_FROM_DATABASE=Bolymin, Inc.
OUI:00198D*
ID_OUI_FROM_DATABASE=Ocean Optics, Inc.
-OUI:00197F*
- ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
-
OUI:001986*
ID_OUI_FROM_DATABASE=Cheng Hongjian
OUI:001398*
ID_OUI_FROM_DATABASE=TrafficSim Co.,Ltd
-OUI:001392*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:00138C*
ID_OUI_FROM_DATABASE=Kumyoung.Co.Ltd
OUI:000BFE*
ID_OUI_FROM_DATABASE=CASTEL Broadband Limited
-OUI:000C03*
- ID_OUI_FROM_DATABASE=HDMI Licensing, LLC
-
OUI:000CA4*
ID_OUI_FROM_DATABASE=Prompttec Product Management GmbH
OUI:00A0F6*
ID_OUI_FROM_DATABASE=AutoGas Systems Inc.
-OUI:00A096*
- ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO., LTD.
-
OUI:00A006*
ID_OUI_FROM_DATABASE=IMAGE DATA PROCESSING SYSTEM GROUP
OUI:0016E3*
ID_OUI_FROM_DATABASE=ASKEY COMPUTER CORP
-OUI:30469A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:0026F2*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:00184D*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:001E2A*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:E8FCAF*
- ID_OUI_FROM_DATABASE=NETGEAR
-
-OUI:4C60DE*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:00300A*
ID_OUI_FROM_DATABASE=Aztech Electronics Pte Ltd
-OUI:A06391*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:9CC7A6*
ID_OUI_FROM_DATABASE=AVM GmbH
-OUI:DCEF09*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:743170*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
OUI:0012BF*
ID_OUI_FROM_DATABASE=Arcadyan Technology Corporation
-OUI:200CC8*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:04FE8D*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
OUI:7864E6*
ID_OUI_FROM_DATABASE=Green Motive Technology Limited
-OUI:743E2B*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:C0CCF8*
ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:000AC2*
ID_OUI_FROM_DATABASE=Wuhan FiberHome Digital Technology Co.,Ltd.
-OUI:F08CFB*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:D4F207*
ID_OUI_FROM_DATABASE=DIAODIAO(Beijing)Technology CO.,Ltd
OUI:9CDF03*
ID_OUI_FROM_DATABASE=Harman/Becker Automotive Systems GmbH
-OUI:F0407B*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:94885E*
ID_OUI_FROM_DATABASE=Surfilter Network Technology Co., Ltd.
OUI:8C9351*
ID_OUI_FROM_DATABASE=Jigowatts Inc.
-OUI:D838FC*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:00248D*
ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
OUI:48DF37*
ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
-OUI:9C93E4*
- ID_OUI_FROM_DATABASE=Private
-
-OUI:005079*
- ID_OUI_FROM_DATABASE=Private
-
OUI:0028F8*
ID_OUI_FROM_DATABASE=Intel Corporate
OUI:882BD7*
ID_OUI_FROM_DATABASE=ADDÉNERGIE TECHNOLOGIES
-OUI:9CA5C0*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:B4A5EF*
ID_OUI_FROM_DATABASE=Sercomm Corporation.
OUI:58528A*
ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
-OUI:BCC00F*
- ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
-
OUI:B0C287*
ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
OUI:F8BBBF*
ID_OUI_FROM_DATABASE=eero inc.
-OUI:0CF4D5*
- ID_OUI_FROM_DATABASE=Ruckus Wireless
-
OUI:000130*
ID_OUI_FROM_DATABASE=Extreme Networks
OUI:049573*
ID_OUI_FROM_DATABASE=zte corporation
-OUI:001D44*
- ID_OUI_FROM_DATABASE=Krohne
-
OUI:48BF6B*
ID_OUI_FROM_DATABASE=Apple, Inc.
OUI:0020DA*
ID_OUI_FROM_DATABASE=Alcatel-Lucent Enterprise
-OUI:1CDA27*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:345BBB*
ID_OUI_FROM_DATABASE=GD Midea Air-Conditioning Equipment Co.,Ltd.
OUI:B4C6F8*
ID_OUI_FROM_DATABASE=Axilspot Communication
-OUI:70D923*
- ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
-
OUI:B83A08*
ID_OUI_FROM_DATABASE=Tenda Technology Co.,Ltd.Dongguan branch
OUI:503DA1*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
-OUI:A040A0*
- ID_OUI_FROM_DATABASE=NETGEAR
-
OUI:508569*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
OUI:000CAB*
ID_OUI_FROM_DATABASE=Commend International GmbH
+
+OUI:00EC0A*
+ ID_OUI_FROM_DATABASE=Xiaomi Communications Co Ltd
+
+OUI:A86B7C*
+ ID_OUI_FROM_DATABASE=SHENZHEN FENGLIAN TECHNOLOGY CO., LTD.
+
+OUI:9CA5C0*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:1CDA27*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:70D923*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
+
+OUI:F430B9*
+ ID_OUI_FROM_DATABASE=Hewlett Packard
+
+OUI:2C9EEC*
+ ID_OUI_FROM_DATABASE=Jabil Circuit Penang
+
+OUI:943FC2*
+ ID_OUI_FROM_DATABASE=Hewlett Packard Enterprise
+
+OUI:A06A44*
+ ID_OUI_FROM_DATABASE=Vizio, Inc
+
+OUI:B44F96*
+ ID_OUI_FROM_DATABASE=Zhejiang Xinzailing Technology co., ltd
+
+OUI:D822F4*
+ ID_OUI_FROM_DATABASE=Avnet Silica
+
+OUI:58493B*
+ ID_OUI_FROM_DATABASE=Palo Alto Networks
+
+OUI:D083D4*
+ ID_OUI_FROM_DATABASE=Xtel Wireless ApS
+
+OUI:7CEB7F*
+ ID_OUI_FROM_DATABASE=Dmet Products Corp.
+
+OUI:8C8580*
+ ID_OUI_FROM_DATABASE=Smart Innovation LLC
+
+OUI:C4571F*
+ ID_OUI_FROM_DATABASE=June Life Inc
+
+OUI:FC5A1D*
+ ID_OUI_FROM_DATABASE=Hitron Technologies. Inc
+
+OUI:287B09*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:4859A4*
+ ID_OUI_FROM_DATABASE=zte corporation
+
+OUI:3894E0*
+ ID_OUI_FROM_DATABASE=Syrotech Networks. Ltd.
+
+OUI:34F64B*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:ACED5C*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:18204C*
+ ID_OUI_FROM_DATABASE=Kummler+Matter AG
+
+OUI:740ABC*
+ ID_OUI_FROM_DATABASE=LightwaveRF Technology Ltd
+
+OUI:54BD79*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:D86C63*
+ ID_OUI_FROM_DATABASE=Google, Inc.
+
+OUI:743E2B*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:D838FC*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:0CF4D5*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:AC6706*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:94F665*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:E0107F*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:001392*
+ ID_OUI_FROM_DATABASE=Ruckus Wireless
+
+OUI:7811DC*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
+OUI:D837BE*
+ ID_OUI_FROM_DATABASE=SHENZHEN GONGJIN ELECTRONICS CO.,LT
+
+OUI:DC44B6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:1007B6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:F4939F*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co., Ltd.
+
+OUI:000C03*
+ ID_OUI_FROM_DATABASE=HDMI Licensing, LLC
+
+OUI:CC2F71*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:F82819*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:F4B520*
+ ID_OUI_FROM_DATABASE=Biostar Microtech international corp.
+
+OUI:9C93E4*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:D4B27A*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:F0F8F2*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:341513*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:64CFD9*
+ ID_OUI_FROM_DATABASE=Texas Instruments
+
+OUI:24B2DE*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:50E971*
+ ID_OUI_FROM_DATABASE=Jibo, Inc.
+
+OUI:50642B*
+ ID_OUI_FROM_DATABASE=XIAOMI Electronics,CO.,LTD
+
+OUI:909D7D*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:84A1D1*
+ ID_OUI_FROM_DATABASE=Sagemcom Broadband SAS
+
+OUI:783690*
+ ID_OUI_FROM_DATABASE=Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd
+
+OUI:788102*
+ ID_OUI_FROM_DATABASE=Sercomm Corporation.
+
+OUI:58A0CB*
+ ID_OUI_FROM_DATABASE=TrackNet, Inc
+
+OUI:586163*
+ ID_OUI_FROM_DATABASE=Quantum Networks (SG) Pte. Ltd.
+
+OUI:3C7843*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:A47758*
+ ID_OUI_FROM_DATABASE=Ningbo Freewings Technologies Co.,Ltd
+
+OUI:00051E*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:080088*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00010F*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00197F*
+ ID_OUI_FROM_DATABASE=PLANTRONICS, INC.
+
+OUI:E4F4C6*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:001E2A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:0014C9*
+ ID_OUI_FROM_DATABASE=Brocade Communications Systems, Inc.
+
+OUI:00184D*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:0026F2*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:30469A*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:4C60DE*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:E8FCAF*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:200CC8*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:DCEF09*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A06391*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:A040A0*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:8C3BAD*
+ ID_OUI_FROM_DATABASE=NETGEAR
+
+OUI:005079*
+ ID_OUI_FROM_DATABASE=Private
+
+OUI:F86465*
+ ID_OUI_FROM_DATABASE=Anova Applied Electronics, Inc.
+
+OUI:A830AD*
+ ID_OUI_FROM_DATABASE=Weifang GoerTek Technology Co.,Ltd.
+
+OUI:70E1FD*
+ ID_OUI_FROM_DATABASE=FLEXTRONICS
+
+OUI:001D44*
+ ID_OUI_FROM_DATABASE=Krohne
+
+OUI:D4D2E5*
+ ID_OUI_FROM_DATABASE=BKAV Corporation
+
+OUI:C06D1A*
+ ID_OUI_FROM_DATABASE=Tianjin Henxinhuifeng Technology Co.,Ltd.
+
+OUI:3432E6*
+ ID_OUI_FROM_DATABASE=Panasonic Industrial Devices Europe GmbH
+
+OUI:40A3CC*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:E470B8*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:B019C6*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:58E28F*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:AC1F74*
+ ID_OUI_FROM_DATABASE=Apple, Inc.
+
+OUI:303855*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:FCE557*
+ ID_OUI_FROM_DATABASE=Nokia Corporation
+
+OUI:9C305B*
+ ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+
+OUI:00289F*
+ ID_OUI_FROM_DATABASE=Semptian Co., Ltd.
+
+OUI:8C4500*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:6C7660*
+ ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
+
+OUI:104B46*
+ ID_OUI_FROM_DATABASE=Mitsubishi Electric Corporation
+
+OUI:903DBD*
+ ID_OUI_FROM_DATABASE=SECURE METERS LIMITED
+
+OUI:384F49*
+ ID_OUI_FROM_DATABASE=Juniper Networks
+
+OUI:A491B1*
+ ID_OUI_FROM_DATABASE=Technicolor
+
+OUI:8CD48E*
+ ID_OUI_FROM_DATABASE=ITEL MOBILE LIMITED
+
+OUI:642B8A*
+ ID_OUI_FROM_DATABASE=ALL BEST Industrial Co., Ltd.
+
+OUI:68ECC5*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
+OUI:CC9891*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:1C7022*
+ ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+
+OUI:947EB9*
+ ID_OUI_FROM_DATABASE=National Narrowband Network Communications Pty Ltd
+
+OUI:4CBD8F*
+ ID_OUI_FROM_DATABASE=Hangzhou Hikvision Digital Technology Co.,Ltd.
+
+OUI:B4D64E*
+ ID_OUI_FROM_DATABASE=Caldero Limited
+
+OUI:F89DBB*
+ ID_OUI_FROM_DATABASE=Tintri
+
+OUI:D4389C*
+ ID_OUI_FROM_DATABASE=Sony Mobile Communications AB
+
+OUI:104963*
+ ID_OUI_FROM_DATABASE=HARTING K.K.
+
+OUI:646E69*
+ ID_OUI_FROM_DATABASE=Liteon Technology Corporation
+
+OUI:BC3D85*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:B0E17E*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:74D21D*
+ ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+
+OUI:44C874*
+ ID_OUI_FROM_DATABASE=China Mobile Group Device Co.,Ltd.
+
+OUI:98EF9B*
+ ID_OUI_FROM_DATABASE=OHSUNG
+
+OUI:84E327*
+ ID_OUI_FROM_DATABASE=TAILYN TECHNOLOGIES INC
+
+OUI:7091F3*
+ ID_OUI_FROM_DATABASE=Universal Electronics, Inc.
+
+OUI:68C63A*
+ ID_OUI_FROM_DATABASE=Espressif Inc.
+
+OUI:F4E204*
+ ID_OUI_FROM_DATABASE=Traqueur
+
+OUI:3456FE*
+ ID_OUI_FROM_DATABASE=Cisco Meraki
+
+OUI:08674E*
+ ID_OUI_FROM_DATABASE=Hisense broadband multimedia technology Co.,Ltd
+
+OUI:F08CFB*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:F0407B*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:BCC00F*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:6405E9*
+ ID_OUI_FROM_DATABASE=Shenzhen WayOS Technology Crop., Ltd.
+
+OUI:B8C716*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:50A83A*
+ ID_OUI_FROM_DATABASE=S Mobile Devices Limited
+
+OUI:EC8AC7*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:E084F3*
+ ID_OUI_FROM_DATABASE=High Grade Controls Corporation
+
+OUI:74BBD3*
+ ID_OUI_FROM_DATABASE=Shenzhen xeme Communication Co., Ltd.
+
+OUI:D8ED1C*
+ ID_OUI_FROM_DATABASE=Magna Technology SL
+
+OUI:78617C*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:00A096*
+ ID_OUI_FROM_DATABASE=MITSUMI ELECTRIC CO.,LTD.
+
+OUI:A07099*
+ ID_OUI_FROM_DATABASE=Beijing Huacan Electronics Co., Ltd
+
+OUI:B0935B*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:20F19E*
+ ID_OUI_FROM_DATABASE=ARRIS Group, Inc.
+
+OUI:389D92*
+ ID_OUI_FROM_DATABASE=Seiko Epson Corporation
+
+OUI:74860B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:C0174D*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:A407B6*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:149F3C*
+ ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+
+OUI:149FB6*
+ ID_OUI_FROM_DATABASE=GUANGDONG GENIUS TECHNOLOGY CO.,LTD.
+
+OUI:7C1C4E*
+ ID_OUI_FROM_DATABASE=LG Innotek
+
+OUI:70708B*
+ ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+
+OUI:BC903A*
+ ID_OUI_FROM_DATABASE=Robert Bosch GmbH
+
+OUI:603D26*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
+OUI:3820A8*
+ ID_OUI_FROM_DATABASE=ColorTokens, Inc.
+
+OUI:705896*
+ ID_OUI_FROM_DATABASE=InShow Technology
+
+OUI:D05995*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:54DF24*
+ ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+
+OUI:78870D*
+ ID_OUI_FROM_DATABASE=Unifiedgateways India Private Limited
+
+OUI:3CA616*
+ ID_OUI_FROM_DATABASE=vivo Mobile Communication Co., Ltd.
acpi:AUTH*:
ID_VENDOR_FROM_DATABASE=AuthenTec
+acpi:BOOT*:
+ ID_VENDOR_FROM_DATABASE=Coreboot Project
+
acpi:BOSC*:
ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH
acpi:ESSX*:
ID_VENDOR_FROM_DATABASE=Everest Semiconductor Co., Ltd.
+acpi:EXAR*:
+ ID_VENDOR_FROM_DATABASE=Exar Corporation
+
acpi:FRSC*:
ID_VENDOR_FROM_DATABASE=Freescale, Inc
acpi:MIPI*:
ID_VENDOR_FROM_DATABASE=MIPI Alliance
+acpi:MRVL*:
+ ID_VENDOR_FROM_DATABASE=Marvell Technology Group Ltd.
+
acpi:MSAY*:
ID_VENDOR_FROM_DATABASE=Microsoft Corporation
acpi:BBL*:
ID_VENDOR_FROM_DATABASE=Brain Boxes Limited
+acpi:BBX*:
+ ID_VENDOR_FROM_DATABASE=Black Box Corporation
+
acpi:BCC*:
ID_VENDOR_FROM_DATABASE=Beaver Computer Corporaton
acpi:CHP*:
ID_VENDOR_FROM_DATABASE=CH Products
+acpi:CHR*:
+ ID_VENDOR_FROM_DATABASE=christmann informationstechnik + medien GmbH & Co. KG
+
acpi:CHS*:
ID_VENDOR_FROM_DATABASE=Agentur Chairos
acpi:GGL*:
ID_VENDOR_FROM_DATABASE=Google Inc.
+acpi:GGT*:
+ ID_VENDOR_FROM_DATABASE=G2TOUCH KOREA
+
acpi:GIC*:
ID_VENDOR_FROM_DATABASE=General Inst. Corporation
acpi:HYD*:
ID_VENDOR_FROM_DATABASE=Hydis Technologies.Co.,LTD
+acpi:HYL*:
+ ID_VENDOR_FROM_DATABASE=Shanghai Chai Ming Huang Info&Tech Co, Ltd
+
acpi:HYO*:
ID_VENDOR_FROM_DATABASE=HYC CO., LTD.
acpi:MVN*:
ID_VENDOR_FROM_DATABASE=Meta Company
+acpi:MVR*:
+ ID_VENDOR_FROM_DATABASE=MediCapture, Inc.
+
acpi:MVS*:
ID_VENDOR_FROM_DATABASE=Microvision
acpi:PMM*:
ID_VENDOR_FROM_DATABASE=Point Multimedia System
+acpi:PMS*:
+ ID_VENDOR_FROM_DATABASE=Pabian Embedded Systems
+
acpi:PMT*:
ID_VENDOR_FROM_DATABASE=Promate Electronic Co., Ltd.
acpi:PNS*:
ID_VENDOR_FROM_DATABASE=PanaScope
+acpi:PNT*:
+ ID_VENDOR_FROM_DATABASE=HOYA Corporation PENTAX Lifecare Division
+
acpi:PNX*:
ID_VENDOR_FROM_DATABASE=Phoenix Technologies, Ltd.
acpi:TCE*:
ID_VENDOR_FROM_DATABASE=Century Corporation
+acpi:TCF*:
+ ID_VENDOR_FROM_DATABASE=Televic Conference
+
acpi:TCH*:
ID_VENDOR_FROM_DATABASE=Interaction Systems, Inc
acpi:TEL*:
ID_VENDOR_FROM_DATABASE=Promotion and Display Technology Ltd.
+acpi:TEN*:
+ ID_VENDOR_FROM_DATABASE=Tencent
+
acpi:TER*:
ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
acpi:TLL*:
ID_VENDOR_FROM_DATABASE=Thinklogical
+acpi:TLN*:
+ ID_VENDOR_FROM_DATABASE=Techlogix Networx
+
acpi:TLS*:
ID_VENDOR_FROM_DATABASE=Teleste Educational OY
acpi:TRN*:
ID_VENDOR_FROM_DATABASE=Datacommunicatie Tron B.V.
+acpi:TRP*:
+ ID_VENDOR_FROM_DATABASE=TRAPEZE GROUP
+
acpi:TRS*:
ID_VENDOR_FROM_DATABASE=Torus Systems Ltd
ID_VENDOR_FROM_DATABASE=Rhino Equipment Corp.
pci:v00000B0Bd00000105*
- ID_MODEL_FROM_DATABASE=Rhino R1T1
+ ID_MODEL_FROM_DATABASE=R1T1
pci:v00000B0Bd00000205*
- ID_MODEL_FROM_DATABASE=Rhino R4FXO
+ ID_MODEL_FROM_DATABASE=R4FXO
pci:v00000B0Bd00000206*
ID_MODEL_FROM_DATABASE=RCB4FXO 4-channel FXO analog telphony card
pci:v00000B0Bd00000305*
- ID_MODEL_FROM_DATABASE=Rhino R4T1
+ ID_MODEL_FROM_DATABASE=R4T1
pci:v00000B0Bd00000405*
- ID_MODEL_FROM_DATABASE=Rhino R8FXX
+ ID_MODEL_FROM_DATABASE=R8FXX
pci:v00000B0Bd00000406*
ID_MODEL_FROM_DATABASE=RCB8FXX 8-channel modular analog telphony card
pci:v00000B0Bd00000505*
- ID_MODEL_FROM_DATABASE=Rhino R24FXX
+ ID_MODEL_FROM_DATABASE=R24FXX
pci:v00000B0Bd00000506*
ID_MODEL_FROM_DATABASE=RCB24FXS 24-Channel FXS analog telphony card
pci:v00000B0Bd00000605*
- ID_MODEL_FROM_DATABASE=Rhino R2T1
+ ID_MODEL_FROM_DATABASE=R2T1
pci:v00000B0Bd00000705*
- ID_MODEL_FROM_DATABASE=Rhino R24FXS
+ ID_MODEL_FROM_DATABASE=R24FXS
pci:v00000B0Bd00000706*
ID_MODEL_FROM_DATABASE=RCB24FXO 24-Channel FXO analog telphony card
pci:v00001000d00000014sv00001D49sd00000602*
ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter)
+pci:v00001000d00000014sv00001D49sd00000604*
+ ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3516 (ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter)
+
pci:v00001000d00000015*
ID_MODEL_FROM_DATABASE=MegaRAID Tri-Mode SAS3416
pci:v00001000d00000064*
ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor]
+pci:v00001000d00000064sv00001000sd000030C0*
+ ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor] (SAS 9201-16i)
+
pci:v00001000d00000065*
ID_MODEL_FROM_DATABASE=SAS2116 PCI-Express Fusion-MPT SAS-2 [Meteor]
pci:v00001000d00000097sv00001000sd000030E0*
ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS9300-8i)
+pci:v00001000d00000097sv00001000sd00003130*
+ ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (SAS 9300-16i)
+
pci:v00001000d00000097sv00001028sd00001F45*
ID_MODEL_FROM_DATABASE=SAS3008 PCI-Express Fusion-MPT SAS-3 (HBA330 Adapter)
pci:v00001000d000000AFsv00001D49sd00000202*
ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8e SAS/SATA 12Gb HBA)
+pci:v00001000d000000AFsv00001D49sd00000204*
+ ID_MODEL_FROM_DATABASE=SAS3408 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) (ThinkSystem 430-8i SAS/SATA 12Gb Dense HBA)
+
pci:v00001000d000000BE*
ID_MODEL_FROM_DATABASE=SAS3504 Fusion-MPT Tri-Mode RAID On Chip (ROC)
ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (IBM Thinkpad A22p)
pci:v00001002d00004C46sv00001014sd00000155*
- ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (IBM Thinkpad A22p)
+ ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (Thinkpad A22p)
pci:v00001002d00004C46sv00001028sd000000B1*
ID_MODEL_FROM_DATABASE=Rage Mobility 128 AGP 2X/Mobility M3 (Latitude C600)
pci:v00001002d00006798sv00001787sd00003000*
ID_MODEL_FROM_DATABASE=Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X] (Tahiti XT2 [Radeon HD 7970 GHz Edition])
-pci:v00001002d00006799*
- ID_MODEL_FROM_DATABASE=New Zealand [Radeon HD 7900 Series]
-
pci:v00001002d0000679A*
ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280]
ID_MODEL_FROM_DATABASE=Tahiti PRO [Radeon HD 7950/8950 OEM / R9 280] (Radeon R9 280)
pci:v00001002d0000679B*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990]
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM]
pci:v00001002d0000679Bsv00001002sd00000B28*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 8990 OEM)
pci:v00001002d0000679Bsv00001002sd00000B2A*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 7990)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 7990)
pci:v00001002d0000679Bsv00001462sd00008036*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 8990 OEM)
pci:v00001002d0000679Bsv0000148Csd00008990*
- ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990] (Radeon HD 8990 OEM)
+ ID_MODEL_FROM_DATABASE=Malta [Radeon HD 7990/8990 OEM] (Radeon HD 8990 OEM)
pci:v00001002d0000679E*
ID_MODEL_FROM_DATABASE=Tahiti LE [Radeon HD 7870 XT]
ID_MODEL_FROM_DATABASE=Hawaii LE
pci:v00001002d000067C0*
- ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100]
pci:v00001002d000067C4*
ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100]
+pci:v00001002d000067C4sv00001002sd00000336*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100] (Radeon Pro Duo)
+
+pci:v00001002d000067C4sv00001002sd00001336*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 7100] (Radeon Pro Duo)
+
pci:v00001002d000067C7*
ID_MODEL_FROM_DATABASE=Ellesmere [Radeon Pro WX 5100]
ID_MODEL_FROM_DATABASE=Ellesmere [Polaris10]
pci:v00001002d000067DF*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480]
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580]
pci:v00001002d000067DFsv00001002sd00000B37*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv00001043sd000004A8*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv00001043sd000004B0*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001043sd000004FB*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
+
+pci:v00001002d000067DFsv00001043sd000004FD*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480 8GB)
+
+pci:v00001002d000067DFsv00001458sd000022F0*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 570)
pci:v00001002d000067DFsv00001462sd00003411*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001462sd00003413*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv0000148Csd00002372*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
pci:v00001002d000067DFsv0000148Csd00002373*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001682sd00009470*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001682sd00009480*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
+
+pci:v00001002d000067DFsv00001682sd00009588*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 580 XTR)
pci:v00001002d000067DFsv0000174Bsd0000E347*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470/480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470/480)
pci:v00001002d000067DFsv0000174Bsd0000E349*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001787sd0000A470*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 470)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 470)
pci:v00001002d000067DFsv00001787sd0000A480*
- ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480] (Radeon RX 480)
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 480)
+
+pci:v00001002d000067DFsv00001DA2sd0000E353*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Sapphire Radeon RX 580 Pulse 8GB)
+
+pci:v00001002d000067DFsv00001DA2sd0000E366*
+ ID_MODEL_FROM_DATABASE=Ellesmere [Radeon RX 470/480/570/580] (Radeon RX 570)
pci:v00001002d000067E0*
ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 460]
pci:v00001002d000067FF*
- ID_MODEL_FROM_DATABASE=Baffin [Polaris11]
+ ID_MODEL_FROM_DATABASE=Baffin [Radeon RX 560]
pci:v00001002d00006800*
ID_MODEL_FROM_DATABASE=Wimbledon XT [Radeon HD 7970M]
pci:v00001002d00006843*
ID_MODEL_FROM_DATABASE=Thames [Radeon HD 7670M]
+pci:v00001002d00006863*
+ ID_MODEL_FROM_DATABASE=Vega 10 [Radeon Vega Frontier Edition]
+
+pci:v00001002d0000687F*
+ ID_MODEL_FROM_DATABASE=Vega [Radeon RX Vega]
+
pci:v00001002d00006888*
ID_MODEL_FROM_DATABASE=Cypress XT [FirePro V8800]
ID_MODEL_FROM_DATABASE=Polaris12
pci:v00001002d00006985*
- ID_MODEL_FROM_DATABASE=Polaris12
+ ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 3100]
pci:v00001002d00006986*
ID_MODEL_FROM_DATABASE=Polaris12
pci:v00001002d00006987*
ID_MODEL_FROM_DATABASE=Polaris12
+pci:v00001002d00006995*
+ ID_MODEL_FROM_DATABASE=Lexa XT [Radeon PRO WX 2100]
+
pci:v00001002d0000699F*
- ID_MODEL_FROM_DATABASE=Polaris12
+ ID_MODEL_FROM_DATABASE=Lexa PRO [Radeon RX 550]
pci:v00001002d0000700F*
ID_MODEL_FROM_DATABASE=RS100 AGP Bridge
pci:v00001014d00000308*
ID_MODEL_FROM_DATABASE=CalIOC2 PCI-E Root Port
+pci:v00001014d00000311*
+ ID_MODEL_FROM_DATABASE=FC 5740/1954 4-Port 10/100/1000 Base-TX PCI-X Adapter for POWER
+
pci:v00001014d00000314*
ID_MODEL_FROM_DATABASE=ZISC 036 Neural accelerator card
pci:v00001014d0000034Asv00001014sd000004C9*
ID_MODEL_FROM_DATABASE=PCI-E IPR SAS Adapter (ASIC) (PCIe3 x 8 Cache SAS RAID Internal Adapter 6GB(2CCD))
+pci:v00001014d000003DC*
+ ID_MODEL_FROM_DATABASE=POWER8 Host Bridge (PHB3)
+
pci:v00001014d0000044B*
ID_MODEL_FROM_DATABASE=GenWQE Accelerator Adapter
pci:v00001022d0000145B*
ID_MODEL_FROM_DATABASE=Zeppelin Non-Transparent Bridge
+pci:v00001022d0000145C*
+ ID_MODEL_FROM_DATABASE=USB3 Host Controller
+
pci:v00001022d00001510*
ID_MODEL_FROM_DATABASE=Family 14h Processor Root Complex
pci:v00001022d000043A3*
ID_MODEL_FROM_DATABASE=Hudson PCI to PCI bridge (PCIE port 3)
+pci:v00001022d000043BB*
+ ID_MODEL_FROM_DATABASE=USB 3.1 XHCI Controller
+
pci:v00001022d00007006*
ID_MODEL_FROM_DATABASE=AMD-751 [Irongate] System Controller
pci:v0000102Bd00000534*
ID_MODEL_FROM_DATABASE=G200eR2
+pci:v0000102Bd00000538*
+ ID_MODEL_FROM_DATABASE=G200eH
+
+pci:v0000102Bd00000538sv00001590sd000000E4*
+ ID_MODEL_FROM_DATABASE=G200eH (iLO5 VGA)
+
pci:v0000102Bd00000540*
ID_MODEL_FROM_DATABASE=M91XX
pci:v0000103Cd00001303*
ID_MODEL_FROM_DATABASE=RMP-3 (Remote Management Processor)
+pci:v0000103Cd000022F6*
+ ID_MODEL_FROM_DATABASE=iLO5 Virtual USB Controller
+
+pci:v0000103Cd000022F6sv00001590sd000000E4*
+ ID_MODEL_FROM_DATABASE=iLO5 Virtual USB Controller (iLO5 Standard Virtual USB Controller)
+
pci:v0000103Cd00002910*
ID_MODEL_FROM_DATABASE=E2910A PCIBus Exerciser
pci:v0000104Cd00008241*
ID_MODEL_FROM_DATABASE=TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller
+pci:v0000104Cd00008241sv00001014sd000004B2*
+ ID_MODEL_FROM_DATABASE=TUSB73x0 SuperSpeed USB 3.0 xHCI Host Controller (S824 (8286-42A))
+
pci:v0000104Cd00008400*
ID_MODEL_FROM_DATABASE=ACX 100 22Mbps Wireless Interface
pci:v00001077d00001656sv00001077sd0000E4F7*
ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (FastLinQ QL45212H 25GbE Adapter)
+pci:v00001077d00001656sv00001590sd00000223*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 25GbE Controller (Synergy 6810C 25/50Gb Ethernet Adapter)
+
pci:v00001077d0000165C*
ID_MODEL_FROM_DATABASE=FastLinQ QL45000 Series 40GbE Controller (FCoE)
ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter
pci:v00001077d00002031sv0000103Csd000017E7*
- ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (HP SN1000Q 16Gb Single Port Fibre Channel Adapter)
+ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (SN1000Q 16Gb Single Port Fibre Channel Adapter)
pci:v00001077d00002031sv0000103Csd000017E8*
- ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (HP SN1000Q 16Gb Dual Port Fibre Channel Adapter)
+ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (SN1000Q 16Gb Dual Port Fibre Channel Adapter)
pci:v00001077d00002031sv0000103Csd00001939*
- ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (HP QMH2672 16Gb Dual Port Fibre Channel Adapter)
+ ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (QMH2672 16Gb Dual Port Fibre Channel Adapter)
pci:v00001077d00002031sv0000103Csd00008002*
ID_MODEL_FROM_DATABASE=ISP8324-based 16Gb Fibre Channel to PCI Express Adapter (3830C 16G Fibre Channel Host Bus Adapter)
ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (QLE2742 Dual Port 32Gb FC to PCIe Gen3 x8 Adapter)
pci:v00001077d00002261sv00001590sd000000F9*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1100Q 16Gb Single Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1100Q 16Gb Single Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002261sv00001590sd000000FA*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1100Q 16Gb Dual Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1100Q 16Gb Dual Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002261sv00001590sd00000203*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1600Q 32Gb Single Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1600Q 32Gb Single Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002261sv00001590sd00000204*
- ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (HPE StoreFabric SN1600Q 32Gb Dual Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2722-based 16/32Gb Fibre Channel to PCIe Adapter (StoreFabric SN1600Q 32Gb Dual Port Fibre Channel Host Bus Adapter)
pci:v00001077d00002300*
ID_MODEL_FROM_DATABASE=QLA2300 64-bit Fibre Channel Adapter
pci:v00001077d00002532*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA
+pci:v00001077d00002532sv00001014sd0000041E*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (FC EN0Y/EN12 PCIe2 LP 8 Gb 4-port Fibre Channel Adapter for POWER)
+
pci:v00001077d00002532sv0000103Csd00003262*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StorageWorks 81Q)
pci:v00001077d00002532sv0000103Csd00003263*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StorageWorks 82Q)
+pci:v00001077d00002532sv00001077sd0000015C*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QLE2560 PCI Express to 8Gb FC Single Channel)
+
+pci:v00001077d00002532sv00001077sd0000015D*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QLE2562 PCI Express to 8Gb FC Dual Channel)
+
+pci:v00001077d00002532sv00001077sd0000015E*
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QLE2564 PCI Express to 8Gb FC Quad Channel)
+
pci:v00001077d00002532sv00001077sd00000167*
ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (QME2572 Dual Port FC8 HBA Mezzanine)
pci:v00001077d00002532sv00001590sd000000FC*
- ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (HPE StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter)
+ ID_MODEL_FROM_DATABASE=ISP2532-based 8Gb Fibre Channel to PCI Express HBA (StoreFabric 84Q 8Gb Quad Port Fibre Channel Host Bus Adapter)
pci:v00001077d00003022*
ID_MODEL_FROM_DATABASE=ISP4022-based Ethernet NIC
pci:v00001077d00008001*
ID_MODEL_FROM_DATABASE=10GbE Converged Network Adapter (FCoE)
+pci:v00001077d00008001sv00001014sd000003AF*
+ ID_MODEL_FROM_DATABASE=10GbE Converged Network Adapter (FCoE) (FC 5708/5270 10 Gb FCoE PCIe Dual Port Adapter for POWER)
+
pci:v00001077d00008020*
ID_MODEL_FROM_DATABASE=cLOM8214 1/10GbE Controller
pci:v00001077d00008070*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller
+pci:v00001077d00008070sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GE 2P QL41162HxRJ-DE Adapter)
+
+pci:v00001077d00008070sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008070sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008070sv00001077sd00000011*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FastLinQ QL41212H 25GbE Adapter)
pci:v00001077d00008080*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE)
+pci:v00001077d00008080sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GE 2P QL41162HxRJ-DE Adapter)
+
+pci:v00001077d00008080sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008080sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008080sv00001077sd0000000D*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (FCoE) (FastLinQ QL41262H 25GbE FCoE Adapter)
pci:v00001077d00008084*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI)
+pci:v00001077d00008084sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GE 2P QL41162HxRJ-DE Adapter)
+
+pci:v00001077d00008084sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008084sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008084sv00001077sd0000000D*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series 10/25/40/50GbE Controller (iSCSI) (FastLinQ QL41262H 25GbE iSCSI Adapter)
pci:v00001077d00008090*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF)
+pci:v00001077d00008090sv00001077sd00000001*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (25GE 2P QL41262HxCU-DE Adapter)
+
+pci:v00001077d00008090sv00001077sd00000002*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (10GE 2P QL41112HxCU-DE Adapter)
+
+pci:v00001077d00008090sv00001077sd0000000B*
+ ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (25GE 2P QL41262HxCU-DE Adapter)
+
pci:v00001077d00008090sv00001077sd0000000D*
ID_MODEL_FROM_DATABASE=FastLinQ QL41000 Series Gigabit Ethernet Controller (SR-IOV VF) (FastLinQ QL41262H 25GbE FCoE Adapter (SR-IOV VF))
ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600]
pci:v000010DEd00000398sv00001025sd0000006C*
- ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600] (Acer 9814 WKMI)
+ ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600] (Aspire 9814WKMi)
pci:v000010DEd00000399*
ID_MODEL_FROM_DATABASE=G73M [GeForce Go 7600 GT]
pci:v000010DEd00000E08*
ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller
+pci:v000010DEd00000E08sv00001043sd000083A0*
+ ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller (ENGT520 SILENT)
+
pci:v000010DEd00000E08sv000010B0sd0000104A*
ID_MODEL_FROM_DATABASE=GF119 HDMI Audio Controller (Gainward GeForce GT 610)
pci:v000010DEd00000FB0*
ID_MODEL_FROM_DATABASE=GM200 High Definition Audio
+pci:v000010DEd00000FB8*
+ ID_MODEL_FROM_DATABASE=GP108 High Definition Audio Controller
+
+pci:v000010DEd00000FB9*
+ ID_MODEL_FROM_DATABASE=GP107GL High Definition Audio Controller
+
pci:v000010DEd00000FBB*
ID_MODEL_FROM_DATABASE=GM204 High Definition Audio Controller
pci:v000010DEd00001040*
ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 520]
+pci:v000010DEd00001040sv00001043sd000083A0*
+ ID_MODEL_FROM_DATABASE=GF119 [GeForce GT 520] (ENGT520 SILENT)
+
pci:v000010DEd00001042*
ID_MODEL_FROM_DATABASE=GF119 [GeForce 510]
pci:v000010DEd000010F0*
ID_MODEL_FROM_DATABASE=GP104 High Definition Audio Controller
+pci:v000010DEd000010F1*
+ ID_MODEL_FROM_DATABASE=GP106 High Definition Audio Controller
+
pci:v000010DEd00001140*
ID_MODEL_FROM_DATABASE=GF117M [GeForce 610M/710M/810M/820M / GT 620M/625M/630M/720M]
pci:v000010DEd0000137Asv000017AAsd0000505A*
ID_MODEL_FROM_DATABASE=GM108GLM [Quadro K620M / Quadro M500M] (Quadro M500M)
+pci:v000010DEd0000137B*
+ ID_MODEL_FROM_DATABASE=GM108GLM [Quadro M520 Mobile]
+
pci:v000010DEd0000137D*
ID_MODEL_FROM_DATABASE=GM108M [GeForce 940A]
pci:v000010DEd000013DA*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980]
+pci:v000010DEd000013E7*
+ ID_MODEL_FROM_DATABASE=GM204 [GeForce GTX 980 Engineering Sample]
+
pci:v000010DEd000013F0*
ID_MODEL_FROM_DATABASE=GM204GL [Quadro M5000]
ID_MODEL_FROM_DATABASE=GM206GLM [Quadro M2200 Mobile]
pci:v000010DEd000015F0*
- ID_MODEL_FROM_DATABASE=GP100GL
+ ID_MODEL_FROM_DATABASE=GP100GL [Quadro GP100]
pci:v000010DEd000015F1*
ID_MODEL_FROM_DATABASE=GP100GL
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 965M]
pci:v000010DEd0000161A*
- ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980]
+ ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 980 Mobile]
pci:v000010DEd00001667*
ID_MODEL_FROM_DATABASE=GM204M [GeForce GTX 965M]
pci:v000010DEd00001B01*
ID_MODEL_FROM_DATABASE=GP102
+pci:v000010DEd00001B02*
+ ID_MODEL_FROM_DATABASE=GP102 [TITAN Xp]
+
+pci:v000010DEd00001B06*
+ ID_MODEL_FROM_DATABASE=GP102 [GeForce GTX 1080 Ti]
+
pci:v000010DEd00001B30*
ID_MODEL_FROM_DATABASE=GP102GL [Quadro P6000]
ID_MODEL_FROM_DATABASE=GP104GL [Quadro P5000]
pci:v000010DEd00001BB1*
- ID_MODEL_FROM_DATABASE=GP104GL
+ ID_MODEL_FROM_DATABASE=GP104GL [Quadro P4000]
pci:v000010DEd00001BB3*
ID_MODEL_FROM_DATABASE=GP104GL [Tesla P4]
ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
pci:v000010DEd00001C30*
- ID_MODEL_FROM_DATABASE=GP106GL
+ ID_MODEL_FROM_DATABASE=GP106GL [Quadro P2000]
pci:v000010DEd00001C35*
ID_MODEL_FROM_DATABASE=GP106
pci:v000010DEd00001C60*
ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1060 Mobile]
+pci:v000010DEd00001C61*
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Ti Mobile]
+
+pci:v000010DEd00001C62*
+ ID_MODEL_FROM_DATABASE=GP106M [GeForce GTX 1050 Mobile]
+
pci:v000010DEd00001C70*
ID_MODEL_FROM_DATABASE=GP106GL
pci:v000010DEd00001CAA*
ID_MODEL_FROM_DATABASE=GP107GL
+pci:v000010DEd00001CB1*
+ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P1000]
+
+pci:v000010DEd00001CB2*
+ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P600]
+
+pci:v000010DEd00001CB3*
+ ID_MODEL_FROM_DATABASE=GP107GL [Quadro P400]
+
pci:v000010DEd00001D01*
- ID_MODEL_FROM_DATABASE=GP108
+ ID_MODEL_FROM_DATABASE=GP108 [GeForce GT 1030]
+
+pci:v000010DEd00001D10*
+ ID_MODEL_FROM_DATABASE=GP108 [GeForce MX150]
+
+pci:v000010DEd00001D81*
+ ID_MODEL_FROM_DATABASE=GV100
pci:v000010DF*
ID_VENDOR_FROM_DATABASE=Emulex Corporation
ID_MODEL_FROM_DATABASE=Proteus-X: LightPulse IOV Fibre Channel Host Adapter
pci:v000010DFd0000E200*
- ID_MODEL_FROM_DATABASE=Lancer-X: LightPulse Fibre Channel Host Adapter
+ ID_MODEL_FROM_DATABASE=LightPulse LPe16002
+
+pci:v000010DFd0000E200sv00001014sd000003F1*
+ ID_MODEL_FROM_DATABASE=LightPulse LPe16002 (PCIe2 16 Gb 2-port Fibre Channel Adapter (FC EL5B; CCIN 577F))
pci:v000010DFd0000E208*
ID_MODEL_FROM_DATABASE=LightPulse 16Gb Fibre Channel Host Adapter (Lancer-VF)
pci:v000010DFd0000E300*
ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter
+pci:v000010DFd0000E300sv000010DFsd0000E310*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E311*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E312*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E322*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E323*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
+pci:v000010DFd0000E300sv000010DFsd0000E325*
+ ID_MODEL_FROM_DATABASE=Lancer Gen6: LPe32000 Fibre Channel Host Adapter (Lancer Gen6: LPe31000 Fibre Channel Host Adapter)
+
pci:v000010DFd0000F011*
ID_MODEL_FROM_DATABASE=Saturn: LightPulse Fibre Channel Host Adapter
pci:v000010DFd0000F100*
ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter
+pci:v000010DFd0000F100sv00001014sd0000038A*
+ ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb PCI Express Dual Port FC Adapter for POWER)
+
pci:v000010DFd0000F100sv0000103Csd00003282*
ID_MODEL_FROM_DATABASE=Saturn-X: LightPulse Fibre Channel Host Adapter (8Gb Dual-port PCI-e FC HBA)
pci:v000010DFd0000FD00*
ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
+pci:v000010DFd0000FD00sv000010DFsd0000FD02*
+ ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter (LightPulse LP11002 Dual-port 4Gigabit PCI Fibre Channel Adapter)
+
pci:v000010DFd0000FD11*
ID_MODEL_FROM_DATABASE=Helios-X LightPulse Fibre Channel Host Adapter
pci:v000010ECd0000525A*
ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader
+pci:v000010ECd0000525Asv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=RTS525A PCI Express Card Reader (ThinkPad X1 Carbon 5th Gen)
+
pci:v000010ECd00005286*
ID_MODEL_FROM_DATABASE=RTS5286 PCI Express Card Reader
pci:v000010ECd00008168sv00007470sd00003468*
ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (TG-3468 Gigabit PCI Express Network Adapter)
+pci:v000010ECd00008168sv00008086sd00002055*
+ ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (NUC Kit DN2820FYKH)
+
pci:v000010ECd00008168sv00008086sd0000D615*
ID_MODEL_FROM_DATABASE=RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (Desktop Board D510MO/D525MW)
pci:v000010ECd0000B723*
ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter
+pci:v000010ECd0000B723sv000010ECsd00008739*
+ ID_MODEL_FROM_DATABASE=RTL8723BE PCIe Wireless Network Adapter (Dell Wireless 1801)
+
pci:v000010ED*
ID_VENDOR_FROM_DATABASE=Ascii Corporation
ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A7V600/K8V-X/K8V Deluxe motherboard (ADI AD1980 codec [SoundMAX]))
pci:v00001106d00003059sv00001043sd000080F3*
- ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (ASUSTek SK8V motherboard)
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (SK8V motherboard)
pci:v00001106d00003059sv00001043sd0000810D*
- ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (Asus P5VD1-X (AD1888 codec [SoundMax]))
+ ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (P5VD1-X (AD1888 codec [SoundMax]))
pci:v00001106d00003059sv00001043sd0000812A*
ID_MODEL_FROM_DATABASE=VT8233/A/8235/8237 AC97 Audio Controller (A8V Deluxe motherboard (Realtek ALC850 codec))
ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (FlyTV mini Asus Digimatrix)
pci:v00001131d00007133sv00001043sd00004843*
- ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (ASUS TV-FM 7133)
+ ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (TV-FM 7133)
pci:v00001131d00007133sv00001043sd00004845*
ID_MODEL_FROM_DATABASE=SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (TV-FM 7135)
ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (Digimatrix TV)
pci:v00001131d00007134sv00001043sd00004840*
- ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (ASUS TV-FM 7134)
+ ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (TV-FM 7134)
pci:v00001131d00007134sv00001043sd00004842*
ID_MODEL_FROM_DATABASE=SAA7134/SAA7135HL Video Broadcast Decoder (TV-FM 7134)
ID_MODEL_FROM_DATABASE=RL5c476 II (V6800V)
pci:v00001180d00000476sv00001043sd00001987*
- ID_MODEL_FROM_DATABASE=RL5c476 II (Asus A4K and Z81K notebooks, possibly others ( mid-2005 machines ))
+ ID_MODEL_FROM_DATABASE=RL5c476 II (A4K and Z81K notebooks, possibly others ( mid-2005 machines ))
pci:v00001180d00000476sv0000104Dsd000080DF*
ID_MODEL_FROM_DATABASE=RL5c476 II (Vaio PCG-FX403)
ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad X60/X60s)
pci:v00001180d00000476sv000017AAsd000020C4*
- ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad T61)
+ ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad T61/R61)
pci:v00001180d00000476sv000017AAsd000020C6*
ID_MODEL_FROM_DATABASE=RL5c476 II (ThinkPad R61)
ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (A6J-Q008)
pci:v00001180d00000822sv00001043sd00001967*
- ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (ASUS V6800V)
+ ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (V6800V)
pci:v00001180d00000822sv000010F7sd00008338*
ID_MODEL_FROM_DATABASE=R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter (Panasonic CF-Y5 laptop)
pci:v00001180d00000832sv0000103Csd000030CF*
ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (Pavilion dv9668eg Laptop)
+pci:v00001180d00000832sv000017AAsd000020C5*
+ ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (ThinkPad R61)
+
pci:v00001180d00000832sv000017AAsd000020C7*
ID_MODEL_FROM_DATABASE=R5C832 IEEE 1394 Controller (ThinkPad R61)
ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Inspiron 1420)
pci:v00001180d00000843sv00001028sd000001F5*
- ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Dell Inspiron 1501)
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Inspiron 1501)
pci:v00001180d00000843sv00001028sd0000024F*
- ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Dell Latitude e6500)
+ ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Latitude e6500)
pci:v00001180d00000843sv0000103Csd000003B5*
ID_MODEL_FROM_DATABASE=R5C843 MMC Host Controller (Presario V3242AU)
pci:v00001180d0000E823*
ID_MODEL_FROM_DATABASE=PCIe SDXC/MMC Host Controller
+pci:v00001180d0000E823sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=PCIe SDXC/MMC Host Controller (ThinkPad T520)
+
pci:v00001180d0000E832*
ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller
pci:v00001180d0000E832sv00001028sd0000040B*
ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller (Latitude E6510)
+pci:v00001180d0000E832sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=R5C832 PCIe IEEE 1394 Controller (ThinkPad T520)
+
pci:v00001180d0000E852*
ID_MODEL_FROM_DATABASE=PCIe xD-Picture Card Controller
ID_VENDOR_FROM_DATABASE=Pericom Semiconductor
pci:v000012D8d000001A7*
- ID_MODEL_FROM_DATABASE=PI7C21P100 PCI to PCI Bridge
+ ID_MODEL_FROM_DATABASE=7C21P100 2-port PCI-X to PCI-X Bridge
pci:v000012D8d0000400A*
ID_MODEL_FROM_DATABASE=PI7C9X442SL PCI Express Bridge Port
pci:v00001344d00005163*
ID_MODEL_FROM_DATABASE=RealSSD P425m
+pci:v00001344d00005180*
+ ID_MODEL_FROM_DATABASE=9100 PRO NVMe SSD
+
+pci:v00001344d00005181*
+ ID_MODEL_FROM_DATABASE=9100 MAX NVMe SSD
+
pci:v00001345*
ID_VENDOR_FROM_DATABASE=Arescom Inc
ID_MODEL_FROM_DATABASE=GPS180AMC GPS Receiver (PCI Express / MicroTCA / AdvancedMC)
pci:v00001360d00000209*
- ID_MODEL_FROM_DATABASE=GRC181PEX GPS/GLONASS/BEIDOU receiver (PCI Express)
+ ID_MODEL_FROM_DATABASE=GNS181PEX GPS/Galileo/GLONASS/BEIDOU receiver (PCI Express)
pci:v00001360d00000301*
ID_MODEL_FROM_DATABASE=TCR510PCI IRIG Timecode Reader
ID_VENDOR_FROM_DATABASE=DSP Research Inc
pci:v0000140B*
- ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms
+ ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
pci:v0000140C*
ID_VENDOR_FROM_DATABASE=Elmic Systems Inc
pci:v00001425d000050A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller
+pci:v00001425d000050A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Ethernet Controller
+
+pci:v00001425d000050A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Ethernet Controller
+
pci:v00001425d00005401*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
pci:v00001425d000054A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller
+pci:v00001425d000054A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Ethernet Controller
+
+pci:v00001425d000054A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Ethernet Controller
+
pci:v00001425d00005501*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
pci:v00001425d000055A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Storage Controller
+pci:v00001425d000055A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Storage Controller
+
+pci:v00001425d000055A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Storage Controller
+
pci:v00001425d00005601*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Storage Controller
pci:v00001425d000056A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Storage Controller
+pci:v00001425d000056A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Storage Controller
+
+pci:v00001425d000056A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Storage Controller
+
pci:v00001425d00005701*
ID_MODEL_FROM_DATABASE=T520-CR Unified Wire Ethernet Controller
pci:v00001425d000058A0*
ID_MODEL_FROM_DATABASE=T540-50A0 Unified Wire Ethernet Controller [VF]
+pci:v00001425d000058A1*
+ ID_MODEL_FROM_DATABASE=T540-50A1 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d000058A2*
+ ID_MODEL_FROM_DATABASE=T580-50A2 Unified Wire Ethernet Controller [VF]
+
pci:v00001425d00006001*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
pci:v00001425d00006081*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller
+pci:v00001425d00006082*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Ethernet Controller
+
+pci:v00001425d00006083*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Ethernet Controller
+
+pci:v00001425d00006084*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller
+
pci:v00001425d00006401*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller
pci:v00001425d00006481*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller
+pci:v00001425d00006482*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Ethernet Controller
+
+pci:v00001425d00006483*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Ethernet Controller
+
+pci:v00001425d00006484*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller
+
pci:v00001425d00006501*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
pci:v00001425d00006581*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Storage Controller
+pci:v00001425d00006582*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Storage Controller
+
+pci:v00001425d00006583*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Storage Controller
+
+pci:v00001425d00006584*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Storage Controller
+
pci:v00001425d00006601*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Storage Controller
pci:v00001425d00006681*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Storage Controller
+pci:v00001425d00006682*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Storage Controller
+
+pci:v00001425d00006683*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Storage Controller
+
+pci:v00001425d00006684*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Storage Controller
+
pci:v00001425d00006801*
ID_MODEL_FROM_DATABASE=T6225-CR Unified Wire Ethernet Controller [VF]
pci:v00001425d00006881*
ID_MODEL_FROM_DATABASE=T62100-6081 Unified Wire Ethernet Controller [VF]
+pci:v00001425d00006882*
+ ID_MODEL_FROM_DATABASE=T6225-6082 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00006883*
+ ID_MODEL_FROM_DATABASE=T62100-6083 Unified Wire Ethernet Controller [VF]
+
+pci:v00001425d00006884*
+ ID_MODEL_FROM_DATABASE=T64100-6084 Unified Wire Ethernet Controller [VF]
+
pci:v00001425d0000A000*
ID_MODEL_FROM_DATABASE=PE10K Unified Wire Ethernet Controller
pci:v0000144Dd0000A821sv00001028sd00001FC4*
ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172X (Express Flash NVMe PM1725 1.6TB AIC)
+pci:v0000144Dd0000A822*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa
+
+pci:v0000144Dd0000A822sv00001014sd00000621*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (PCIe3 1.6TB NVMe Flash Adapter II x8)
+
+pci:v0000144Dd0000A822sv00001014sd00000622*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (PCIe3 3.2TB NVMe Flash Adapter II x8)
+
+pci:v0000144Dd0000A822sv00001028sd00001FD9*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 800GB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDA*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 1.6TB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDB*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 3.2TB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDC*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 6.4TB SFF)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDD*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 1.6TB AIC)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDE*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 3.2TB AIC)
+
+pci:v0000144Dd0000A822sv00001028sd00001FDF*
+ ID_MODEL_FROM_DATABASE=NVMe SSD Controller 172Xa (Express Flash PM1725a 6.4TB AIC)
+
pci:v0000144E*
ID_VENDOR_FROM_DATABASE=OLITEC
ID_VENDOR_FROM_DATABASE=NAKAYO Telecommunications Inc
pci:v000014CD*
- ID_VENDOR_FROM_DATABASE=Universal Scientific Ind.
+ ID_VENDOR_FROM_DATABASE=Universal Global Scientific Industrial Co.,Ltd
+
+pci:v000014CDd00000001*
+ ID_MODEL_FROM_DATABASE=USI-1514-1GbaseT [OCP1]
+
+pci:v000014CDd00000002*
+ ID_MODEL_FROM_DATABASE=USI-4227-SFP [OCP2]
+
+pci:v000014CDd00000003*
+ ID_MODEL_FROM_DATABASE=USI-X557-10GbaseT [OCP3]
pci:v000014CE*
ID_VENDOR_FROM_DATABASE=Whistle Communications
pci:v000014E4d0000163D*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet
+pci:v000014E4d0000163Dsv00001043sd0000858A*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57811 10-Gigabit Ethernet (PEB-10G/57811-1S)
+
pci:v000014E4d0000163E*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57811 10 Gigabit Ethernet Multi Function
ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express
pci:v000014E4d0000165Asv00001014sd00000378*
- ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (IBM System x3350 (Machine type 4192))
+ ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (System x3350 (Machine type 4192))
pci:v000014E4d0000165Asv00001028sd0000020F*
ID_MODEL_FROM_DATABASE=NetXtreme BCM5722 Gigabit Ethernet PCI Express (PowerEdge R300 Broadcom NetXtreme 5722)
pci:v000014E4d0000168E*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet
+pci:v000014E4d0000168Esv00001014sd00000492*
+ ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (PCIe2 2-port 10 GbE BaseT RJ45 Adapter (FC EN0W; CCIN 2CC4))
+
pci:v000014E4d0000168Esv0000103Csd00001798*
ID_MODEL_FROM_DATABASE=NetXtreme II BCM57810 10 Gigabit Ethernet (Flex-10 10Gb 2-port 530FLB Adapter [Meru])
pci:v000014E4d00001693sv0000103Csd000030C0*
ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express (6710b)
+pci:v000014E4d00001693sv000017AAsd000020D5*
+ ID_MODEL_FROM_DATABASE=NetLink BCM5787M Gigabit Ethernet PCI Express (ThinkPad R61)
+
pci:v000014E4d00001694*
ID_MODEL_FROM_DATABASE=NetLink BCM57790 Gigabit Ethernet PCIe
ID_MODEL_FROM_DATABASE=BCM57304 NetXtreme-C 10Gb/25Gb/40Gb/50Gb Ethernet Controller
pci:v000014E4d000016CB*
- ID_MODEL_FROM_DATABASE=BCM57304 NetXtreme-C Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-C Ethernet Virtual Function
pci:v000014E4d000016CC*
ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E Ethernet Partition
ID_MODEL_FROM_DATABASE=BCM57406 NetXtreme-E 10GBASE-T Ethernet Controller
pci:v000014E4d000016D3*
- ID_MODEL_FROM_DATABASE=BCM57404 NetXtreme-E Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-E Ethernet Virtual Function
pci:v000014E4d000016D4*
ID_MODEL_FROM_DATABASE=BCM57402 NetXtreme-E Ethernet Partition
pci:v000014E4d000016D7*
ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller
+pci:v000014E4d000016D7sv000014E4sd00001202*
+ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957412M4122 OCP 1x25G Type1 wRoCE)
+
+pci:v000014E4d000016D7sv000014E4sd00001404*
+ ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (BCM957414M4142 OCP 2x25G Type1 wRoCE)
+
pci:v000014E4d000016D7sv00001590sd0000020E*
ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller (Ethernet 25Gb 2-port 631SFP28 Adapter)
ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E 10GBASE-T RDMA Ethernet Controller (Dual Port 10GBase-T Ethernet Controller)
pci:v000014E4d000016DC*
- ID_MODEL_FROM_DATABASE=BCM57414 NetXtreme-E Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-E Ethernet Virtual Function
pci:v000014E4d000016DD*
ID_MODEL_FROM_DATABASE=NetLink BCM5781 Gigabit Ethernet PCI Express
ID_MODEL_FROM_DATABASE=BCM57314 NetXtreme-C 10Gb/25Gb/40Gb/50Gb RDMA Ethernet Controller
pci:v000014E4d000016E1*
- ID_MODEL_FROM_DATABASE=BCM57314 NetXtreme-C Ethernet Virtual Function
+ ID_MODEL_FROM_DATABASE=NetXtreme-C Ethernet Virtual Function
pci:v000014E4d000016E2*
ID_MODEL_FROM_DATABASE=BCM57417 NetXtreme-E 10Gb/25Gb RDMA Ethernet Controller
pci:v000014E4d000016E3*
ID_MODEL_FROM_DATABASE=BCM57416 NetXtreme-E 10Gb RDMA Ethernet Controller
+pci:v000014E4d000016E5*
+ ID_MODEL_FROM_DATABASE=NetXtreme-C RDMA Virtual Function
+
pci:v000014E4d000016E7*
ID_MODEL_FROM_DATABASE=BCM57404 NetXtreme-E Ethernet Partition
pci:v000014E4d0000B842*
ID_MODEL_FROM_DATABASE=BCM56842 Trident 10GE Switch Controller
+pci:v000014E4d0000B850*
+ ID_MODEL_FROM_DATABASE=Broadcom BCM56850 Switch ASIC
+
+pci:v000014E4d0000B960*
+ ID_MODEL_FROM_DATABASE=Broadcom BCM56960 Switch ASIC
+
pci:v000014E5*
ID_VENDOR_FROM_DATABASE=Pixelfusion Ltd
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (HDTV Wonder)
pci:v000014F1d00008800sv00001043sd00004823*
- ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (ASUS PVR-416)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (PVR-416)
pci:v000014F1d00008800sv0000107Dsd00006611*
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder (Winfast TV 2000XP Expert)
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (WinTV 88x MPEG Encoder)
pci:v000014F1d00008802sv00001043sd00004823*
- ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (ASUS PVR-416)
+ ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (PVR-416)
pci:v000014F1d00008802sv0000107Dsd0000663C*
ID_MODEL_FROM_DATABASE=CX23880/1/2/3 PCI Video and Audio Decoder [MPEG Port] (Leadtek PVR 2000)
ID_VENDOR_FROM_DATABASE=MACHONE Communications
pci:v00001542*
- ID_VENDOR_FROM_DATABASE=Concurrent Computer Corporation
+ ID_VENDOR_FROM_DATABASE=Concurrent Real-Time
pci:v00001542d00009260*
ID_MODEL_FROM_DATABASE=RCIM-II Real-Time Clock & Interrupt Module
pci:v000015B3d00001003sv0000103Csd000018D6*
ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (InfiniBand FDR/EN 10/40Gb Dual Port 544QSFP Adapter)
+pci:v000015B3d00001003sv000015B3sd00000025*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 IB QDR Dual Port Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000026*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 IB FDR Dual Port Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000028*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI Dual QSFP+ Port QDR Infiniband 40Gb/s or 10Gb Ethernet)
+
+pci:v000015B3d00001003sv000015B3sd00000059*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Single Port QSFP+ Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000065*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Dual Port QSFP+ Adapter)
+
+pci:v000015B3d00001003sv000015B3sd00000066*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 IB FDR10 Dual Port Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000067*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Single Port QSFP+ Adapter)
+
+pci:v000015B3d00001003sv000015B3sd00000071*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 VPI IB FDR/40 GbE Dual Port QSFP+ Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000078*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 10 GbE Dual Port KR Mezzanine Card)
+
+pci:v000015B3d00001003sv000015B3sd00000079*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 40 GbE Dual Port QSFP+ Adapter)
+
+pci:v000015B3d00001003sv000015B3sd00000080*
+ ID_MODEL_FROM_DATABASE=MT27500 Family [ConnectX-3] (ConnectX-3 10 GbE Dual Port SFP+ Adapter)
+
pci:v000015B3d00001004*
ID_MODEL_FROM_DATABASE=MT27500/MT27520 Family [ConnectX-3/ConnectX-3 Pro Virtual Function]
pci:v000015B3d00001007sv0000117Csd00000093*
ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (FastFrame NQ12)
+pci:v000015B3d00001007sv000015B3sd00000078*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (ConnectX-3 Pro 10 GbE Dual Port KR Mezzanine Card)
+
+pci:v000015B3d00001007sv000015B3sd00000079*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (ConnectX-3 Pro 40 GbE Dual Port QSFP+ Adapter)
+
+pci:v000015B3d00001007sv000015B3sd00000080*
+ ID_MODEL_FROM_DATABASE=MT27520 Family [ConnectX-3 Pro] (ConnectX-3 Pro 10 GbE Dual Port SFP+ Adapter)
+
pci:v000015B3d00001009*
ID_MODEL_FROM_DATABASE=MT27530 Family
pci:v000015B3d00001013*
ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4]
+pci:v000015B3d00001013sv000015B3sd00000006*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (MCX416A-BCAT, ConnectX-4 EN, 40/56GbE 2P, PCIe3.0 x16)
+
+pci:v000015B3d00001013sv000015B3sd00000033*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 VPI IB EDR/100 GbE Single Port QSFP28 Adapter)
+
+pci:v000015B3d00001013sv000015B3sd00000034*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 VPI IB EDR/100 GbE Dual Port QSFP28 Adapter)
+
+pci:v000015B3d00001013sv000015B3sd00000050*
+ ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4] (ConnectX-4 100 GbE Dual Port QSFP28 Adapter)
+
pci:v000015B3d00001014*
ID_MODEL_FROM_DATABASE=MT27700 Family [ConnectX-4 Virtual Function]
pci:v000015B3d00001015*
ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx]
+pci:v000015B3d00001015sv000015B3sd00000016*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (ConnectX-4 Lx 25 GbE Dual Port SFP28 Adapter)
+
+pci:v000015B3d00001015sv000015B3sd00000020*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (MCX4411A-ACQN, ConnectX-4 Lx EN OCP, 1x25Gb)
+
+pci:v000015B3d00001015sv000015B3sd00000021*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (MCX4421A-ACQN ConnectX-4 Lx EN OCP,2x25G)
+
+pci:v000015B3d00001015sv000015B3sd00000025*
+ ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx] (ConnectX-4 Lx 25 GbE Dual Port SFP28 rNDC)
+
pci:v000015B3d00001016*
ID_MODEL_FROM_DATABASE=MT27710 Family [ConnectX-4 Lx Virtual Function]
pci:v000015B3d0000673C*
ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE]
+pci:v000015B3d0000673Csv00001014sd00000487*
+ ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] (GX++ 1-port 4X IB QDR Adapter for Power 795)
+
pci:v000015B3d0000673Csv0000103Csd00001782*
ID_MODEL_FROM_DATABASE=MT26428 [ConnectX VPI PCIe 2.0 5GT/s - IB QDR / 10GigE] (4X QDR InfiniBand Mezzanine HCA for c-Class BladeSystem)
pci:v000015B3d00006750sv000015B3sd00000018*
ID_MODEL_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s] (HP 10 GbE PCI-e G2 Dual-Port NIC (rev C1))
+pci:v000015B3d00006750sv000015B3sd00006572*
+ ID_MODEL_FROM_DATABASE=MT26448 [ConnectX EN 10GigE, PCIe 2.0 5GT/s] (IBM Flex System EN4132 2-port 10Gb RoCE Adapter)
+
pci:v000015B3d0000675A*
ID_MODEL_FROM_DATABASE=MT25408 [ConnectX EN 10GigE 10GBaseT, PCIe Gen2 5GT/s]
pci:v000015B3d0000A2D1*
ID_MODEL_FROM_DATABASE=MT416842 BlueField SoC Crypto disabled
+pci:v000015B3d0000A2D2*
+ ID_MODEL_FROM_DATABASE=MT416842 BlueField integrated ConnectX-5 network controller
+
pci:v000015B3d0000A2D3*
ID_MODEL_FROM_DATABASE=MT416842 BlueField multicore SoC family VF
pci:v0000168Cd00000034*
ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter
+pci:v0000168Cd00000034sv00001028sd0000020B*
+ ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter (Wireless 1601 802.11abgn Adapter)
+
pci:v0000168Cd00000034sv00001028sd00000300*
ID_MODEL_FROM_DATABASE=AR9462 Wireless Network Adapter (Wireless 1802 802.11abgn Adapter)
ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller
pci:v00001924d00000A03sv00001924sd00008011*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R1 Flareon 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R1 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008012*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R1 Flareon Ultra 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R1 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008013*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R1 Flareon 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R1 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008014*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R1 Flareon Ultra 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R1 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008016*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R2 Flareon 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8022-R2 8000 Series 10G Adapte)
pci:v00001924d00000A03sv00001924sd00008017*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R2 Flareon Ultra 8000 Series 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8522-R2 8000 Series 10G Adapter)
pci:v00001924d00000A03sv00001924sd00008018*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R2 Flareon 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8042-R2 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd00008019*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R2 Flareon Ultra 8000 Series 10/40G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8542-R2 8000 Series 10/40G Adapter)
pci:v00001924d00000A03sv00001924sd0000801A*
- ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8722-R1 Flareon Ultra 8000 Series OCP 10G Adapter)
+ ID_MODEL_FROM_DATABASE=SFC9220 10/40G Ethernet Controller (SFN8722-R1 8000 Series OCP 10G Adapter)
pci:v00001924d00001803*
ID_MODEL_FROM_DATABASE=SFC9020 10G Ethernet Controller (Virtual Function)
ID_MODEL_FROM_DATABASE=BladeEngine3 10Gb Gen2 PCIe iSCSI Adapter
pci:v000019A2d00000700*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE
pci:v000019A2d00000700sv0000103Csd00001747*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC550SFP DualPort 10GbE Server Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC550SFP DualPort 10GbE Server Adapter)
pci:v000019A2d00000700sv0000103Csd00001749*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC550SFP Dual Port Server Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC550SFP Dual Port Server Adapter)
pci:v000019A2d00000700sv0000103Csd0000174A*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC551m Dual Port FlexFabric 10Gb Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC551m Dual Port FlexFabric 10Gb Adapter)
pci:v000019A2d00000700sv0000103Csd0000174B*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (StorageWorks NC550 DualPort Converged Network Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (StorageWorks NC550 DualPort Converged Network Adapter)
pci:v000019A2d00000700sv0000103Csd00003314*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (NC551i Dual Port FlexFabric 10Gb Adapter)
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE (NC551i Dual Port FlexFabric 10Gb Adapter)
pci:v000019A2d00000702*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator
pci:v000019A2d00000704*
- ID_MODEL_FROM_DATABASE=OneConnect 10Gb FCoE Initiator
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE CNA
+
+pci:v000019A2d00000704sv000010DFsd0000E602*
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE CNA (OneConnect OCe10100 10Gb CNA)
+
+pci:v000019A2d00000704sv000010DFsd0000E630*
+ ID_MODEL_FROM_DATABASE=OneConnect OCe10100/OCe10102 Series 10 GbE CNA (OneConnect OCe10102-FM-E / OCe10102-FX-E for EMC VNX Symmetrix)
pci:v000019A2d00000710*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3)
+pci:v000019A2d00000710sv00001014sd000003D0*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (PCIe2 2-port 10GbE SR Adapter for POWER)
+
+pci:v000019A2d00000710sv00001014sd000003D1*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (PCIe2 2-port 10GbE SFP+ Copper Adapter for POWER)
+
+pci:v000019A2d00000710sv00001014sd00000409*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (Integrated Multifunction Card with Dual 10GbE SR Optical + Dual 1GbE for Power 750/760)
+
+pci:v000019A2d00000710sv00001014sd0000040A*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (Integrated Multifunction Card with Dual 10GbE SR Copper + Dual 1GbE for Power 750/760)
+
pci:v000019A2d00000710sv0000103Csd00003315*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC553i 10Gb 2-port FlexFabric Converged Network Adapter)
pci:v000019A2d00000710sv0000103Csd0000337B*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (NC554FLB 10Gb 2-port FlexFabric Converged Network Adapter)
+pci:v000019A2d00000710sv000010DFsd0000E733*
+ ID_MODEL_FROM_DATABASE=OneConnect 10Gb NIC (be3) (Flex System EN4054 4-port 10Gb Ethernet Mezzanine Adapter)
+
pci:v000019A2d00000712*
ID_MODEL_FROM_DATABASE=OneConnect 10Gb iSCSI Initiator (be3)
pci:v00001B36d00000007*
ID_MODEL_FROM_DATABASE=PCI SD Card Host Controller Interface
+pci:v00001B36d00000008*
+ ID_MODEL_FROM_DATABASE=QEMU PCIe Host bridge
+
+pci:v00001B36d00000009*
+ ID_MODEL_FROM_DATABASE=QEMU PCI Expander bridge
+
pci:v00001B36d0000000A*
ID_MODEL_FROM_DATABASE=PCI-PCI bridge (multiseat)
+pci:v00001B36d0000000B*
+ ID_MODEL_FROM_DATABASE=QEMU PCIe Expander bridge
+
+pci:v00001B36d0000000C*
+ ID_MODEL_FROM_DATABASE=QEMU PCIe Root port
+
+pci:v00001B36d0000000D*
+ ID_MODEL_FROM_DATABASE=QEMU XHCI Host Controller
+
pci:v00001B36d00000100*
ID_MODEL_FROM_DATABASE=QXL paravirtual graphic card
pci:v00001B37d00000020*
ID_MODEL_FROM_DATABASE=ADQ14
+pci:v00001B37d00000023*
+ ID_MODEL_FROM_DATABASE=ADQ7
+
pci:v00001B37d00002014*
ID_MODEL_FROM_DATABASE=TX320
pci:v00001B85d00001041*
ID_MODEL_FROM_DATABASE=RevoDrive 3 X2 PCI-Express SSD 240 GB (Marvell Controller)
+pci:v00001B85d00006018*
+ ID_MODEL_FROM_DATABASE=RD400/400A SSD
+
pci:v00001B85d00008788*
ID_MODEL_FROM_DATABASE=RevoDrive Hybrid
pci:v00001CE4d00000006*
ID_MODEL_FROM_DATABASE=ExaNIC X10-HPT
+pci:v00001CE4d00000007*
+ ID_MODEL_FROM_DATABASE=ExaNIC X40
+
pci:v00001CF7*
ID_VENDOR_FROM_DATABASE=Subspace Dynamics
pci:v00001D00*
ID_VENDOR_FROM_DATABASE=Pure Storage
+pci:v00001D18*
+ ID_VENDOR_FROM_DATABASE=RME
+
+pci:v00001D18d00000001*
+ ID_MODEL_FROM_DATABASE=Fireface UFX+
+
pci:v00001D1D*
ID_VENDOR_FROM_DATABASE=CNEX Labs
pci:v00001D49*
ID_VENDOR_FROM_DATABASE=Lenovo
+pci:v00001D4C*
+ ID_VENDOR_FROM_DATABASE=Diamanti, Inc.
+
pci:v00001D5C*
ID_VENDOR_FROM_DATABASE=Fantasia Trading LLC
pci:v00001D7C*
ID_VENDOR_FROM_DATABASE=Aerotech, Inc.
+pci:v00001D87*
+ ID_VENDOR_FROM_DATABASE=Rockchip Inc. RK3399 PCI Express Root Port
+
pci:v00001D8F*
ID_VENDOR_FROM_DATABASE=Enyx
pci:v00001DA1*
ID_VENDOR_FROM_DATABASE=Teko Telecom S.r.l.
+pci:v00001DA2*
+ ID_VENDOR_FROM_DATABASE=Sapphire Technology Limited
+
pci:v00001DE1*
ID_VENDOR_FROM_DATABASE=Tekram Technology Co.,Ltd.
pci:v00001FC9d00004027*
ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter
+pci:v00001FC9d00004027sv00001154sd00000368*
+ ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (LGY-PCIE-MG)
+
pci:v00001FC9d00004027sv00001432sd00008104*
ID_MODEL_FROM_DATABASE=TN9710P 10GBase-T/NBASE-T Ethernet Adapter (10 Gigabit Ethernet PCI Express Adapter)
pci:v00005555d00000003*
ID_MODEL_FROM_DATABASE=TURBOstor HFP-832 [HiPPI NIC]
+pci:v00005555d00003B00*
+ ID_MODEL_FROM_DATABASE=Epiphan DVI2PCIe video capture card
+
pci:v00005646*
ID_VENDOR_FROM_DATABASE=Vector Fabrics BV
pci:v00005700*
ID_VENDOR_FROM_DATABASE=Netpower
+pci:v00005845*
+ ID_VENDOR_FROM_DATABASE=X-ES, Inc.
+
pci:v0000584D*
ID_VENDOR_FROM_DATABASE=AuzenTech Co., Ltd.
ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak]
pci:v00008086d00000085sv00008086sd00001311*
- ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 AGN)
+ ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 (802.11a/b/g/n))
pci:v00008086d00000085sv00008086sd00001316*
ID_MODEL_FROM_DATABASE=Centrino Advanced-N 6205 [Taylor Peak] (Centrino Advanced-N 6205 ABG)
pci:v00008086d00000104sv0000144Dsd0000C652*
ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (NP300E5C series laptop)
+pci:v00008086d00000104sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family DRAM Controller (ThinkPad T520)
+
pci:v00008086d00000105*
ID_MODEL_FROM_DATABASE=Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port
pci:v00008086d00000126sv00001028sd000004CC*
ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (Vostro 3350)
+pci:v00008086d00000126sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=2nd Generation Core Processor Family Integrated Graphics Controller (ThinkPad T520)
+
pci:v00008086d00000150*
ID_MODEL_FROM_DATABASE=Xeon E3-1200 v2/3rd Gen Core processor DRAM Controller
pci:v00008086d000010BC*
ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper)
+pci:v00008086d000010BCsv00001014sd00000368*
+ ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (4-Port 10/100/1000 Base-TX PCI Express Adapter for POWER)
+
pci:v00008086d000010BCsv0000103Csd0000704B*
ID_MODEL_FROM_DATABASE=82571EB Gigabit Ethernet Controller (Copper) (NC364T PCI Express Quad Port Gigabit Server Adapter)
ID_MODEL_FROM_DATABASE=82567V-3 Gigabit Network Connection
pci:v00008086d00001502*
- ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville)
pci:v00008086d00001502sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Precision M4600)
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (Precision M4600)
+
+pci:v00008086d00001502sv000017AAsd000021CE*
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (ThinkPad T520)
pci:v00008086d00001502sv00008086sd0000357A*
- ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Server Board S1200BTS)
+ ID_MODEL_FROM_DATABASE=82579LM Gigabit Network Connection (Lewisville) (Server Board S1200BTS)
pci:v00008086d00001503*
ID_MODEL_FROM_DATABASE=82579V Gigabit Network Connection
pci:v00008086d0000152E*
ID_MODEL_FROM_DATABASE=82599 Virtual Function
+pci:v00008086d0000152F*
+ ID_MODEL_FROM_DATABASE=I350 Virtual Function
+
pci:v00008086d00001530*
ID_MODEL_FROM_DATABASE=X540 Virtual Function
pci:v00008086d00001537sv00001059sd00000130*
ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (T4009 1GbE interface)
+pci:v00008086d00001537sv00001059sd00000140*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (T2035 1GbE interface)
+
+pci:v00008086d00001537sv00001059sd00000150*
+ ID_MODEL_FROM_DATABASE=I210 Gigabit Backplane Connection (RD-01068 1GbE interface)
+
pci:v00008086d00001538*
ID_MODEL_FROM_DATABASE=I210 Gigabit Network Connection
pci:v00008086d00001563sv00008086sd0000001A*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
+pci:v00008086d00001563sv00008086sd0000001B*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Server Adapter X550-T2 for OCP)
+
+pci:v00008086d00001563sv00008086sd0000001D*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet 10G 2P X550-t Adapter)
+
pci:v00008086d00001563sv00008086sd00000022*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T2)
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 562SFP+ Adapter)
pci:v00008086d00001572sv0000103Csd000022FC*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (HP Ethernet 10Gb 2-port 562FLR-SFP+ Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 2-port 562FLR-SFP+ Adapter)
pci:v00008086d00001572sv0000103Csd000022FD*
- ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (HP Ethernet 10Gb 2-port 562SFP+ Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet 10Gb 2-port 562SFP+ Adapter)
pci:v00008086d00001572sv00001137sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged NIC X710-DA)
pci:v00008086d00001572sv00008086sd0000000D*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+pci:v00008086d00001572sv00008086sd0000000E*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Server Adapter OCP X710-2)
+
pci:v00008086d00001572sv00008086sd00000010*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+ (Ethernet Converged Network Adapter X710)
pci:v00008086d00001572sv00008086sd00004006*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+pci:v00008086d00001572sv00008086sd00004007*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE SFP+
+
pci:v00008086d00001575*
ID_MODEL_FROM_DATABASE=DSL6340 Thunderbolt 3 NHI [Alpine Ridge 2C 2015]
pci:v00008086d00001581sv00001028sd00001F9E*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 10G 2P X710-k bNDC)
+pci:v00008086d00001581sv00001059sd00000150*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (RD-01068 10GbE-KR interface)
+
pci:v00008086d00001581sv00001590sd00000000*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710 for 10GbE backplane (Ethernet 2-port 563i Adapter)
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane
pci:v00008086d00001587sv0000103Csd00000000*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (HPE Ethernet 10/20Gb 2-port 660FLB Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660FLB Adapter)
pci:v00008086d00001587sv0000103Csd000022FE*
- ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (HPE Ethernet 10/20Gb 2-port 660FLB Adapter)
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane (Ethernet 10/20Gb 2-port 660FLB Adapter)
pci:v00008086d00001588*
ID_MODEL_FROM_DATABASE=Ethernet Controller XL710 for 20GbE backplane
pci:v00008086d00001589sv00008086sd00000002*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T4)
+pci:v00008086d00001589sv00008086sd00000003*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T)
+
+pci:v00008086d00001589sv00008086sd000000A0*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T4)
+
pci:v00008086d00001589sv00008086sd00001003*
ID_MODEL_FROM_DATABASE=Ethernet Controller X710/X557-AT 10GBASE-T (Ethernet Converged Network Adapter X710-T)
pci:v00008086d0000158Bsv00008086sd00000008*
ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter OCP XXV710-1)
+pci:v00008086d0000158Bsv00008086sd00004001*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller XXV710 for 25GbE SFP28 (Ethernet Network Adapter XXV710-2)
+
pci:v00008086d000015A0*
ID_MODEL_FROM_DATABASE=Ethernet Connection (2) I218-LM
pci:v00008086d000015AAsv00001059sd00000120*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (T4008 10GbE interface)
+pci:v00008086d000015AAsv00001059sd00000150*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane (RD-01068 10GbE interface)
+
pci:v00008086d000015AB*
ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane
pci:v00008086d000015C0*
ID_MODEL_FROM_DATABASE=JHL6240 Thunderbolt 3 Bridge (Low Power) [Alpine Ridge LP 2016]
+pci:v00008086d000015C2*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 Backplane
+
+pci:v00008086d000015C3*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 Backplane
+
+pci:v00008086d000015C4*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 10 GbE SFP+
+
pci:v00008086d000015C5*
ID_MODEL_FROM_DATABASE=X553 Virtual Function
+pci:v00008086d000015C6*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
+pci:v00008086d000015C7*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
+pci:v00008086d000015C8*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553/X557-AT 10GBASE-T
+
+pci:v00008086d000015CE*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 10 GbE SFP+
+
pci:v00008086d000015D0*
ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-100GbE-QDA2
pci:v00008086d000015D1sv00008086sd00000002*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
+pci:v00008086d000015D1sv00008086sd0000001B*
+ ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Server Adapter X550-T1 for OCP)
+
pci:v00008086d000015D1sv00008086sd00000021*
ID_MODEL_FROM_DATABASE=Ethernet Controller 10G X550T (Ethernet Converged Network Adapter X550-T1)
pci:v00008086d000015D3*
ID_MODEL_FROM_DATABASE=JHL6540 Thunderbolt 3 Bridge (C step) [Alpine Ridge 4C 2016]
+pci:v00008086d000015D4*
+ ID_MODEL_FROM_DATABASE=JHL6540 Thunderbolt 3 USB Controller (C step) [Alpine Ridge 4C 2016]
+
pci:v00008086d000015D5*
ID_MODEL_FROM_DATABASE=Ethernet SDI Adapter FM10420-25GbE-DA2
pci:v00008086d000015D8*
ID_MODEL_FROM_DATABASE=Ethernet Connection (4) I219-V
+pci:v00008086d000015D8sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (4) I219-V (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d000015D9*
ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 NHI (C step) [Alpine Ridge 2C 2016]
pci:v00008086d000015DA*
ID_MODEL_FROM_DATABASE=JHL6340 Thunderbolt 3 Bridge (C step) [Alpine Ridge 2C 2016]
+pci:v00008086d000015DF*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (8) I219-LM
+
+pci:v00008086d000015E0*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (8) I219-V
+
+pci:v00008086d000015E1*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (9) I219-LM
+
+pci:v00008086d000015E2*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection (9) I219-V
+
pci:v00008086d000015E3*
ID_MODEL_FROM_DATABASE=Ethernet Connection (5) I219-LM
+pci:v00008086d000015E4*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
+pci:v00008086d000015E5*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X553 1GbE
+
pci:v00008086d00001600*
ID_MODEL_FROM_DATABASE=Broadwell-U Host Bridge -OPI
pci:v00008086d0000163E*
ID_MODEL_FROM_DATABASE=Broadwell-U Integrated Graphics
+pci:v00008086d00001889*
+ ID_MODEL_FROM_DATABASE=Ethernet Adaptive Virtual Function
+
pci:v00008086d00001900*
ID_MODEL_FROM_DATABASE=Skylake Host Bridge/DRAM Registers
pci:v00008086d00001911*
ID_MODEL_FROM_DATABASE=Skylake Gaussian Mixture Model
+pci:v00008086d00001911sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Skylake Gaussian Mixture Model (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00001912*
ID_MODEL_FROM_DATABASE=HD Graphics 530
ID_MODEL_FROM_DATABASE=82597EX 10GbE Ethernet Controller (PRO/10GbE LR Server Adapter)
pci:v00008086d00001C00*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Desktop SATA Controller (IDE mode, ports 0-3)
pci:v00008086d00001C01*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 4 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Mobile SATA Controller (IDE mode, ports 0-3)
pci:v00008086d00001C02*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller
pci:v00008086d00001C02sv00001028sd000004AA*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (XPS 8300)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (XPS 8300)
pci:v00008086d00001C02sv00001043sd0000844D*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (P8 series motherboard)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (P8 series motherboard)
pci:v00008086d00001C02sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA AHCI Controller (Server Board S1200BTS)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Desktop SATA AHCI Controller (Server Board S1200BTS)
pci:v00008086d00001C03*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller
pci:v00008086d00001C03sv00001028sd000004A3*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Precision M4600)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Precision M4600)
pci:v00008086d00001C03sv00001028sd000004B2*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Vostro 3350)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Vostro 3350)
pci:v00008086d00001C03sv00001028sd000004DA*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Vostro 3750)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Vostro 3750)
+
+pci:v00008086d00001C03sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (ThinkPad T520)
pci:v00008086d00001C03sv00008086sd00007270*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port SATA AHCI Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 6 port Mobile SATA AHCI Controller (Apple MacBookPro8,2 [Core i7, 15", 2011])
pci:v00008086d00001C04*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Desktop SATA RAID Controller
pci:v00008086d00001C04sv0000103Csd00003118*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller (Smart Array B110i SATA RAID Controller)
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Desktop SATA RAID Controller (Smart Array B110i SATA RAID Controller)
pci:v00008086d00001C05*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SATA RAID Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Mobile SATA RAID Controller
+
+pci:v00008086d00001C06*
+ ID_MODEL_FROM_DATABASE=Z68 Express Chipset SATA RAID Controller
pci:v00008086d00001C08*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Desktop SATA Controller (IDE mode, ports 4-5)
pci:v00008086d00001C09*
- ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family 2 port SATA IDE Controller
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family Mobile SATA Controller (IDE mode, ports 4-5)
pci:v00008086d00001C10*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1
pci:v00008086d00001C10sv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (P8 series motherboard)
+pci:v00008086d00001C10sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (ThinkPad T520)
+
pci:v00008086d00001C10sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
pci:v00008086d00001C12sv00001028sd000004AA*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (XPS 8300)
+pci:v00008086d00001C12sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (ThinkPad T520)
+
pci:v00008086d00001C12sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 2 (Apple MacBookPro8,2 [Core i7, 15", 2011])
pci:v00008086d00001C16sv00001028sd000004AA*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4 (XPS 8300)
+pci:v00008086d00001C16sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 4 (ThinkPad T520)
+
pci:v00008086d00001C18*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5
pci:v00008086d00001C18sv00001028sd000004DA*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (Vostro 3750)
+pci:v00008086d00001C18sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (ThinkPad T520)
+
pci:v00008086d00001C18sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family PCI Express Root Port 5 (Server Board S1200BTS)
pci:v00008086d00001C20sv00001043sd0000841B*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (P8H67 Series Motherboard)
+pci:v00008086d00001C20sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (ThinkPad T520)
+
pci:v00008086d00001C20sv00008086sd00002008*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family High Definition Audio Controller (DQ67SW board)
pci:v00008086d00001C22sv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (P8 series motherboard)
+pci:v00008086d00001C22sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (ThinkPad T520)
+
pci:v00008086d00001C22sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family SMBus Controller (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
pci:v00008086d00001C26sv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (P8 series motherboard)
+pci:v00008086d00001C26sv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (ThinkPad T520)
+
pci:v00008086d00001C26sv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #1 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
pci:v00008086d00001C2Dsv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (P8 series motherboard)
+pci:v00008086d00001C2Dsv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (ThinkPad T520)
+
pci:v00008086d00001C2Dsv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family USB Enhanced Host Controller #2 (Server Board S1200BTS / Apple MacBook Pro 8,1/8,2)
pci:v00008086d00001C3Asv00001043sd0000844D*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (P8 series motherboard)
+pci:v00008086d00001C3Asv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (ThinkPad T520)
+
pci:v00008086d00001C3Asv00008086sd00007270*
ID_MODEL_FROM_DATABASE=6 Series/C200 Series Chipset Family MEI Controller #1 (Apple MacBookPro8,2 [Core i7, 15", 2011])
pci:v00008086d00001C4Fsv00001028sd000004A3*
ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (Precision M4600)
+pci:v00008086d00001C4Fsv000017AAsd000021CF*
+ ID_MODEL_FROM_DATABASE=QM67 Express Chipset Family LPC Controller (ThinkPad T520)
+
pci:v00008086d00001C50*
ID_MODEL_FROM_DATABASE=B65 Express Chipset Family LPC Controller
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller
pci:v00008086d00001E20sv00001028sd0000054B*
- ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (Dell XPS One 2710)
+ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (XPS One 2710)
pci:v00008086d00001E20sv00001043sd0000108D*
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (VivoBook X202EV)
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (P8H77-I Motherboard)
pci:v00008086d00001E20sv00001043sd00008445*
- ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (ASUS P8Z77-V LX Motherboard)
+ ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (P8Z77-V LX Motherboard)
pci:v00008086d00001E20sv0000144Dsd0000C652*
ID_MODEL_FROM_DATABASE=7 Series/C216 Chipset Family High Definition Audio Controller (NP300E5C series laptop)
ID_MODEL_FROM_DATABASE=Sky Lake-E MM/Vt-d Configuration Registers
pci:v00008086d00002030*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1A
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port A
pci:v00008086d00002031*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1B
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port B
pci:v00008086d00002032*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1C
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port C
pci:v00008086d00002033*
- ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port 1D
+ ID_MODEL_FROM_DATABASE=Sky Lake-E PCI Express Root Port D
pci:v00008086d00002035*
ID_MODEL_FROM_DATABASE=Sky Lake-E RAS Configuration Registers
pci:v00008086d000024FDsv00008086sd00000010*
ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265)
+pci:v00008086d000024FDsv00008086sd00001130*
+ ID_MODEL_FROM_DATABASE=Wireless 8265 / 8275 (Dual Band Wireless-AC 8265)
+
pci:v00008086d00002500*
ID_MODEL_FROM_DATABASE=82820 820 (Camino) Chipset Host Bridge (MCH)
ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (ThinkPad X41 / Z60t)
pci:v00008086d00002590sv00001028sd00000182*
- ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Dell Latitude C610)
+ ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Latitude C610)
pci:v00008086d00002590sv0000103Csd00000934*
ID_MODEL_FROM_DATABASE=Mobile 915GM/PM/GMS/910GML Express Processor to DRAM Controller (Compaq nw8240/nx8220)
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (PufferM-UL8E)
pci:v00008086d00002668sv00001043sd00001173*
- ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (Asus A6VC)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (A6VC)
pci:v00008086d00002668sv00001043sd0000814E*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller (P5GD1-VW Mainboard)
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Latitude D610 Laptop)
pci:v00008086d0000266Esv00001028sd00000187*
- ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Dell Precision M70 Laptop)
+ ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Precision M70 Laptop)
pci:v00008086d0000266Esv00001028sd00000188*
ID_MODEL_FROM_DATABASE=82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller (Inspiron 6000 laptop)
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (A6J-Q008)
pci:v00008086d000027D8sv00001043sd000013C4*
- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Asus G2P)
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (G2P)
pci:v00008086d000027D8sv00001043sd0000817F*
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (P5LD2-VM Mainboard (Realtek ALC 882 codec))
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (ThinkPad R60/T60/X60 series)
pci:v00008086d000027D8sv000017AAsd00003802*
- ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (Lenovo 3000 C200 audio [Realtek ALC861VD])
+ ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (3000 C200 audio [Realtek ALC861VD])
pci:v00008086d000027D8sv00008086sd00001112*
ID_MODEL_FROM_DATABASE=NM10/ICH7 Family High Definition Audio Controller (DeskTop Board D945GTP)
pci:v00008086d00002815sv0000104Dsd0000902D*
ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (VAIO VGN-NR120E)
+pci:v00008086d00002815sv000017AAsd000020A5*
+ ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (ThinkPad R61)
+
pci:v00008086d00002815sv000017C0sd00004083*
ID_MODEL_FROM_DATABASE=82801HM (ICH8M) LPC Interface Controller (Medion WIM 2210 Notebook PC [MD96850])
pci:v00008086d00002828sv0000103Csd000030C0*
ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (Compaq 6710b)
+pci:v00008086d00002828sv000017AAsd000020A8*
+ ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (ThinkPad R61)
+
pci:v00008086d00002828sv0000E4BFsd0000CC47*
ID_MODEL_FROM_DATABASE=82801HM/HEM (ICH8M/ICH8M-E) SATA Controller [IDE mode] (CCG-RUMBA)
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1
pci:v00008086d00002830sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (Aspire 5920G)
pci:v00008086d00002830sv00001028sd000001DA*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #1 (OptiPlex 745)
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5
pci:v00008086d00002835sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (Aspire 5920G)
pci:v00008086d00002835sv00001028sd000001DA*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB UHCI Controller #5 (OptiPlex 745)
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2
pci:v00008086d0000283Asv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (Aspire 5920G)
pci:v00008086d0000283Asv00001028sd000001DA*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) USB2 EHCI Controller #2 (OptiPlex 745)
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Inspiron 1420)
pci:v00008086d0000284Bsv00001028sd000001F9*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Latitude D630)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Latitude D630)
pci:v00008086d0000284Bsv00001028sd000001FF*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Dell Precision M4300)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Precision M4300)
pci:v00008086d0000284Bsv00001028sd00000256*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Studio 1735)
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Pavilion dv6700)
pci:v00008086d0000284Bsv00001043sd00001339*
- ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (Asus M51S series)
+ ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (M51S series)
pci:v00008086d0000284Bsv00001043sd000081EC*
ID_MODEL_FROM_DATABASE=82801H (ICH8 Family) HD Audio Controller (P5B)
ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub
pci:v00008086d00002A00sv00001025sd00000121*
- ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Acer Aspire 5920G)
+ ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Aspire 5920G)
pci:v00008086d00002A00sv00001028sd000001F3*
ID_MODEL_FROM_DATABASE=Mobile PM965/GM965/GL960 Memory Controller Hub (Inspiron 1420)
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (VAIO VGN-NR120E)
pci:v00008086d00002A02sv000017AAsd000020B5*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (ThinkPad T61/R61)
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (GM965 [X3100] on ThinkPad T61/R61)
pci:v00008086d00002A02sv000017C0sd00004082*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (Medion WIM 2210 Notebook PC [MD96850])
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (GM965 on Medion WIM 2210 Notebook PC [MD96850])
pci:v00008086d00002A02sv0000E4BFsd0000CC47*
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (primary) (CCG-RUMBA)
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (VAIO VGN-NR120E)
pci:v00008086d00002A03sv000017AAsd000020B5*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (ThinkPad T61/R61)
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (GM965 [X3100] on ThinkPad T61/R61)
pci:v00008086d00002A03sv000017C0sd00004082*
- ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (Medion WIM 2210 Notebook PC [MD96850])
+ ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (GM965 on Medion WIM 2210 Notebook PC [MD96850])
pci:v00008086d00002A03sv0000E4BFsd0000CC47*
ID_MODEL_FROM_DATABASE=Mobile GM965/GL960 Integrated Graphics Controller (secondary) (CCG-RUMBA)
ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller
pci:v00008086d00002E20sv00001028sd00000283*
- ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (Dell Vostro 220)
+ ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (Vostro 220)
pci:v00008086d00002E20sv00001043sd000082D3*
ID_MODEL_FROM_DATABASE=4 Series Chipset DRAM Controller (P5Q Deluxe Motherboard)
pci:v00008086d000037D1sv00001590sd00000217*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Ethernet 1Gb 2-port 368FLR-MMT Adapter)
+pci:v00008086d000037D1sv00001590sd00000247*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Ethernet 1Gb 4-port 369i Adapter)
+
pci:v00008086d000037D1sv000017AAsd00004020*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 1GbE (Intel Ethernet Connection X722 for 1GbE)
pci:v00008086d000037D2*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
+pci:v00008086d000037D2sv000014CDsd00000030*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Ethernet OCP 2x10G RJ45 Phy Card [USI-X557-10GbaseT])
+
pci:v00008086d000037D2sv00001590sd00000218*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Ethernet 10Gb 2-port 568FLR-MMT Adapter)
pci:v00008086d000037D2sv000017AAsd00004020*
- ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Intel Ethernet Connection X722 for 10GBASE)
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
pci:v00008086d000037D2sv000017AAsd00004021*
- ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T (Intel Ethernet Connection X722 for 10GBASE)
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
pci:v00008086d000037D2sv000017AAsd00004022*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GBASE-T
pci:v00008086d000037D3sv00001590sd00000219*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+ (Ethernet 10Gb 2-port 568FLR-MMSFP+ Adapter)
+pci:v00008086d000037D3sv000017AAsd00004020*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
+pci:v00008086d000037D3sv000017AAsd00004021*
+ ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE SFP+
+
pci:v00008086d000037D4*
ID_MODEL_FROM_DATABASE=Ethernet Connection X722 for 10GbE QSFP+
ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (Latitude E6510)
pci:v00008086d00003B56sv00001043sd00001373*
- ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (ASUSTek G73-series gaming laptop)
+ ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (G73-series gaming laptop)
pci:v00008086d00003B56sv0000144Dsd0000C06A*
ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset High Definition Audio (R730 Laptop)
pci:v00008086d00004223sv00001003sd00008086*
ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (mPCI 3B High-Band ZZH)
-pci:v00008086d00004223sv00001351sd0000103C*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (Compaq NC6220)
+pci:v00008086d00004223sv0000103Csd00001351*
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection (Compaq nc6220)
pci:v00008086d00004224*
ID_MODEL_FROM_DATABASE=PRO/Wireless 2915ABG [Calexico2] Network Connection
ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad R60e)
pci:v00008086d00004227sv00008086sd00001011*
- ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad T60/R60e/X60s)
+ ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (ThinkPad T60/R60e/X60s/R61)
pci:v00008086d00004227sv00008086sd00001014*
ID_MODEL_FROM_DATABASE=PRO/Wireless 3945ABG [Golan] Network Connection (PRO/Wireless 3945BG Network Connection)
pci:v00008086d00005845sv00001AF4sd00001100*
ID_MODEL_FROM_DATABASE=QEMU NVM Express Controller (QEMU Virtual Machine)
+pci:v00008086d00005902*
+ ID_MODEL_FROM_DATABASE=HD Graphics 610
+
+pci:v00008086d00005904*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
+
+pci:v00008086d00005904sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers (ThinkPad X1 Carbon 5th Gen)
+
+pci:v00008086d0000590F*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
+
+pci:v00008086d00005910*
+ ID_MODEL_FROM_DATABASE=Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers
+
+pci:v00008086d00005912*
+ ID_MODEL_FROM_DATABASE=HD Graphics 630
+
+pci:v00008086d00005916*
+ ID_MODEL_FROM_DATABASE=HD Graphics 620
+
+pci:v00008086d00005916sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=HD Graphics 620 (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00005A84*
ID_MODEL_FROM_DATABASE=Celeron N3350/Pentium N4200/Atom E3900 Series Integrated Graphics Controller
pci:v00008086d00009D03sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP SATA Controller [AHCI mode] (B51-80 Laptop)
+pci:v00008086d00009D10*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #1
+
+pci:v00008086d00009D12*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #3
+
pci:v00008086d00009D14*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP PCI Express Root Port #5
pci:v00008086d00009D21sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (Latitude 3570)
+pci:v00008086d00009D21sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D21sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP PMC (B51-80 Laptop)
pci:v00008086d00009D23sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (Latitude 3570)
+pci:v00008086d00009D23sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D23sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP SMBus (B51-80 Laptop)
pci:v00008086d00009D31sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (Latitude 3570)
+pci:v00008086d00009D31sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D31sv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP Thermal subsystem (B51-80 Laptop)
pci:v00008086d00009D3Asv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (Latitude 3570)
+pci:v00008086d00009D3Asv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D3Asv000017AAsd0000382A*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP CSME HECI #1 (B51-80 Laptop)
pci:v00008086d00009D48sv00001028sd000006F3*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (Latitude 3570)
+pci:v00008086d00009D58*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller
+
+pci:v00008086d00009D58sv000017AAsd0000224F*
+ ID_MODEL_FROM_DATABASE=Sunrise Point-LP LPC Controller (ThinkPad X1 Carbon 5th Gen)
+
pci:v00008086d00009D60*
ID_MODEL_FROM_DATABASE=Sunrise Point-LP Serial IO I2C Controller #0
pci:v00008086d0000A282*
ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [AHCI mode]
-pci:v00008086d0000A294*
+pci:v00008086d0000A286*
+ ID_MODEL_FROM_DATABASE=200 Series PCH SATA controller [RAID mode]
+
+pci:v00008086d0000A290*
ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #1
+pci:v00008086d0000A291*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #2
+
+pci:v00008086d0000A292*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #3
+
+pci:v00008086d0000A293*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #4
+
+pci:v00008086d0000A294*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #5
+
+pci:v00008086d0000A295*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #6
+
+pci:v00008086d0000A296*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #7
+
+pci:v00008086d0000A297*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #8
+
+pci:v00008086d0000A298*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #9
+
+pci:v00008086d0000A299*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #10
+
+pci:v00008086d0000A29A*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #11
+
+pci:v00008086d0000A29B*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #12
+
+pci:v00008086d0000A29C*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #13
+
+pci:v00008086d0000A29D*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #14
+
+pci:v00008086d0000A29E*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #15
+
+pci:v00008086d0000A29F*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #16
+
pci:v00008086d0000A2A1*
ID_MODEL_FROM_DATABASE=200 Series PCH PMC
pci:v00008086d0000A2BB*
ID_MODEL_FROM_DATABASE=200 Series PCH CSME HECI #2
+pci:v00008086d0000A2C4*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (H270)
+
+pci:v00008086d0000A2C5*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Z270)
+
pci:v00008086d0000A2C6*
- ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Q270)
+
+pci:v00008086d0000A2C7*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (Q250)
+
+pci:v00008086d0000A2C8*
+ ID_MODEL_FROM_DATABASE=200 Series PCH LPC Controller (B250)
pci:v00008086d0000A2E0*
ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO I2C Controller #0
pci:v00008086d0000A2E6*
ID_MODEL_FROM_DATABASE=200 Series PCH Serial IO UART Controller #2
+pci:v00008086d0000A2E7*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #17
+
+pci:v00008086d0000A2E8*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #18
+
+pci:v00008086d0000A2E9*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #19
+
+pci:v00008086d0000A2EA*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #20
+
+pci:v00008086d0000A2EB*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #21
+
+pci:v00008086d0000A2EC*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #22
+
+pci:v00008086d0000A2ED*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #23
+
+pci:v00008086d0000A2EE*
+ ID_MODEL_FROM_DATABASE=200 Series PCH PCI Express Root Port #24
+
pci:v00008086d0000A2F0*
ID_MODEL_FROM_DATABASE=200 Series PCH HD Audio
pci:v00009005d0000028Dsv00009005sd00000554*
ID_MODEL_FROM_DATABASE=Series 8 12G SAS/PCIe 3 (Series 8 - ASR-8885 - 8 internal 8 external 12G SAS Port/PCIe 3.0)
+pci:v00009005d0000028F*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3
+
+pci:v00009005d0000028Fsv0000103Csd00000600*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000601*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408e-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000602*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-a SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000603*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408i-c SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000650*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000651*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208e-p SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000652*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-c SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000654*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array E208i-a SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000655*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P408e-m SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000700*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P204i-c SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00000701*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P204i-b SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00001100*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P816i-a SR Gen10)
+
+pci:v00009005d0000028Fsv0000103Csd00001101*
+ ID_MODEL_FROM_DATABASE=Smart Storage PQI 12G SAS/PCIe 3 (Smart Array P416ie-m SR G10)
+
pci:v00009005d00000410*
ID_MODEL_FROM_DATABASE=AIC-9410W SAS (Razor HBA RAID)
pci:v0000F1D0d0000DAFF*
ID_MODEL_FROM_DATABASE=KONA LHi
+pci:v0000F1D0d0000DB01*
+ ID_MODEL_FROM_DATABASE=Corvid22
+
pci:v0000F1D0d0000DB09*
ID_MODEL_FROM_DATABASE=Corvid 24
pci:v0000F1D0d0000DFEE*
ID_MODEL_FROM_DATABASE=Xena HD-DA
+pci:v0000F1D0d0000EB0E*
+ ID_MODEL_FROM_DATABASE=Corvid 44
+
pci:v0000F1D0d0000EFAC*
ID_MODEL_FROM_DATABASE=Xena SD-MM/SD-22-MM
usb:v041Ep3220*
ID_MODEL_FROM_DATABASE=Sound Blaster Tactic(3D) Sigma sound card
+usb:v041Ep3232*
+ ID_MODEL_FROM_DATABASE=Sound Blaster Premium HD [SBX]
+
usb:v041Ep3F00*
ID_MODEL_FROM_DATABASE=E-Mu Xboard 25 MIDI Controller
usb:v0430pA103*
ID_MODEL_FROM_DATABASE=remote storage for P3 chip
+usb:v0430pA111*
+ ID_MODEL_FROM_DATABASE=remote keyboard for P4 chip
+
+usb:v0430pA112*
+ ID_MODEL_FROM_DATABASE=remote mouse for P4 chip
+
+usb:v0430pA113*
+ ID_MODEL_FROM_DATABASE=remote storage for P4 chip
+
usb:v0430pA4A2*
ID_MODEL_FROM_DATABASE=Ethernet (RNDIS and CDC ethernet)
usb:v043Ep3001*
ID_MODEL_FROM_DATABASE=AN-WF100 802.11abgn Wireless Adapter [Broadcom BCM4323]
+usb:v043Ep3004*
+ ID_MODEL_FROM_DATABASE=TWFM-B003D 802.11abgn Wireless Module [Broadcom BCM43236B]
+
+usb:v043Ep3101*
+ ID_MODEL_FROM_DATABASE=AN-WF500 802.11abgn + BT Wireless Adapter [Broadcom BCM43242]
+
usb:v043Ep42BD*
ID_MODEL_FROM_DATABASE=Flatron 795FT Plus Monitor
usb:v045Ep0761*
ID_MODEL_FROM_DATABASE=LifeCam VX-2000
+usb:v045Ep0765*
+ ID_MODEL_FROM_DATABASE=Xbox360 Slim Internal Wireless Module (1400) [Marvell 88W8786U]
+
usb:v045Ep0766*
ID_MODEL_FROM_DATABASE=LifeCam VX-800
usb:v046Dp082B*
ID_MODEL_FROM_DATABASE=Webcam C170
+usb:v046Dp082C*
+ ID_MODEL_FROM_DATABASE=HD Webcam C615
+
usb:v046Dp082D*
ID_MODEL_FROM_DATABASE=HD Pro Webcam C920
usb:v046DpC07E*
ID_MODEL_FROM_DATABASE=G402 Gaming Mouse
+usb:v046DpC083*
+ ID_MODEL_FROM_DATABASE=G403 Prodigy Gaming Mouse
+
usb:v046DpC101*
ID_MODEL_FROM_DATABASE=UltraX Media Remote
usb:v046DpC31D*
ID_MODEL_FROM_DATABASE=Media Keyboard K200
+usb:v046DpC31F*
+ ID_MODEL_FROM_DATABASE=Comfort Keyboard K290
+
usb:v046DpC332*
ID_MODEL_FROM_DATABASE=G502 Proteus Spectrum Optical Mouse
+usb:v046DpC335*
+ ID_MODEL_FROM_DATABASE=G910 Orion Spectrum Mechanical Keyboard
+
usb:v046DpC401*
ID_MODEL_FROM_DATABASE=TrackMan Marble Wheel
usb:v048Dp9507*
ID_MODEL_FROM_DATABASE=ITE it9507 full featured DVB-T transmission chip [ccHDtv]
+usb:v048Dp9910*
+ ID_MODEL_FROM_DATABASE=IT9910 chipset based grabber
+
usb:v048F*
ID_VENDOR_FROM_DATABASE=Eicon Tech.
usb:v04A9p1608*
ID_MODEL_FROM_DATABASE=DR-2580C Scanner
+usb:v04A9p1609*
+ ID_MODEL_FROM_DATABASE=DR-3080CII
+
usb:v04A9p1700*
ID_MODEL_FROM_DATABASE=PIXMA MP110 Scanner
ID_MODEL_FROM_DATABASE=PIXMA MP750 Scanner
usb:v04A9p1707*
- ID_MODEL_FROM_DATABASE=PIXMA MP780 Scanner
+ ID_MODEL_FROM_DATABASE=PIXMA MP780/MP790
usb:v04A9p1708*
- ID_MODEL_FROM_DATABASE=PIXMA MP760 Scanner
+ ID_MODEL_FROM_DATABASE=PIXMA MP760/MP770
usb:v04A9p1709*
ID_MODEL_FROM_DATABASE=PIXMA MP150 Scanner
ID_MODEL_FROM_DATABASE=PIXMA MP800 Scanner
usb:v04A9p170E*
- ID_MODEL_FROM_DATABASE=MP800R
+ ID_MODEL_FROM_DATABASE=PIXMA MP800R
usb:v04A9p1710*
ID_MODEL_FROM_DATABASE=MP950
usb:v04A9p1712*
- ID_MODEL_FROM_DATABASE=MP530
+ ID_MODEL_FROM_DATABASE=PIXMA MP530
usb:v04A9p1713*
ID_MODEL_FROM_DATABASE=PIXMA MP830 Scanner
ID_MODEL_FROM_DATABASE=MP160
usb:v04A9p1715*
- ID_MODEL_FROM_DATABASE=MP180 Storage
+ ID_MODEL_FROM_DATABASE=PIXMA MP180
usb:v04A9p1716*
- ID_MODEL_FROM_DATABASE=MP460 Composite
+ ID_MODEL_FROM_DATABASE=PIXMA MP460
usb:v04A9p1717*
- ID_MODEL_FROM_DATABASE=MP510
+ ID_MODEL_FROM_DATABASE=PIXMA MP510
usb:v04A9p1718*
- ID_MODEL_FROM_DATABASE=MP600 Storage
+ ID_MODEL_FROM_DATABASE=PIXMA MP600
+
+usb:v04A9p1719*
+ ID_MODEL_FROM_DATABASE=PIXMA MP600R
usb:v04A9p171A*
- ID_MODEL_FROM_DATABASE=MP810 Storage
+ ID_MODEL_FROM_DATABASE=PIXMA MP810
usb:v04A9p171B*
- ID_MODEL_FROM_DATABASE=MP960
+ ID_MODEL_FROM_DATABASE=PIXMA MP960
+
+usb:v04A9p171C*
+ ID_MODEL_FROM_DATABASE=PIXMA MX7600
usb:v04A9p1721*
- ID_MODEL_FROM_DATABASE=MP210 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP210
+
+usb:v04A9p1722*
+ ID_MODEL_FROM_DATABASE=PIXMA MP220
usb:v04A9p1723*
- ID_MODEL_FROM_DATABASE=MP470 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP470
usb:v04A9p1724*
ID_MODEL_FROM_DATABASE=PIXMA MP520 series
usb:v04A9p1725*
- ID_MODEL_FROM_DATABASE=MP610 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP610
usb:v04A9p1726*
- ID_MODEL_FROM_DATABASE=MP970 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MP970
usb:v04A9p1727*
- ID_MODEL_FROM_DATABASE=MX300 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX300
usb:v04A9p1728*
ID_MODEL_FROM_DATABASE=PIXMA MX310 series
usb:v04A9p1729*
- ID_MODEL_FROM_DATABASE=MX700 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX700
usb:v04A9p172B*
ID_MODEL_FROM_DATABASE=MP140 ser
+usb:v04A9p172C*
+ ID_MODEL_FROM_DATABASE=PIXMA MX850
+
+usb:v04A9p172D*
+ ID_MODEL_FROM_DATABASE=PIXMA MP980
+
+usb:v04A9p172E*
+ ID_MODEL_FROM_DATABASE=PIXMA MP630
+
+usb:v04A9p172F*
+ ID_MODEL_FROM_DATABASE=PIXMA MP620
+
+usb:v04A9p1730*
+ ID_MODEL_FROM_DATABASE=PIXMA MP540
+
+usb:v04A9p1731*
+ ID_MODEL_FROM_DATABASE=PIXMA MP480
+
+usb:v04A9p1732*
+ ID_MODEL_FROM_DATABASE=PIXMA MP240
+
+usb:v04A9p1733*
+ ID_MODEL_FROM_DATABASE=PIXMA MP260
+
+usb:v04A9p1734*
+ ID_MODEL_FROM_DATABASE=PIXMA MP190
+
+usb:v04A9p1735*
+ ID_MODEL_FROM_DATABASE=PIXMA MX860
+
usb:v04A9p1736*
ID_MODEL_FROM_DATABASE=PIXMA MX320 series
+usb:v04A9p1737*
+ ID_MODEL_FROM_DATABASE=PIXMA MX330
+
usb:v04A9p173A*
- ID_MODEL_FROM_DATABASE=MP250 series printer
+ ID_MODEL_FROM_DATABASE=PIXMA MP250
usb:v04A9p173B*
ID_MODEL_FROM_DATABASE=PIXMA MP270 All-In-One Printer
+usb:v04A9p173C*
+ ID_MODEL_FROM_DATABASE=PIXMA MP490
+
+usb:v04A9p173D*
+ ID_MODEL_FROM_DATABASE=PIXMA MP550
+
usb:v04A9p173E*
- ID_MODEL_FROM_DATABASE=MP560
+ ID_MODEL_FROM_DATABASE=PIXMA MP560
usb:v04A9p173F*
- ID_MODEL_FROM_DATABASE=Pixma MP640 Multifunction device
+ ID_MODEL_FROM_DATABASE=PIXMA MP640
+
+usb:v04A9p1740*
+ ID_MODEL_FROM_DATABASE=PIXMA MP990
+
+usb:v04A9p1741*
+ ID_MODEL_FROM_DATABASE=PIXMA MX340
+
+usb:v04A9p1742*
+ ID_MODEL_FROM_DATABASE=PIXMA MX350
+
+usb:v04A9p1743*
+ ID_MODEL_FROM_DATABASE=PIXMA MX870
+
+usb:v04A9p1746*
+ ID_MODEL_FROM_DATABASE=PIXMA MP280
+
+usb:v04A9p1747*
+ ID_MODEL_FROM_DATABASE=PIXMA MP495
usb:v04A9p1748*
- ID_MODEL_FROM_DATABASE=Pixma MG5150
+ ID_MODEL_FROM_DATABASE=PIXMA MG5100 Series
+
+usb:v04A9p1749*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5200 Series
+
+usb:v04A9p174A*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6100 Series
+
+usb:v04A9p174B*
+ ID_MODEL_FROM_DATABASE=PIXMA MG8100 Series
usb:v04A9p174D*
- ID_MODEL_FROM_DATABASE=MX360 ser
+ ID_MODEL_FROM_DATABASE=PIXMA MX360
+
+usb:v04A9p174E*
+ ID_MODEL_FROM_DATABASE=PIXMA MX410
+
+usb:v04A9p174F*
+ ID_MODEL_FROM_DATABASE=PIXMA MX420
+
+usb:v04A9p1750*
+ ID_MODEL_FROM_DATABASE=PIXMA MX880 Series
+
+usb:v04A9p1752*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3100 Series
+
+usb:v04A9p1753*
+ ID_MODEL_FROM_DATABASE=PIXMA MG4100 Series
+
+usb:v04A9p1754*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5300 Series
+
+usb:v04A9p1755*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6200 Series
+
+usb:v04A9p1756*
+ ID_MODEL_FROM_DATABASE=PIXMA MG8200 Series
+
+usb:v04A9p1757*
+ ID_MODEL_FROM_DATABASE=PIXMA MP493
+
+usb:v04A9p1759*
+ ID_MODEL_FROM_DATABASE=PIXMA MX370 Series
+
+usb:v04A9p175B*
+ ID_MODEL_FROM_DATABASE=PIXMA MX430 Series
+
+usb:v04A9p175C*
+ ID_MODEL_FROM_DATABASE=PIXMA MX510 Series
+
+usb:v04A9p175D*
+ ID_MODEL_FROM_DATABASE=PIXMA MX710 Series
+
+usb:v04A9p175E*
+ ID_MODEL_FROM_DATABASE=PIXMA MX890 Series
+
+usb:v04A9p175F*
+ ID_MODEL_FROM_DATABASE=PIXMA MP230
+
+usb:v04A9p1762*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3200 Series
+
+usb:v04A9p1763*
+ ID_MODEL_FROM_DATABASE=PIXMA MG4200 Series
+
+usb:v04A9p1764*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5400 Series
+
+usb:v04A9p1765*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6300 Series
+
+usb:v04A9p1766*
+ ID_MODEL_FROM_DATABASE=PIXMA MX390 Series
+
+usb:v04A9p1768*
+ ID_MODEL_FROM_DATABASE=PIXMA MX450 Series
+
+usb:v04A9p1769*
+ ID_MODEL_FROM_DATABASE=PIXMA MX520 Series
+
+usb:v04A9p176A*
+ ID_MODEL_FROM_DATABASE=PIXMA MX720 Series
+
+usb:v04A9p176B*
+ ID_MODEL_FROM_DATABASE=PIXMA MX920 Series
usb:v04A9p176D*
- ID_MODEL_FROM_DATABASE=PIXMA MG2550
+ ID_MODEL_FROM_DATABASE=PIXMA MG2500 Series
+
+usb:v04A9p176E*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3500 Series
+
+usb:v04A9p176F*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6500 Series
+
+usb:v04A9p1770*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6400 Series
+
+usb:v04A9p1771*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5500 Series
+
+usb:v04A9p1772*
+ ID_MODEL_FROM_DATABASE=PIXMA MG7100 Series
+
+usb:v04A9p1774*
+ ID_MODEL_FROM_DATABASE=PIXMA MX470 Series
+
+usb:v04A9p1775*
+ ID_MODEL_FROM_DATABASE=PIXMA MX530 Series
+
+usb:v04A9p177C*
+ ID_MODEL_FROM_DATABASE=PIXMA MG7500 Series
+
+usb:v04A9p177E*
+ ID_MODEL_FROM_DATABASE=PIXMA MG6600 Series
+
+usb:v04A9p177F*
+ ID_MODEL_FROM_DATABASE=PIXMA MG5600 Series
+
+usb:v04A9p1780*
+ ID_MODEL_FROM_DATABASE=PIXMA MG2900 Series
+
+usb:v04A9p1787*
+ ID_MODEL_FROM_DATABASE=PIXMA MX490 Series
+
+usb:v04A9p178A*
+ ID_MODEL_FROM_DATABASE=PIXMA MG3600 Series
usb:v04A9p178D*
ID_MODEL_FROM_DATABASE=PIXMA MG6853
ID_MODEL_FROM_DATABASE=iR C3200
usb:v04A9p262F*
- ID_MODEL_FROM_DATABASE=MultiPASS MP730
+ ID_MODEL_FROM_DATABASE=PIXMA MP730
usb:v04A9p2630*
- ID_MODEL_FROM_DATABASE=MultiPASS MP700
+ ID_MODEL_FROM_DATABASE=PIXMA MP700
usb:v04A9p2631*
ID_MODEL_FROM_DATABASE=LASER CLASS 700
ID_MODEL_FROM_DATABASE=iR C3100
usb:v04A9p263C*
- ID_MODEL_FROM_DATABASE=Smartbase MP360
+ ID_MODEL_FROM_DATABASE=PIXMA MP360
usb:v04A9p263D*
- ID_MODEL_FROM_DATABASE=MP370
+ ID_MODEL_FROM_DATABASE=PIXMA MP370
usb:v04A9p263E*
- ID_MODEL_FROM_DATABASE=MP390 FAX
+ ID_MODEL_FROM_DATABASE=PIXMA MP390
usb:v04A9p263F*
- ID_MODEL_FROM_DATABASE=MP375
+ ID_MODEL_FROM_DATABASE=PIXMA MP375R
usb:v04A9p2646*
ID_MODEL_FROM_DATABASE=MF5530 Scanner Device V1.9.1
usb:v04A9p2647*
ID_MODEL_FROM_DATABASE=MF5550 Composite
+usb:v04A9p264C*
+ ID_MODEL_FROM_DATABASE=PIXMA MP740
+
usb:v04A9p264D*
ID_MODEL_FROM_DATABASE=PIXMA MP710
usb:v04A9p327A*
ID_MODEL_FROM_DATABASE=SELPHY CP910
+usb:v04A9p327B*
+ ID_MODEL_FROM_DATABASE=SELPHY CP820
+
usb:v04A9p327D*
ID_MODEL_FROM_DATABASE=Powershot ELPH 115 IS / IXUS 132
usb:v04A9p32BB*
ID_MODEL_FROM_DATABASE=EOS M5
+usb:v04A9p32BF*
+ ID_MODEL_FROM_DATABASE=PowerShot SX420 IS
+
usb:v04A9p32C1*
ID_MODEL_FROM_DATABASE=PowerShot ELPH 180 / IXUS 175
usb:v04A9p32C2*
ID_MODEL_FROM_DATABASE=PowerShot SX720 HS
+usb:v04A9p32D5*
+ ID_MODEL_FROM_DATABASE=PowerShot SX430 IS
+
usb:v04AA*
ID_VENDOR_FROM_DATABASE=DaeWoo Telecom, Ltd
usb:v04B0p042A*
ID_MODEL_FROM_DATABASE=D800 (ptp)
+usb:v04B0p043F*
+ ID_MODEL_FROM_DATABASE=D5600
+
usb:v04B0p0F03*
ID_MODEL_FROM_DATABASE=PD-10 Wireless Printer Adapter
usb:v04D9p0499*
ID_MODEL_FROM_DATABASE=Optical Mouse
+usb:v04D9p1135*
+ ID_MODEL_FROM_DATABASE=Mouse [MGK-15BU/MLK-15BU]
+
usb:v04D9p1203*
ID_MODEL_FROM_DATABASE=Keyboard
usb:v04D9pA055*
ID_MODEL_FROM_DATABASE=Keyboard
+usb:v04D9pA100*
+ ID_MODEL_FROM_DATABASE=Mouse [HV-MS735]
+
usb:v04D9pA11B*
ID_MODEL_FROM_DATABASE=Mouse [MX-3200]
usb:v04DAp3904*
ID_MODEL_FROM_DATABASE=N5HBZ0000055 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+usb:v04DAp3908*
+ ID_MODEL_FROM_DATABASE=N5HBZ0000062 802.11abgn Wireless Adapter [Atheros AR9374v1.1]
+
usb:v04DAp3C04*
ID_MODEL_FROM_DATABASE=JT-P100MR-20 [ePassport Reader]
usb:v04E6p5591*
ID_MODEL_FROM_DATABASE=SCL3711-NFC&RW
+usb:v04E6p5810*
+ ID_MODEL_FROM_DATABASE=uTrust 2700 R Smart Card Reader
+
usb:v04E6pE000*
ID_MODEL_FROM_DATABASE=SCRx31 Reader
usb:v04E8p330C*
ID_MODEL_FROM_DATABASE=ML-1865
+usb:v04E8p330F*
+ ID_MODEL_FROM_DATABASE=ML-216x Series Laser Printer
+
usb:v04E8p3310*
ID_MODEL_FROM_DATABASE=ML-331x Series Laser Printer
usb:v04F2pB394*
ID_MODEL_FROM_DATABASE=Integrated Camera
+usb:v04F2pB3EB*
+ ID_MODEL_FROM_DATABASE=HP 720p HD Monitor Webcam
+
usb:v04F2pB3F6*
ID_MODEL_FROM_DATABASE=HD WebCam (Acer)
usb:v0547p4D90*
ID_MODEL_FROM_DATABASE=AmScope MD1900 camera
+usb:v0547p6010*
+ ID_MODEL_FROM_DATABASE=AmScope MU1000 camera
+
usb:v0547p6510*
ID_MODEL_FROM_DATABASE=Touptek UCMOS05100KPA
usb:v054Cp0154*
ID_MODEL_FROM_DATABASE=Eyetoy Audio Device
+usb:v054Cp0155*
+ ID_MODEL_FROM_DATABASE=Eyetoy Video Device
+
usb:v054Cp015F*
ID_MODEL_FROM_DATABASE=IC Recorder (BM)
usb:v054Cp03BC*
ID_MODEL_FROM_DATABASE=Webbie HD - MHS-CM1
+usb:v054Cp03CC*
+ ID_MODEL_FROM_DATABASE=SD Card Reader
+
usb:v054Cp03D1*
ID_MODEL_FROM_DATABASE=DPF-X95
ID_MODEL_FROM_DATABASE=DSC-HX100V [Cybershot Digital Still Camera]
usb:v054Cp05C4*
- ID_MODEL_FROM_DATABASE=DualShock 4
+ ID_MODEL_FROM_DATABASE=DualShock 4 [CUH-ZCT1E]
usb:v054Cp0689*
ID_MODEL_FROM_DATABASE=Walkman NWZ-B173F
usb:v054Cp0994*
ID_MODEL_FROM_DATABASE=ILCE-6000 (aka Alpha-6000) in charging mode
+usb:v054Cp09CC*
+ ID_MODEL_FROM_DATABASE=DualShock 4 [CUH-ZCT2E]
+
usb:v054Cp0BB5*
ID_MODEL_FROM_DATABASE=Headset MDR-1000X
usb:v056Ap034E*
ID_MODEL_FROM_DATABASE=DTH-W1620 [MobileStudio Pro 16] tablet
+usb:v056Ap034F*
+ ID_MODEL_FROM_DATABASE=DTH-1320 [Cintiq Pro 13] tablet
+
+usb:v056Ap0350*
+ ID_MODEL_FROM_DATABASE=DTH-1620 [Cintiq Pro 16] tablet
+
+usb:v056Ap0353*
+ ID_MODEL_FROM_DATABASE=DTH-1320 [Cintiq Pro 13] touchscreen
+
+usb:v056Ap0354*
+ ID_MODEL_FROM_DATABASE=DTH-1620 [Cintiq Pro 16] touchscreen
+
+usb:v056Ap0357*
+ ID_MODEL_FROM_DATABASE=PTH-660 [Intuos Pro (M)]
+
+usb:v056Ap0358*
+ ID_MODEL_FROM_DATABASE=PTH-860 [Intuos Pro (L)]
+
usb:v056Ap0400*
ID_MODEL_FROM_DATABASE=PenPartner 4x5
ID_MODEL_FROM_DATABASE=Teledat X130 DSL
usb:v057Cp2800*
- ID_MODEL_FROM_DATABASE=ISDN-Connector TA
+ ID_MODEL_FROM_DATABASE=Teledat 2a/b / X120 / NetXXL ISDN Terminal Adapter
usb:v057Cp3200*
ID_MODEL_FROM_DATABASE=Teledat X130 DSL
ID_MODEL_FROM_DATABASE=FRITZ!Box WLAN
usb:v057Cp3D00*
- ID_MODEL_FROM_DATABASE=Fritz!Box
+ ID_MODEL_FROM_DATABASE=FRITZ!Box Fon WLAN 7050/7140/7170/IAD3331
usb:v057Cp3E01*
ID_MODEL_FROM_DATABASE=FRITZ!Box (Annex A)
usb:v057Ep0306*
ID_MODEL_FROM_DATABASE=Wii Remote Controller RVL-003
+usb:v057Ep2006*
+ ID_MODEL_FROM_DATABASE=Joy-Con L
+
+usb:v057Ep2007*
+ ID_MODEL_FROM_DATABASE=Joy-Con R
+
usb:v057F*
ID_VENDOR_FROM_DATABASE=QuickShot, Ltd
usb:v059Fp0829*
ID_MODEL_FROM_DATABASE=BigDisk Extreme+
+usb:v059Fp1004*
+ ID_MODEL_FROM_DATABASE=Little Disk 20 GB
+
usb:v059Fp100C*
ID_MODEL_FROM_DATABASE=Rugged Triple Interface Mobile Hard Drive
usb:v059Fp1052*
ID_MODEL_FROM_DATABASE=P'9220 Mobile Drive
+usb:v059Fp1061*
+ ID_MODEL_FROM_DATABASE=Rugged USB3-FW
+
usb:v059Fp1064*
ID_MODEL_FROM_DATABASE=Rugged 16 and 32 GB
usb:v05DCpA815*
ID_MODEL_FROM_DATABASE=JumpDrive V10
+usb:v05DCpA81D*
+ ID_MODEL_FROM_DATABASE=LJDTT16G [JumpDrive 16GB]
+
usb:v05DCpA833*
ID_MODEL_FROM_DATABASE=JumpDrive S23 64GB
usb:v05FCp0001*
ID_MODEL_FROM_DATABASE=Soundcraft Si Multi Digital Card
+usb:v05FCp0010*
+ ID_MODEL_FROM_DATABASE=Soundcraft Si MADI combo card
+
usb:v05FCp7849*
ID_MODEL_FROM_DATABASE=Harman/Kardon SoundSticks
ID_VENDOR_FROM_DATABASE=Zida Technologies, Ltd
usb:v062A*
- ID_VENDOR_FROM_DATABASE=Creative Labs
+ ID_VENDOR_FROM_DATABASE=MosArt Semiconductor Corp.
usb:v062Ap0000*
ID_MODEL_FROM_DATABASE=Optical mouse
ID_VENDOR_FROM_DATABASE=WIBU-Systems AG
usb:v064Fp03E9*
- ID_MODEL_FROM_DATABASE=CmStick (article no. 1001)
+ ID_MODEL_FROM_DATABASE=CmStick (MSD, article no. 1001-xx-xxx)
usb:v064Fp03F2*
- ID_MODEL_FROM_DATABASE=CmStick/M (article no. 1010)
+ ID_MODEL_FROM_DATABASE=CmStick/M (MSD, article no. 1010-xx-xxx)
usb:v064Fp03F3*
- ID_MODEL_FROM_DATABASE=CmStick/M (article no. 1011)
+ ID_MODEL_FROM_DATABASE=CmStick/M (MSD, article no. 1011-xx-xxx)
usb:v064Fp0BD7*
- ID_MODEL_FROM_DATABASE=BOX/U
+ ID_MODEL_FROM_DATABASE=Wibu-Box/U (article no. 3031-xx-xxx)
usb:v064Fp0BD8*
- ID_MODEL_FROM_DATABASE=BOX/RU
+ ID_MODEL_FROM_DATABASE=Wibu-Box/RU (article no. 3032-xx-xxx)
+
+usb:v064Fp2AF9*
+ ID_MODEL_FROM_DATABASE=CmStick (HID, article no. 1001-xx-xxx)
+
+usb:v064Fp2B03*
+ ID_MODEL_FROM_DATABASE=CmStick/M (HID, article no. 1011-xx-xxx)
+
+usb:v064Fp5213*
+ ID_MODEL_FROM_DATABASE=CmStick/M (COMPOSITE, article no. 1011-xx-xxx)
usb:v0650*
ID_VENDOR_FROM_DATABASE=Dynapro Systems
usb:v06D3p0394*
ID_MODEL_FROM_DATABASE=CP9000D/DW Port
+usb:v06D3p0398*
+ ID_MODEL_FROM_DATABASE=P93D
+
usb:v06D3p03A1*
ID_MODEL_FROM_DATABASE=CP9550D/DW Port
ID_MODEL_FROM_DATABASE=CP3020DA
usb:v06D3p03AD*
- ID_MODEL_FROM_DATABASE=CP-9800DW-S
+ ID_MODEL_FROM_DATABASE=CP-9800D/DW
usb:v06D3p03AE*
ID_MODEL_FROM_DATABASE=CP-9800DW-S
usb:v06D3p3B10*
ID_MODEL_FROM_DATABASE=P95D
+usb:v06D3p3B21*
+ ID_MODEL_FROM_DATABASE=CP-9810D/DW
+
usb:v06D3p3B30*
ID_MODEL_FROM_DATABASE=CP-D70DW / CP-D707DW
usb:v06D3p3B31*
ID_MODEL_FROM_DATABASE=CP-K60DW-S
+usb:v06D3p3B36*
+ ID_MODEL_FROM_DATABASE=CP-D80DW
+
+usb:v06D3p3B50*
+ ID_MODEL_FROM_DATABASE=CP-W5000DW
+
+usb:v06D3p3B60*
+ ID_MODEL_FROM_DATABASE=CP-D90DW
+
usb:v06D4*
ID_VENDOR_FROM_DATABASE=Cisco Systems
usb:v071E*
ID_VENDOR_FROM_DATABASE=Ariston Technologies
+usb:v0720*
+ ID_VENDOR_FROM_DATABASE=Keyence Corp.
+
+usb:v0720p8001*
+ ID_MODEL_FROM_DATABASE=LJ-V7001
+
usb:v0723*
ID_VENDOR_FROM_DATABASE=Centillium Communications Corp.
usb:v0757*
ID_VENDOR_FROM_DATABASE=Network Technologies, Inc.
+usb:v0758*
+ ID_VENDOR_FROM_DATABASE=Carl Zeiss Microscopy GmbH
+
usb:v075B*
ID_VENDOR_FROM_DATABASE=Sophisticated Circuits, Inc.
ID_MODEL_FROM_DATABASE=Kick-off! Watchdog
usb:v0763*
- ID_VENDOR_FROM_DATABASE=Midiman
+ ID_VENDOR_FROM_DATABASE=M-Audio
usb:v0763p0115*
ID_MODEL_FROM_DATABASE=O2 / KeyRig 25
ID_MODEL_FROM_DATABASE=GW-US54ZGL 802.11bg
usb:v07B8p6001*
- ID_MODEL_FROM_DATABASE=802.11bg
+ ID_MODEL_FROM_DATABASE=WUG2690 802.11bg Wireless Module [ZyDAS ZD1211+AL2230]
usb:v07B8p8188*
ID_MODEL_FROM_DATABASE=AboCom Systems Inc [WN2001 Prolink Wireless-N Nano Adapter]
usb:v0810p0003*
ID_MODEL_FROM_DATABASE=PlayStation Gamepad
+usb:v0810pE001*
+ ID_MODEL_FROM_DATABASE=Twin controller
+
usb:v0810pE501*
ID_MODEL_FROM_DATABASE=SNES Gamepad
usb:v0846p9050*
ID_MODEL_FROM_DATABASE=A6200 802.11a/b/g/n/ac Wireless Adapter [Broadcom BCM43526]
+usb:v0846p9051*
+ ID_MODEL_FROM_DATABASE=A6200v2 802.11a/b/g/n/ac (2x2) Wireless Adapter [Realtek RTL8812AU]
+
usb:v0846p9052*
ID_MODEL_FROM_DATABASE=A6100 AC600 DB Wireless Adapter [Realtek RTL8811AU]
usb:v0897*
ID_VENDOR_FROM_DATABASE=Lauterbach
+usb:v0897p0001*
+ ID_MODEL_FROM_DATABASE=ICE In-Circuit Emulator
+
usb:v0897p0002*
ID_MODEL_FROM_DATABASE=Power Debug/Power Debug II
+usb:v0897p0004*
+ ID_MODEL_FROM_DATABASE=PowerDebug
+
+usb:v0897p0005*
+ ID_MODEL_FROM_DATABASE=PowerDebug PRO
+
usb:v089C*
ID_VENDOR_FROM_DATABASE=United Technologies Research Cntr.
usb:v0908p04B2*
ID_MODEL_FROM_DATABASE=NC interface
+usb:v0908p04B3*
+ ID_MODEL_FROM_DATABASE=keyboard front panel Cockpit
+
+usb:v0908p04B4*
+ ID_MODEL_FROM_DATABASE=SCR_CCID
+
usb:v0908p2701*
ID_MODEL_FROM_DATABASE=ShenZhen SANZHAI Technology Co.,Ltd Spy Pen VGA
usb:v0930p0A08*
ID_MODEL_FROM_DATABASE=WLM-20U2/GN-1080 802.11abgn Wireless Adapter [Atheros AR7010+AR9280]
+usb:v0930p0A0B*
+ ID_MODEL_FROM_DATABASE=WLU5053 802.11abgn Wireless Module [Broadcom BCM43236B]
+
usb:v0930p0A13*
ID_MODEL_FROM_DATABASE=AX88179 Gigabit Ethernet [Toshiba]
usb:v0951p162A*
ID_MODEL_FROM_DATABASE=DataTraveler 112 4GB Pen Drive
+usb:v0951p162B*
+ ID_MODEL_FROM_DATABASE=DataTraveler HyperX 3.0
+
usb:v0951p162D*
ID_MODEL_FROM_DATABASE=DataTraveler 102
ID_VENDOR_FROM_DATABASE=RPM Systems Corp.
usb:v0955*
- ID_VENDOR_FROM_DATABASE=NVidia Corp.
+ ID_VENDOR_FROM_DATABASE=NVIDIA Corp.
usb:v0955p7018*
- ID_MODEL_FROM_DATABASE=APX
+ ID_MODEL_FROM_DATABASE=T186 [Tegra Parker]
+
+usb:v0955p701A*
+ ID_MODEL_FROM_DATABASE=U-Boot running on Tegra
+
+usb:v0955p7020*
+ ID_MODEL_FROM_DATABASE=L4T (Linux for Tegra) running on Tegra
usb:v0955p7030*
- ID_MODEL_FROM_DATABASE=Tegra 3 (recovery mode)
+ ID_MODEL_FROM_DATABASE=T30 [Tegra 3] recovery mode
usb:v0955p7100*
ID_MODEL_FROM_DATABASE=Tegra Device
+usb:v0955p7140*
+ ID_MODEL_FROM_DATABASE=T124 [Tegra K1/Logan 32-bit]
+
usb:v0955p7210*
ID_MODEL_FROM_DATABASE=SHIELD Controller
+usb:v0955p7721*
+ ID_MODEL_FROM_DATABASE=T210 [Tegra Erista]
+
usb:v0955p7820*
- ID_MODEL_FROM_DATABASE=Tegra 2 AC100 developer mode
+ ID_MODEL_FROM_DATABASE=T20 [Tegra 2] recovery mode
usb:v0955pB400*
ID_MODEL_FROM_DATABASE=SHIELD (debug)
usb:v095Dp0001*
ID_MODEL_FROM_DATABASE=Polycom ViaVideo
+usb:v0964*
+ ID_VENDOR_FROM_DATABASE=BITRAN
+
usb:v0967*
ID_VENDOR_FROM_DATABASE=Acer NeWeb Corp.
ID_MODEL_FROM_DATABASE=BCM20703A1 Bluetooth 4.1 + LE
usb:v0A5CpBD11*
- ID_MODEL_FROM_DATABASE=TiVo AG0100 802.11bg Wireless Adapter [Broadcom BCM4320]
+ ID_MODEL_FROM_DATABASE=BCM4320 802.11bg Wireless Adapter
+
+usb:v0A5CpBD12*
+ ID_MODEL_FROM_DATABASE=BCM4326U 802.11bg Wireless Adapter
usb:v0A5CpBD13*
ID_MODEL_FROM_DATABASE=BCM4323 802.11abgn Wireless Adapter
usb:v0A5CpBD17*
ID_MODEL_FROM_DATABASE=BCM43236 802.11abgn Wireless Adapter
+usb:v0A5CpBD1D*
+ ID_MODEL_FROM_DATABASE=BCM43526 802.11a/b/g/n/ac (2x2) Wireless Adapter
+
+usb:v0A5CpBD1E*
+ ID_MODEL_FROM_DATABASE=BCM43143 802.11bgn (1x1) Wireless Adapter
+
+usb:v0A5CpBD1F*
+ ID_MODEL_FROM_DATABASE=BCM43242 802.11abgn Wireless Adapter
+
usb:v0A5CpD11B*
ID_MODEL_FROM_DATABASE=Eminent EM4045 [Broadcom 4320 USB]
usb:v0B05p0001*
ID_MODEL_FROM_DATABASE=MeMO Pad HD 7 (CD-ROM mode)
+usb:v0B05p0301*
+ ID_MODEL_FROM_DATABASE=MyPal A696 GPS PDA
+
usb:v0B05p1101*
ID_MODEL_FROM_DATABASE=Mass Storage (UISDMC4S)
ID_MODEL_FROM_DATABASE=Multi card reader
usb:v0B05p170C*
- ID_MODEL_FROM_DATABASE=WL-159g 802.11bg
+ ID_MODEL_FROM_DATABASE=WL-159g 802.11bg [ZyDAS ZD1211B+AL2230]
usb:v0B05p170D*
ID_MODEL_FROM_DATABASE=802.11b/g Wireless Network Adapter
ID_MODEL_FROM_DATABASE=Laptop OLED Display
usb:v0B05p172A*
- ID_MODEL_FROM_DATABASE=ASUS 802.11n Network Adapter
+ ID_MODEL_FROM_DATABASE=802.11n Network Adapter
usb:v0B05p172B*
ID_MODEL_FROM_DATABASE=802.11n Network Adapter
ID_MODEL_FROM_DATABASE=802.11n Network Adapter
usb:v0B05p1734*
- ID_MODEL_FROM_DATABASE=ASUS AF-200
+ ID_MODEL_FROM_DATABASE=AF-200
usb:v0B05p173C*
ID_MODEL_FROM_DATABASE=BT-183 Bluetooth 2.0
ID_MODEL_FROM_DATABASE=Broadcom BCM20702A0 Bluetooth
usb:v0B05p17D1*
- ID_MODEL_FROM_DATABASE=AC51 802.11a/b/g/n/ac Wireless Adapter [Mediatek MT7610/Ralink RT2870]
+ ID_MODEL_FROM_DATABASE=AC51 802.11a/b/g/n/ac Wireless Adapter [Mediatek MT7610U]
+
+usb:v0B05p17D2*
+ ID_MODEL_FROM_DATABASE=USB-AC56 802.11a/b/g/n/ac Wireless Adapter [Realtek RTL8812AU]
+
+usb:v0B05p17D3*
+ ID_MODEL_FROM_DATABASE=USB-N10 v2 802.11b/g/n Wireless Adapter [MediaTek MT7601U]
+
+usb:v0B05p17DB*
+ ID_MODEL_FROM_DATABASE=USB-AC50 802.11a/b/g/n/ac (1x1) Wireless Adapter [MediaTek MT7610U]
+
+usb:v0B05p17E8*
+ ID_MODEL_FROM_DATABASE=USB-N14 802.11b/g/n (2x2) Wireless Adapter [Ralink RT5372]
+
+usb:v0B05p17EB*
+ ID_MODEL_FROM_DATABASE=USB-AC55 802.11a/b/g/n/ac Wireless Adapter [MediaTek MT7612U]
usb:v0B05p180A*
ID_MODEL_FROM_DATABASE=Broadcom BCM20702 Single-Chip Bluetooth 4.0 + LE
+usb:v0B05p1817*
+ ID_MODEL_FROM_DATABASE=USB-AC68 802.11a/b/g/n/ac (4x4) Wireless Adapter [Realtek RTL8814AU]
+
usb:v0B05p1825*
ID_MODEL_FROM_DATABASE=Qualcomm Bluetooth 4.1
ID_MODEL_FROM_DATABASE=Remote NDIS Device
usb:v0B05p7772*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (MTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (MTP mode)
usb:v0B05p7773*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, MTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (Debug, MTP mode)
usb:v0B05p7774*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (RNDIS mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (RNDIS mode)
usb:v0B05p7775*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, RNDIS mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (Debug, RNDIS mode)
usb:v0B05p7776*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (PTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (PTP mode)
usb:v0B05p7777*
- ID_MODEL_FROM_DATABASE=ASUS Zenfone GO (ZB500KL) (Debug, PTP mode)
+ ID_MODEL_FROM_DATABASE=Zenfone GO (ZB500KL) (Debug, PTP mode)
usb:v0B05pB700*
ID_MODEL_FROM_DATABASE=Broadcom Bluetooth 2.1
usb:v0B33p0030*
ID_MODEL_FROM_DATABASE=ShuttlePro v2
+usb:v0B33p0401*
+ ID_MODEL_FROM_DATABASE=RollerMouse Free 2
+
usb:v0B33p0700*
ID_MODEL_FROM_DATABASE=RollerMouse Pro
usb:v0BC2p3320*
ID_MODEL_FROM_DATABASE=SRD00F2 [Expansion Desktop Drive]
+usb:v0BC2p3322*
+ ID_MODEL_FROM_DATABASE=SRD0NF2 [Expansion Desktop Drive]
+
usb:v0BC2p3332*
ID_MODEL_FROM_DATABASE=Expansion
usb:v0BC2p5161*
ID_MODEL_FROM_DATABASE=FreeAgent GoFlex dock
+usb:v0BC2p6126*
+ ID_MODEL_FROM_DATABASE=Maxtor D3 Station 5TB
+
+usb:v0BC2p61B6*
+ ID_MODEL_FROM_DATABASE=Maxtor HX-M101TCB/GM [M3 Portable 1TB]
+
usb:v0BC2p61B7*
ID_MODEL_FROM_DATABASE=Maxtor M3 Portable
usb:v0BC2pAB00*
ID_MODEL_FROM_DATABASE=Slim Portable Drive
+usb:v0BC2pAB1E*
+ ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
+
usb:v0BC2pAB20*
ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
usb:v0BC2pAB24*
ID_MODEL_FROM_DATABASE=Backup Plus Portable Drive
+usb:v0BC2pAB26*
+ ID_MODEL_FROM_DATABASE=Backup Plus Slim Portable Drive 1 TB
+
usb:v0BC2pAB31*
ID_MODEL_FROM_DATABASE=Backup Plus Desktop Drive (5TB)
usb:v0BDAp0307*
ID_MODEL_FROM_DATABASE=Card Reader
+usb:v0BDAp0326*
+ ID_MODEL_FROM_DATABASE=Card reader
+
usb:v0BDAp1724*
ID_MODEL_FROM_DATABASE=RTL8723AU 802.11n WLAN Adapter
usb:v0BDAp57DA*
ID_MODEL_FROM_DATABASE=Built-In Video Camera
+usb:v0BDAp58C8*
+ ID_MODEL_FROM_DATABASE=Integrated Webcam HD
+
usb:v0BDAp8150*
ID_MODEL_FROM_DATABASE=RTL8150 Fast Ethernet Adapter
ID_MODEL_FROM_DATABASE=RTL8187B Wireless 802.11g 54Mbps Network Adapter
usb:v0BDAp818B*
- ID_MODEL_FROM_DATABASE=ACT-WNP-UA-005 802.11b/g/n WLAN Adapter
+ ID_MODEL_FROM_DATABASE=RTL8192EU 802.11b/g/n WLAN Adapter
usb:v0BDAp8192*
ID_MODEL_FROM_DATABASE=RTL8191SU 802.11n Wireless Adapter
ID_MODEL_FROM_DATABASE=RTL8187SU 802.11g WLAN Adapter
usb:v0BDAp8812*
- ID_MODEL_FROM_DATABASE=RTL8812AU 802.11a/b/g/n/ac WLAN Adapter
+ ID_MODEL_FROM_DATABASE=RTL8812AU 802.11a/b/g/n/ac 2T2R DB WLAN Adapter
+
+usb:v0BDAp8813*
+ ID_MODEL_FROM_DATABASE=RTL8814AU 802.11a/b/g/n/ac Wireless Adapter
+
+usb:v0BDApA811*
+ ID_MODEL_FROM_DATABASE=RTL8811AU 802.11a/b/g/n/ac WLAN Adapter
usb:v0BDB*
ID_VENDOR_FROM_DATABASE=Ericsson Business Mobile Networks BV
usb:v0C2Ep0B81*
ID_MODEL_FROM_DATABASE=Barcode scanner Voyager 1400g Series
+usb:v0C30*
+ ID_VENDOR_FROM_DATABASE=Mutoh Industries Ltd
+
+usb:v0C30p6010*
+ ID_MODEL_FROM_DATABASE=Kona 1400 Cutting Plotter
+
usb:v0C35*
ID_VENDOR_FROM_DATABASE=Eagletron, Inc.
usb:v0C45p641D*
ID_MODEL_FROM_DATABASE=1.3 MPixel Integrated Webcam
+usb:v0C45p6433*
+ ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam HD (Composite Device)
+
usb:v0C45p643F*
ID_MODEL_FROM_DATABASE=Dell Integrated HD Webcam
usb:v0CADp1007*
ID_MODEL_FROM_DATABASE=APX Series Consolette
+usb:v0CADp1020*
+ ID_MODEL_FROM_DATABASE=MOTOTRBO Series Radio (Portable)
+
usb:v0CADp1030*
ID_MODEL_FROM_DATABASE=APX Series Radio (Portable)
ID_VENDOR_FROM_DATABASE=NXP
usb:v0D28p0204*
- ID_MODEL_FROM_DATABASE=LPC1768
+ ID_MODEL_FROM_DATABASE=ARM mbed
usb:v0D32*
ID_VENDOR_FROM_DATABASE=Leo Hui Electric Wire & Cable Co., Ltd
usb:v0D46p3003*
ID_MODEL_FROM_DATABASE=mIDentity Light / KAAN SIM III
+usb:v0D46p3014*
+ ID_MODEL_FROM_DATABASE=Smart Token
+
usb:v0D46p4000*
ID_MODEL_FROM_DATABASE=mIDentity (mass storage)
usb:v0D64p3108*
ID_MODEL_FROM_DATABASE=Digicam Mass Storage Device
+usb:v0D64p5566*
+ ID_MODEL_FROM_DATABASE=Contour Roam Model 1600
+
usb:v0D65*
ID_VENDOR_FROM_DATABASE=KMJP Co., Ltd
usb:v0D8Cp0003*
ID_MODEL_FROM_DATABASE=Sound Device
+usb:v0D8Cp0005*
+ ID_MODEL_FROM_DATABASE=Blue Snowball
+
usb:v0D8Cp0006*
ID_MODEL_FROM_DATABASE=Storm HP-USB500 5.1 Headset
usb:v0DB0p3801*
ID_MODEL_FROM_DATABASE=Motorola Bluetooth 2.1+EDR Device
+usb:v0DB0p3870*
+ ID_MODEL_FROM_DATABASE=MS-3870 802.11bgn Wireless Module [Ralink RT3070]
+
+usb:v0DB0p3871*
+ ID_MODEL_FROM_DATABASE=MS-3871 802.11bgn Wireless Module [Ralink RT8070]
+
usb:v0DB0p4011*
ID_MODEL_FROM_DATABASE=Medion Flash XL V2.0 Card Reader
usb:v0E50*
ID_VENDOR_FROM_DATABASE=TechnoData Interware
+usb:v0E50p0001*
+ ID_MODEL_FROM_DATABASE=Matrix USB-Key
+
usb:v0E50p0002*
ID_MODEL_FROM_DATABASE=Matrixlock Dongle (HID)
usb:v0E6Ap6001*
ID_MODEL_FROM_DATABASE=GEMBIRD Flexible keyboard KB-109F-B-DE
+usb:v0E6Ap7F5C*
+ ID_MODEL_FROM_DATABASE=BPF-015 Key Chain Photo Frame
+
usb:v0E6F*
ID_VENDOR_FROM_DATABASE=Logic3
usb:v0E8Fp0201*
ID_MODEL_FROM_DATABASE=SmartJoy Frag Xpad/PS2 adaptor
+usb:v0E8Fp300A*
+ ID_MODEL_FROM_DATABASE=steering Wheel
+
usb:v0E90*
ID_VENDOR_FROM_DATABASE=WiebeTech, LLC
usb:v1058p259F*
ID_MODEL_FROM_DATABASE=My Passport Ultra (WD10JMVW)
+usb:v1058p25A1*
+ ID_MODEL_FROM_DATABASE=Elements / My Passport (WD20NMVW)
+
+usb:v1058p25A2*
+ ID_MODEL_FROM_DATABASE=Elements 25A2
+
+usb:v1058p25A3*
+ ID_MODEL_FROM_DATABASE=Elements Desktop (WDBWLG)
+
+usb:v1058p25E2*
+ ID_MODEL_FROM_DATABASE=My Passport (WD40NMZW)
+
+usb:v1058p30A0*
+ ID_MODEL_FROM_DATABASE=SATA adapter cable
+
usb:v1059*
ID_VENDOR_FROM_DATABASE=Giesecke & Devrient GmbH
usb:v1065p2136*
ID_MODEL_FROM_DATABASE=EasyDisk ED1064
+usb:v1068*
+ ID_VENDOR_FROM_DATABASE=Micropi Elettronica
+
+usb:v1068p0001*
+ ID_MODEL_FROM_DATABASE=CPUSB - V 1.8 - software-rights management key
+
usb:v106A*
ID_VENDOR_FROM_DATABASE=Loyal Legend, Ltd
usb:v1083*
ID_VENDOR_FROM_DATABASE=Canon Electronics, Inc.
+usb:v1083p160C*
+ ID_MODEL_FROM_DATABASE=CR-55
+
+usb:v1083p160F*
+ ID_MODEL_FROM_DATABASE=DR-1210C
+
+usb:v1083p1614*
+ ID_MODEL_FROM_DATABASE=DR-4010C
+
+usb:v1083p1617*
+ ID_MODEL_FROM_DATABASE=DR-2510C
+
+usb:v1083p1618*
+ ID_MODEL_FROM_DATABASE=DR-X10C
+
+usb:v1083p161A*
+ ID_MODEL_FROM_DATABASE=CR-25
+
usb:v1083p161B*
ID_MODEL_FROM_DATABASE=DR-2010C Scanner
+usb:v1083p161D*
+ ID_MODEL_FROM_DATABASE=DR-3010C
+
+usb:v1083p1620*
+ ID_MODEL_FROM_DATABASE=DR-7090C
+
+usb:v1083p1622*
+ ID_MODEL_FROM_DATABASE=DR-9050C
+
+usb:v1083p1623*
+ ID_MODEL_FROM_DATABASE=DR-7550C
+
+usb:v1083p1624*
+ ID_MODEL_FROM_DATABASE=DR-6050C
+
+usb:v1083p1626*
+ ID_MODEL_FROM_DATABASE=DR-6010C
+
usb:v1083p162C*
ID_MODEL_FROM_DATABASE=P-150 Scanner
+usb:v1083p1638*
+ ID_MODEL_FROM_DATABASE=DR-6030C
+
+usb:v1083p1639*
+ ID_MODEL_FROM_DATABASE=CR-135i
+
+usb:v1083p163E*
+ ID_MODEL_FROM_DATABASE=DR-M160
+
+usb:v1083p163F*
+ ID_MODEL_FROM_DATABASE=DR-M140
+
+usb:v1083p1640*
+ ID_MODEL_FROM_DATABASE=DR-C125
+
+usb:v1083p1641*
+ ID_MODEL_FROM_DATABASE=DR-P215
+
+usb:v1083p1648*
+ ID_MODEL_FROM_DATABASE=FSU-201
+
+usb:v1083p164A*
+ ID_MODEL_FROM_DATABASE=DR-C130
+
+usb:v1083p164B*
+ ID_MODEL_FROM_DATABASE=DR-P208
+
+usb:v1083p164F*
+ ID_MODEL_FROM_DATABASE=DR-G1130
+
+usb:v1083p1650*
+ ID_MODEL_FROM_DATABASE=DR-G1100
+
+usb:v1083p1651*
+ ID_MODEL_FROM_DATABASE=DR-C120
+
+usb:v1083p1654*
+ ID_MODEL_FROM_DATABASE=DR-F120
+
+usb:v1083p1657*
+ ID_MODEL_FROM_DATABASE=DR-M1060
+
+usb:v1083p1658*
+ ID_MODEL_FROM_DATABASE=DR-C225
+
+usb:v1083p1659*
+ ID_MODEL_FROM_DATABASE=DR-P215II
+
+usb:v1083p165D*
+ ID_MODEL_FROM_DATABASE=DR-P208II
+
usb:v1084*
ID_VENDOR_FROM_DATABASE=Pantech Co., Ltd
usb:v108E*
ID_VENDOR_FROM_DATABASE=Lotes Co., Ltd.
+usb:v1091*
+ ID_VENDOR_FROM_DATABASE=Numerik Jena
+
+usb:v1091p8101*
+ ID_MODEL_FROM_DATABASE=Absoflex
+
usb:v1099*
ID_VENDOR_FROM_DATABASE=Surface Optics Corp.
ID_VENDOR_FROM_DATABASE=DiBcom
usb:v10B8p0BB8*
- ID_MODEL_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (cold)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD300) (cold)
usb:v10B8p0BB9*
- ID_MODEL_FROM_DATABASE=DiBcom USB DVB-T reference design (MOD300) (warm)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD300) (warm)
usb:v10B8p0BC6*
- ID_MODEL_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD3000P) (cold)
usb:v10B8p0BC7*
- ID_MODEL_FROM_DATABASE=DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm)
+ ID_MODEL_FROM_DATABASE=DVB-T reference design (MOD3000P) (warm)
usb:v10BB*
ID_VENDOR_FROM_DATABASE=TM Technology, Inc.
usb:v10C4p0003*
ID_MODEL_FROM_DATABASE=CommandIR
+usb:v10C4p800A*
+ ID_MODEL_FROM_DATABASE=SPORTident
+
+usb:v10C4p800B*
+ ID_MODEL_FROM_DATABASE=AES
+
usb:v10C4p8030*
ID_MODEL_FROM_DATABASE=K4JRG Ham Radio devices
usb:v10C4p80A9*
ID_MODEL_FROM_DATABASE=CP210x to UART Bridge Controller
+usb:v10C4p80C4*
+ ID_MODEL_FROM_DATABASE=Infrared Thermometer Adapter
+
usb:v10C4p80CA*
ID_MODEL_FROM_DATABASE=ATM2400 Sensor Device
usb:v10C4p81E8*
ID_MODEL_FROM_DATABASE=Zephyr BioHarness
+usb:v10C4p834B*
+ ID_MODEL_FROM_DATABASE=Infrared Online Sensor Adapter
+
+usb:v10C4p834E*
+ ID_MODEL_FROM_DATABASE=Infrared Sensor Adapter
+
usb:v10C4p8460*
ID_MODEL_FROM_DATABASE=Sangoma Wanpipe VoiceTime
usb:v10C4p8461*
ID_MODEL_FROM_DATABASE=Sangoma U100
+usb:v10C4p8470*
+ ID_MODEL_FROM_DATABASE=Juniper Networks BX Series System Console
+
usb:v10C4p8477*
ID_MODEL_FROM_DATABASE=Balluff RFID Reader
usb:v10C4p8497*
ID_MODEL_FROM_DATABASE=SiLabs Cypress EVB
+usb:v10C4p84FB*
+ ID_MODEL_FROM_DATABASE=Infrared Blackbody Adapter
+
+usb:v10C4p8508*
+ ID_MODEL_FROM_DATABASE=RS485 Adapter
+
usb:v10C4p8605*
ID_MODEL_FROM_DATABASE=dilitronics ESoLUX solar lighting controller
+usb:v10C4p8660*
+ ID_MODEL_FROM_DATABASE=Netronics CANdoISO
+
usb:v10C4p86BC*
ID_MODEL_FROM_DATABASE=C8051F34x AudioDelay [AD-340]
usb:v10C4p8897*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Splitter [UHBX]
+usb:v10C4p88C9*
+ ID_MODEL_FROM_DATABASE=AES HID device
+
usb:v10C4p8918*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Audio Extractor [VSA-HA-DP]
usb:v10C4p8973*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Extender [UHBX-8X]
+usb:v10C4p89C6*
+ ID_MODEL_FROM_DATABASE=SPORTident HID device
+
usb:v10C4p89E1*
ID_MODEL_FROM_DATABASE=C8051F38x HDMI Extender [UHBX-SW3-WP]
usb:v10C4pEA60*
- ID_MODEL_FROM_DATABASE=CP210x UART Bridge / myAVR mySmartUSB light
+ ID_MODEL_FROM_DATABASE=CP2102/CP2109 UART Bridge Controller [CP210x family]
usb:v10C4pEA61*
ID_MODEL_FROM_DATABASE=CP210x UART Bridge
usb:v10C4pEA80*
ID_MODEL_FROM_DATABASE=CP210x UART Bridge
+usb:v10C4pEAC9*
+ ID_MODEL_FROM_DATABASE=EFM8UB1 Bootloader
+
+usb:v10C4pEACA*
+ ID_MODEL_FROM_DATABASE=EFM8UB2 Bootloader
+
usb:v10C5*
ID_VENDOR_FROM_DATABASE=Sanei Electric, Inc.
usb:v10CE*
ID_VENDOR_FROM_DATABASE=Silicon Labs
+usb:v10CEp0007*
+ ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S1245
+
usb:v10CEp000E*
ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S2145
+usb:v10CEp0019*
+ ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S6145
+
+usb:v10CEp001D*
+ ID_MODEL_FROM_DATABASE=Shinko/Sinfonia CHC-S6245
+
+usb:v10CEp001E*
+ ID_MODEL_FROM_DATABASE=Ciaat Brava 21
+
usb:v10CEpEA6A*
ID_MODEL_FROM_DATABASE=MobiData EDGE USB Modem
usb:v10F1p1A2A*
ID_MODEL_FROM_DATABASE=Laptop Integrated Webcam
+usb:v10F1p1A2E*
+ ID_MODEL_FROM_DATABASE=HP Truevision HD Integrated Webcam
+
usb:v10F5*
ID_VENDOR_FROM_DATABASE=Turtle Beach
usb:v1130p660C*
ID_MODEL_FROM_DATABASE=Foot Pedal/Thermometer
+usb:v1130p6626*
+ ID_MODEL_FROM_DATABASE=Key
+
usb:v1130p6806*
ID_MODEL_FROM_DATABASE=Keychain photo frame
usb:v113D*
ID_VENDOR_FROM_DATABASE=Mapower Electronics Co., Ltd
+usb:v113F*
+ ID_VENDOR_FROM_DATABASE=Integrated Biometrics, LLC
+
+usb:v113Fp1020*
+ ID_MODEL_FROM_DATABASE=Watson Two-Finger Roll Scanner
+
+usb:v113Fp1100*
+ ID_MODEL_FROM_DATABASE=Columbo Single-Finger Scanner
+
usb:v1141*
ID_VENDOR_FROM_DATABASE=V One Multimedia, Pte., Ltd
usb:v1199p900A*
ID_MODEL_FROM_DATABASE=Gobi 2000 Wireless Modem
+usb:v1199p9013*
+ ID_MODEL_FROM_DATABASE=Sierra Wireless Gobi 3000 Modem device (MC8355)
+
usb:v1199p9055*
ID_MODEL_FROM_DATABASE=Gobi 9x15 Multimode 3G/4G LTE Modem (NAT mode)
usb:v11BEpF0A0*
ID_MODEL_FROM_DATABASE=Martin Maxxyz DMX
+usb:v11C0*
+ ID_VENDOR_FROM_DATABASE=Betop
+
+usb:v11C0p5506*
+ ID_MODEL_FROM_DATABASE=Gamepad
+
usb:v11C5*
ID_VENDOR_FROM_DATABASE=Inmax
usb:v1209p1006*
ID_MODEL_FROM_DATABASE=Mini IO-Board
+usb:v1209p1AB5*
+ ID_MODEL_FROM_DATABASE=Arachnid Labs Tsunami
+
usb:v1209p2000*
ID_MODEL_FROM_DATABASE=Zygmunt Krynicki Lantern Brightness Sensor
usb:v1209p2301*
ID_MODEL_FROM_DATABASE=Keyboardio Keyboardio Model 01
+usb:v1209p2327*
+ ID_MODEL_FROM_DATABASE=K.T.E.C.Bootloader Device
+
+usb:v1209p2328*
+ ID_MODEL_FROM_DATABASE=K.T.E.C. Keyboard Device
+
usb:v1209p2337*
ID_MODEL_FROM_DATABASE=/Dev or SlashDev /Net
usb:v1209p5222*
ID_MODEL_FROM_DATABASE=telavivmakers attami
+usb:v1209p53C0*
+ ID_MODEL_FROM_DATABASE=SatoshiLabs TREZOR Bootloader
+
+usb:v1209p53C1*
+ ID_MODEL_FROM_DATABASE=SatoshiLabs TREZOR
+
usb:v1209p5A22*
ID_MODEL_FROM_DATABASE=ikari_01 sd2snes
+usb:v1209p7530*
+ ID_MODEL_FROM_DATABASE=Refflion - IoT Board - Bootloader
+
+usb:v1209p7531*
+ ID_MODEL_FROM_DATABASE=Refflion - IoT Board - Sketch
+
usb:v1209p7BD0*
ID_MODEL_FROM_DATABASE=pokey9000 Tiny Bit Dingus
usb:v1209pABD0*
ID_MODEL_FROM_DATABASE=tibounise ADB converter
+usb:v1209pACED*
+ ID_MODEL_FROM_DATABASE=Open Lighting Project - Ja Rule Device
+
+usb:v1209pACEE*
+ ID_MODEL_FROM_DATABASE=Open Lighting Project - Ja Rule Bootloader
+
usb:v1209pBEEF*
ID_MODEL_FROM_DATABASE=Modal MC-USB
usb:v121Ep3403*
ID_MODEL_FROM_DATABASE=Muzio JM250 Audio Player
+usb:v1220*
+ ID_VENDOR_FROM_DATABASE=TC Electronic
+
+usb:v1220p000A*
+ ID_MODEL_FROM_DATABASE=Hall of Fame Reverb
+
+usb:v1220p002A*
+ ID_MODEL_FROM_DATABASE=Polytune
+
+usb:v1220p0032*
+ ID_MODEL_FROM_DATABASE=Ditto X2 Looper
+
+usb:v1220p0039*
+ ID_MODEL_FROM_DATABASE=Alter Ego X4 Vintage Echo
+
usb:v1221*
ID_VENDOR_FROM_DATABASE=Unknown manufacturer
usb:v1235p8014*
ID_MODEL_FROM_DATABASE=Scarlett 18i8
+usb:v1235p8016*
+ ID_MODEL_FROM_DATABASE=Focusrite Scarlett 2i2
+
+usb:v1235p8203*
+ ID_MODEL_FROM_DATABASE=Focusrite Scarlett 6i6
+
+usb:v1235p8204*
+ ID_MODEL_FROM_DATABASE=Scarlett 18i8 2nd Gen
+
usb:v1241*
ID_VENDOR_FROM_DATABASE=Belkin
usb:v125FpCB10*
ID_MODEL_FROM_DATABASE=Dash Drive UV100
+usb:v125FpCB20*
+ ID_MODEL_FROM_DATABASE=DashDrive UV110
+
usb:v1260*
ID_VENDOR_FROM_DATABASE=Standard Microsystems Corp.
ID_MODEL_FROM_DATABASE=G-720 Keyboard
usb:v1267p0201*
- ID_MODEL_FROM_DATABASE=A4Tech SWOP-3 Mouse
+ ID_MODEL_FROM_DATABASE=Mouse
usb:v1267p0210*
ID_MODEL_FROM_DATABASE=LG Optical Mouse 3D-310
usb:v1286p2006*
ID_MODEL_FROM_DATABASE=88W8362 802.11n WLAN
+usb:v1286p203C*
+ ID_MODEL_FROM_DATABASE=K30326 802.11bgn Wireless Module [Marvell 88W8786U]
+
usb:v1286p8001*
ID_MODEL_FROM_DATABASE=BLOB boot loader firmware
usb:v1292p0258*
ID_MODEL_FROM_DATABASE=Creative Labs VoIP Blaster
+usb:v1292p4154*
+ ID_MODEL_FROM_DATABASE=Retro Link Atari cable
+
usb:v1293*
ID_VENDOR_FROM_DATABASE=Belkin Components [hex]
usb:v1294p1320*
ID_MODEL_FROM_DATABASE=Webmail Notifier
+usb:v1297*
+ ID_VENDOR_FROM_DATABASE=DekTec
+
+usb:v1297p020F*
+ ID_MODEL_FROM_DATABASE=DTU-215 Multi-Standard Modulator
+
usb:v129B*
ID_VENDOR_FROM_DATABASE=CyberTAN Technology
usb:v12BA*
ID_VENDOR_FROM_DATABASE=Licensed by Sony Computer Entertainment America
+usb:v12BAp0032*
+ ID_MODEL_FROM_DATABASE=Wireless Stereo Headset
+
+usb:v12BAp0042*
+ ID_MODEL_FROM_DATABASE=Wireless Stereo Headset
+
usb:v12BAp00FF*
ID_MODEL_FROM_DATABASE=Rocksmith Guitar Adapter
usb:v12BDpD012*
ID_MODEL_FROM_DATABASE=JPD Shockforce gamepad
+usb:v12BDpD015*
+ ID_MODEL_FROM_DATABASE=Generic 4-button NES USB Controller
+
usb:v12C4*
ID_VENDOR_FROM_DATABASE=Autocue Group Ltd
usb:v12CFp0170*
ID_MODEL_FROM_DATABASE=Tt eSPORTS BLACK Gaming mouse
+usb:v12CFp600B*
+ ID_MODEL_FROM_DATABASE=Cougar 600M Gaming Mouse
+
usb:v12D1*
ID_VENDOR_FROM_DATABASE=Huawei Technologies Co., Ltd.
usb:v12D1p1001*
- ID_MODEL_FROM_DATABASE=E169/E620/E800 HSDPA Modem
+ ID_MODEL_FROM_DATABASE=E161/E169/E620/E800 HSDPA Modem
usb:v12D1p1003*
ID_MODEL_FROM_DATABASE=E220 HSDPA Modem / E230/E270/E870 HSDPA/HSUPA Modem
usb:v12D1p1039*
ID_MODEL_FROM_DATABASE=Ideos (tethering mode)
+usb:v12D1p1052*
+ ID_MODEL_FROM_DATABASE=MT7-L09
+
usb:v12D1p1404*
ID_MODEL_FROM_DATABASE=EM770W miniPCI WCDMA Modem
ID_MODEL_FROM_DATABASE=Broadband stick
usb:v12D1p1446*
- ID_MODEL_FROM_DATABASE=Broadband stick (modem on)
+ ID_MODEL_FROM_DATABASE=HSPA modem
usb:v12D1p1465*
ID_MODEL_FROM_DATABASE=K3765 HSPA
+usb:v12D1p14AC*
+ ID_MODEL_FROM_DATABASE=E815
+
usb:v12D1p14C3*
ID_MODEL_FROM_DATABASE=K5005 Vodafone LTE/UMTS/GSM Modem/Networkcard
usb:v12EFp0100*
ID_MODEL_FROM_DATABASE=Tapwave Handheld [Tapwave Zodiac]
+usb:v12F2*
+ ID_VENDOR_FROM_DATABASE=ViewPlus Technologies, Inc.
+
+usb:v12F2p000A*
+ ID_MODEL_FROM_DATABASE=Braille embosser [SpotDot Emprint]
+
usb:v12F5*
ID_VENDOR_FROM_DATABASE=Dynamic System Electronics Corp.
ID_MODEL_FROM_DATABASE=Ut190 8 GB Flash Drive with MicroSD reader
usb:v1307p0310*
- ID_MODEL_FROM_DATABASE=SD/MicroSD CardReader [hama]
+ ID_MODEL_FROM_DATABASE=SD/MicroSD CardReader [hama]/IT1327E [Basic Line flash drive]
usb:v1307p0330*
ID_MODEL_FROM_DATABASE=63-in-1 Multi-Card Reader/Writer
usb:v1313p8070*
ID_MODEL_FROM_DATABASE=PM100D
+usb:v1313p8072*
+ ID_MODEL_FROM_DATABASE=PM100USB Power and Energy Meter Interface
+
+usb:v1313p8078*
+ ID_MODEL_FROM_DATABASE=PM100D Compact Power and Energy Meter Console
+
+usb:v1313p8080*
+ ID_MODEL_FROM_DATABASE=CCS100 - Compact Spectrometer
+
usb:v131D*
ID_VENDOR_FROM_DATABASE=Natural Point
usb:v131Dp0156*
ID_MODEL_FROM_DATABASE=TrackIR 4 Pro Head Tracker
+usb:v131Dp0158*
+ ID_MODEL_FROM_DATABASE=TrackIR 5 Pro Head Tracker
+
+usb:v1325*
+ ID_VENDOR_FROM_DATABASE=ams AG
+
usb:v132A*
ID_VENDOR_FROM_DATABASE=Envara Inc.
EVDEV_ABS_35=::31
EVDEV_ABS_36=::30
+# Asus UX301L
+evdev:name:Elan Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnUX301LAA:*
+ EVDEV_ABS_00=::30
+ EVDEV_ABS_01=::29
+ EVDEV_ABS_35=::30
+ EVDEV_ABS_36=::29
+
# Asus UX305
evdev:name:Elan Touchpad:dmi:*:svnASUSTeKCOMPUTERINC.:pnUX305UA:*
EVDEV_ABS_00=0:3097:32
EVDEV_ABS_35=79:1841:22
EVDEV_ABS_36=140:1325:29
+# Dell Latitude E7470
+evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE7470*
+ EVDEV_ABS_00=39:5856:59
+ EVDEV_ABS_01=10:1532:29
+ EVDEV_ABS_35=39:5856:59
+ EVDEV_ABS_36=10:1532:29
+
# Dell Precision 5510
evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnPrecision5510*
EVDEV_ABS_00=::42
EVDEV_ABS_00=85:947:15
EVDEV_ABS_01=154:726:18
+#####
+# Sun
+#####
+
+# Fujitsu Component - USB Touch Panel
+evdev:input:b0003v0430p0530*
+ EVDEV_ABS_00=0:4096:16
+ EVDEV_ABS_01=0:4096:16
+
#########################################
# Google
#########################################
EVDEV_ABS_35=1262:5679:44
EVDEV_ABS_36=1101:4824:65
+# Lenovo Thinkpad Carbon X1 5th gen.
+evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th*
+ EVDEV_ABS_00=::44
+ EVDEV_ABS_01=::65
+ EVDEV_ABS_35=::44
+ EVDEV_ABS_36=::65
+
+# Lenovo Thinkpad Carbon X1 5th gen. (rmi4)
+evdev:name:Synaptics TM3289-002:dmi:*svnLENOVO*:pvrThinkPadX1Carbon5th*
+ EVDEV_ABS_00=::19
+ EVDEV_ABS_01=::19
+ EVDEV_ABS_35=::19
+ EVDEV_ABS_36=::19
+
# Lenovo T460
evdev:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO*:pn*ThinkPad*T460*
EVDEV_ABS_00=1266:5677:44
EVDEV_ABS_35=0:2480:28
EVDEV_ABS_36=0:1116:24
+# Samsung 880Z5E
+evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn870Z5E/880Z5E/680Z5E*
+ EVDEV_ABS_00=::30
+ EVDEV_ABS_01=::29
+ EVDEV_ABS_35=::30
+ EVDEV_ABS_36=::29
+
#########################################
# Toshiba
#########################################
evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnTOSHIBA:pnTECRAM11*
EVDEV_ABS_00=90:962:11
EVDEV_ABS_01=51:681:14
+
+#########################################
+# Waltop
+#########################################
+
+# WALTOP International Corp. Slim Tablet
+evdev:input:b0003v172Fp0031*
+ EVDEV_ABS_00=0:10000:400
+ EVDEV_ABS_01=0:6250:400
# This file is part of systemd.
#
-# Keyboard mapping of scan codes to key codes, and
-# scan codes to add to the AT keyboard's 'force-release' list.
+# This file contains 3 types of metadata to apply to keyboards and
+# keyboard-like input devices:
+# - Key mapping
+# - Hard-coded layouts
+# - Absence of modifier LEDs
+#
+# The matching process is the same for the different types of metadata.
+#
+# ########################### MATCHING #######################################
#
# The lookup keys are composed in:
# 60-evdev.rules
# /sys/class/input/input?/capabilities/ev" and <vendor> is the
# firmware-provided string exported by the kernel DMI modalias,
# see /sys/class/dmi/id/modalias
+
+
+# ######################### KEY MAPPING ######################################
+#
+# Keyboard mapping of scan codes to key codes, and
+# scan codes to add to the AT keyboard's 'force-release' list.
#
# Scan codes are specified as:
# KEYBOARD_KEY_<hex scan code>=<key code identifier>
# The scan code should be expressed in hex lowercase. The key codes
# are retrieved and normalized from the kernel input API header.
+# Keycodes are either KEY_* defines in lowercase with the key_ prefix
+# optionally removed or BTN_ defines in lowercase with btn_ preserved.
#
# An '!' as the first character of the key identifier string
# will add the scan code to the AT keyboard's list of scan codes
# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the keyboard in question. If in
-# doubt, simply use /dev/input/event* to reload all input rules.
+# doubt, simply reload all input rules
+# udevadm trigger --verbose --sysname-match="event*"
#
# If your changes are generally applicable, preferably send them as a pull
# request to
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnGateway*:pnA0A1*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svneMachines:pneMachines*E725:pvr*
+ KEYBOARD_KEY_86=wlan # Fn+F3 or Fn+Q for comunication key
KEYBOARD_KEY_a5=help # Fn+F1
KEYBOARD_KEY_a6=setup # Fn+F2 Acer eSettings
KEYBOARD_KEY_a7=battery # Fn+F3 Power Management
KEYBOARD_KEY_f3=prog2 # "P2" programmable button
KEYBOARD_KEY_f4=prog1 # "P1" programmable button
KEYBOARD_KEY_f5=presentation
+ KEYBOARD_KEY_f6=power # Power button
KEYBOARD_KEY_f8=fn
KEYBOARD_KEY_f9=prog1 # Launch NTI shadow
KEYBOARD_KEY_6b=fn
KEYBOARD_KEY_6c=screenlock # FIXME: lock tablet device/buttons
+# Travelmate P648-G2-MG
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnTravelMate*P648-G2-MG*:pvr*
+ KEYBOARD_KEY_8a=f20 # Microphone mute button; should be micmute
+
# on some models this isn't brightnessup
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5210*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pn*5220*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAcer*:pnAOA*:pvr*
KEYBOARD_KEY_a9=!switchvideomode # Fn+F5
+# Easynote models
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnPackard*Bell*:pnEasynote*:pvr*
+ KEYBOARD_KEY_86=wlan # Fn+F3 or Fn+Q for comunication key
+
###########################################################
# Alienware
###########################################################
###########################################################
evdev:name:gpio-keys:phys:gpio-keys/input0:ev:3:dmi:bvn*:bvr*:bd*:svncube:pni1-TF:*
- KEYBOARD_KEY_0=home
+ KEYBOARD_KEY_0=leftmeta
KEYBOARD_KEY_1=power
###########################################################
KEYBOARD_KEY_88=! # wireless switch
KEYBOARD_KEY_9e=!f21
+# Dell Latitude E7*
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*E7*:pvr*
+ KEYBOARD_KEY_88=unknown # Fn-PrtScr rfkill - handled in HW
+
# Dell XPS
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS*:pvr*
KEYBOARD_KEY_8c=!unknown
###########################################################
# Akoya
+evdev:atkbd:dmi:bvn*:bvr*:svnMEDION*:pnS3409*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:svnMedion*:pnAkoya*:pvr*
KEYBOARD_KEY_a0=!mute
KEYBOARD_KEY_ae=!volumedown
KEYBOARD_KEY_ae=! # volume down
KEYBOARD_KEY_b0=! # volume up
-###########################################################
-# Fixed layout devices
-###########################################################
+######################### FIXED LAYOUT DEVICES #############################
+# This section lists devices for which only one keyboard layout is possible
+# or useful such as devices which "type" expecting the user's keymap to match
+# a particular one. For example, barcode readers and OTP keys.
+#
+# The layout must be an xkb compatible layout (defined with XKB_FIXED_LAYOUT),
+# with an accompanying variant (defined with XKB_FIXED_VARIANT) if necessary.
# Yubico Yubico Yubikey II"
evdev:input:b0003v1050p0010*
evdev:input:b0003v05FEp1010*
XKB_FIXED_LAYOUT="us"
XKB_FIXED_VARIANT=""
+
+######################### LACK OF MODIFIER LEDS ############################
+# This section lists keyboard which do not have their own LEDs for some
+# modifiers. Only Caps-Lock (KEYBOARD_LED_CAPSLOCK) and Num-Lock
+# (KEYBOARD_LED_CAPSLOCK) are currently handled and need their values set
+# to "0" to indicate the absence of LED.
+#
+# Presence of a LED is implicit when the property is absent.
+
+# Logitech K750
+evdev:input:b0003v046Dp4002*
+ KEYBOARD_LED_NUMLOCK=0
+ KEYBOARD_LED_CAPSLOCK=0
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 0
+sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ*
+ ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
+
+#########################################
+# Endless
+#########################################
+sensor:modalias:acpi:ACCE0001*:dmi:*svnEndless*:*pnELT-NL3*
+ ACCEL_MOUNT_MATRIX=0, 1, 0; 0, 0, -1; -1, 0, 0
+
+#########################################
+# HP
+#########################################
+sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8540w*
+sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8560w*
+ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, 0, -1; 0, 1, 0
+
#########################################
# Winbook
#########################################
sensor:modalias:acpi:BMA250*:dmi:*svn*WinBook*:*pn*TW100*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 0
+
+#########################################
+# Cytrix (Mytrix)
+#########################################
+sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t*
+ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
+
--- /dev/null
+# This file is part of systemd.
+#
+# Database for joystick device information that cannot be queried directly.
+#
+# The lookup keys are composed in:
+# 70-joystick.rules
+#
+# Note: The format of the "joystick:" prefix match key is a
+# contract between the rules file and the hardware data, it might
+# change in later revisions to support more or better matches, it
+# is not necessarily expected to be a stable ABI.
+#
+# Match string format:
+# joystick:<bustype>:v<vid>p<pid>:name:<name>:
+#
+# vid/pid as 4-digit hex lowercase vendor/product
+#
+# To add local entries, create a new file
+# /etc/udev/hwdb.d/71-joystick-local.hwdb
+# and add your rules there. To load the new rules execute (as root):
+# systemd-hwdb update
+# udevadm trigger /dev/input/eventXX
+# where /dev/input/eventXX is the joystick in question. If in
+# doubt, simply use /dev/input/event* to reload all input rules.
+#
+# If your changes are generally applicable, preferably send them as a pull
+# request to
+# https://github.com/systemd/systemd
+# or create a bug report on https://github.com/systemd/systemd/issues and
+# include your new rules, a description of the device, and the output of
+# udevadm info /dev/input/eventXX.
+#
+# Permitted keys:
+# Specify if a joystick is a built-in one or external:
+# ID_INPUT_JOYSTICK_INTEGRATION=internal|external
+#
+# If the property is missing, user-space can assume:
+# ID_INPUT_JOYSTICK_INTEGRATION=external
+
+joystick:bluetooth:*
+ ID_INPUT_JOYSTICK_INTEGRATION=external
+
+###########################################################
+# GPD
+###########################################################
+
+# GPD Win, Classic and XBox 360 compat modes
+joystick:usb:v11c5p5507*
+joystick:usb:v045ep028e*
+ ID_INPUT_JOYSTICK_INTEGRATION=internal
mouse:usb:v0461p4d16:name:USB Optical Mouse:
MOUSE_DPI=500@125
+##########################################
+# Future Technology Devices International
+##########################################
+
+# SNES Mouse plugged into a Retrode 2
+mouse:usb:v0403p97c1:name:Retrode SNES Mouse:
+ MOUSE_DPI=235@126
+
##########################################
# HandShoe Mouse
##########################################
mouse:usb:v093ap2510:name:PIXART USB OPTICAL MOUSE:
MOUSE_DPI=1000@125
+##########################################
+# IBM
+##########################################
+
+# IBM USB Travel Mouse (MO32BO)
+mouse:usb:v04b3p3107:name:*
+ MOUSE_DPI=800@125
+
##########################################
# Lenovo
##########################################
POINTINGSTICK_SENSITIVITY=200
POINTINGSTICK_CONST_ACCEL=1.0
-# Lenovo Thinkpad X200s / X201s
+# Lenovo Thinkpad X200/X201/X200s/X201s
# Note these come with 2 revisions of keyboard, with the trackpoints having a
# different sensitivity in the different revisions. 1.25 is a bit slow for the
# least sensitive revision, but it is better to be a bit slow than too fast.
-evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20?s:*
+evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20?:*
+evdev:name:TPPS/2 IBM TrackPoint:dmi:bvn*:bvr*:bd*:svnLENOVO:pn*:pvrThinkPadX20??:*
POINTINGSTICK_SENSITIVITY=200
POINTINGSTICK_CONST_ACCEL=1.25
+
+# Lenovo UltraNav SK-8845 (USB keyboard)
+evdev:input:b0003v06CBp0009*
+ POINTINGSTICK_CONST_ACCEL=2.5
+ POINTINGSTICK_SENSITIVITY=200
###########################################################
touchpad:usb:v056a*
ID_INPUT_TOUCHPAD_INTEGRATION=external
+
+###########################################################
+# Microsoft (Surface Type Covers)
+###########################################################
+touchpad:usb:v045ep07*
+ ID_INPUT_TOUCHPAD_INTEGRATION=internal
+
-#!/usr/bin/python3
+#!/usr/bin/env python3
from html.parser import HTMLParser
from enum import Enum
--- /dev/null
+hwdb_files = files('''
+ 20-pci-vendor-model.hwdb
+ 20-pci-classes.hwdb
+ 20-usb-vendor-model.hwdb
+ 20-usb-classes.hwdb
+ 20-sdio-vendor-model.hwdb
+ 20-sdio-classes.hwdb
+ 20-bluetooth-vendor-product.hwdb
+ 20-acpi-vendor.hwdb
+ 20-OUI.hwdb
+ 20-net-ifname.hwdb
+ 60-evdev.hwdb
+ 60-keyboard.hwdb
+ 60-sensor.hwdb
+ 70-mouse.hwdb
+ 70-pointingstick.hwdb
+ 70-touchpad.hwdb
+'''.split())
+
+if conf.get('ENABLE_HWDB', false)
+ install_data(hwdb_files,
+ install_dir : udevhwdbdir)
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'udev/hwdb.d')))
+
+ meson.add_install_script('sh', '-c',
+ 'test -n "$DESTDIR" || @0@/systemd-hwdb update'
+ .format(rootbindir))
+endif
+
+############################################################
+
+parse_hwdb_py = find_program('parse_hwdb.py')
+test('parse-hwdb',
+ parse_hwdb_py,
+ timeout : 90)
+
+############################################################
+
+run_target(
+ 'update',
+ command : [hwdb_update_sh, meson.current_source_dir()])
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd. It is distrubuted under the MIT license, see
TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
'evdev': ('name', 'atkbd', 'input'),
'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'),
+ 'joystick': ('i8042', 'rmi', 'bluetooth', 'usb'),
'keyboard': ('name', ),
'sensor': ('modalias', ),
}
('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')),
('POINTINGSTICK_SENSITIVITY', INTEGER),
('POINTINGSTICK_CONST_ACCEL', REAL),
+ ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))),
('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))),
('XKB_FIXED_LAYOUT', STRING),
('XKB_FIXED_VARIANT', STRING),
+ ('KEYBOARD_LED_NUMLOCK', Literal('0')),
+ ('KEYBOARD_LED_CAPSLOCK', Literal('0')),
('ACCEL_MOUNT_MATRIX', mount_matrix),
)
fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE')
if value != '!' and ecodes is not None:
key = 'KEY_' + value.upper()
if key not in ecodes:
- error('Keycode {} unknown', key)
+ key = value.upper()
+ if key not in ecodes:
+ error('Keycode {} unknown', key)
def check_properties(groups):
grammar = property_grammar()
-#!/usr/bin/python3
+#!/usr/bin/env python3
"""
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<!ENTITY MOUNT_PATH @MOUNT_PATH@>
+<!ENTITY UMOUNT_PATH @UMOUNT_PATH@>
+<!ENTITY systemgeneratordir @SYSTEM_GENERATOR_PATH@>
+<!ENTITY usergeneratordir @USER_GENERATOR_PATH@>
+<!ENTITY systemenvgeneratordir @SYSTEM_ENV_GENERATOR_PATH@>
+<!ENTITY userenvgeneratordir @USER_ENV_GENERATOR_PATH@>
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="environment.d" xmlns:xi="http://www.w3.org/2001/XInclude">
+<refentry id="environment.d" conditional='ENABLE_ENVIRONMENT_D'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>environment.d</title>
<programlisting>
FOO_DEBUG=force-software-gl,log-verbose
PATH=/opt/foo/bin:$PATH
- LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}/opt/foo/lib
+ LD_LIBRARY_PATH=/opt/foo/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}
</programlisting>
</example>
<varlistentry>
<term>
- <option>short-precise</option>
+ <option>short-iso-precise</option>
</term>
<listitem>
- <para>is very similar, but shows timestamps with full
+ <para>as for <option>short-iso</option> but includes full
microsecond precision.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>short-precise</option>
+ </term>
+ <listitem>
+ <para>is very similar, but shows classic syslog timestamps
+ with full microsecond precision.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>
<option>short-monotonic</option>
kernel command line arguments.</para>
<para>For command line parameters understood by the kernel, please
- see <ulink
- url="https://www.kernel.org/doc/Documentation/kernel-parameters.txt"><filename>kernel-parameters.txt</filename></ulink>
+ see
+ <ulink url="https://www.kernel.org/doc/html/latest/admin-guide/kernel-parameters.html"><filename>kernel-parameters.html</filename></ulink>
and
<citerefentry project='man-pages'><refentrytitle>bootparam</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<listitem><para>Pager to use when <option>--no-pager</option> is not given; overrides
<varname>$PAGER</varname>. If neither <varname>$SYSTEMD_PAGER</varname> nor <varname>$PAGER</varname> are set, a
set of well-known pager implementations are tried in turn, including
- <citerefentry><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
- <citerefentry><refentrytitle>more</refentrytitle><manvolnum>1</manvolnum></citerefentry>, until one is found. If
+ <citerefentry project='man-pages'><refentrytitle>less</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
+ <citerefentry project='man-pages'><refentrytitle>more</refentrytitle><manvolnum>1</manvolnum></citerefentry>, until one is found. If
no pager implementation is discovered no pager is invoked. Setting this environment variable to an empty string
or the value <literal>cat</literal> is equivalent to passing <option>--no-pager</option>.</para></listitem>
</varlistentry>
might be checked for locale configuration as well, however only as
fallback.</para>
- <para><citerefentry project='man-pages'><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ <para><filename>/etc/vconsole.conf</filename> is usually created and updated
+ using
+ <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ <citerefentry project='man-pages'><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
may be used to alter the settings in this file during runtime from
the command line. Use
<citerefentry><refentrytitle>systemd-firstboot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- to initialize them on mounted (but not booted) system
- images.</para>
+ to initialize them on mounted (but not booted) system images.</para>
</refsect1>
<refsect1>
<para>A different application may disable logind's handling of system power and
sleep keys and the lid switch by taking a low-level inhibitor lock
- ("handle-power-key", "handle-suspend-key", "handle-hibernate-key",
- "handle-lid-switch"). This is most commonly used by graphical desktop environments
+ (<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
+ <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>).
+ This is most commonly used by graphical desktop environments
to take over suspend and hibernation handling, and to use their own configuration
mechanisms. If a low-level inhibitor lock is taken, logind will not take any
action when that key or switch is triggered and the <varname>Handle*=</varname>
<listitem><para>Controls whether actions that <command>systemd-logind</command>
takes when the power and sleep keys and the lid switch are triggered are subject
to high-level inhibitor locks ("shutdown", "sleep", "idle"). Low level inhibitor
- locks ("handle-*-key"), are always honored, irrespective of this setting.</para>
+ locks (<literal>handle-power-key</literal>, <literal>handle-suspend-key</literal>,
+ <literal>handle-hibernate-key</literal>, <literal>handle-lid-switch</literal>),
+ are always honored, irrespective of this setting.</para>
<para>These settings take boolean arguments. If <literal>no</literal>, the
inhibitor locks taken by applications are respected. If <literal>yes</literal>,
is automatically derived from the last component of the URL,
with its suffix removed.</para>
- <para>The image is verified before it is made available,
- unless <option>--verify=no</option> is specified. Verification
- is done via SHA256SUMS and SHA256SUMS.gpg files that need to
- be made available on the same web server, under the same URL
- as the <filename>.tar</filename> file, but with the last
- component (the filename) of the URL replaced. With
- <option>--verify=checksum</option>, only the SHA256 checksum
- for the file is verified, based on the
- <filename>SHA256SUMS</filename> file. With
- <option>--verify=signature</option>, the SHA256SUMS file is
- first verified with detached GPG signature file
- <filename>SHA256SUMS.gpg</filename>. The public key for this
- verification step needs to be available in
+ <para>The image is verified before it is made available, unless
+ <option>--verify=no</option> is specified.
+ Verification is done either via an inline signed file with the name
+ of the image and the suffix <filename>.sha256</filename> or via
+ separate <filename>SHA256SUMS</filename> and
+ <filename>SHA256SUMS.gpg</filename> files.
+ The signature files need to be made available on the same web
+ server, under the same URL as the <filename>.tar</filename> file.
+ With <option>--verify=checksum</option>, only the SHA256 checksum
+ for the file is verified, based on the <filename>.sha256</filename>
+ suffixed file or the<filename>SHA256SUMS</filename> file.
+ With <option>--verify=signature</option>, the sha checksum file is
+ first verified with the inline signature in the
+ <filename>.sha256</filename> file or the detached GPG signature file
+ <filename>SHA256SUMS.gpg</filename>.
+ The public key for this verification step needs to be available in
<filename>/usr/lib/systemd/import-pubring.gpg</filename> or
<filename>/etc/systemd/import-pubring.gpg</filename>.</para>
--- /dev/null
+# This is lame, I know, but meson has no other include mechanism
+subdir('rules')
+
+want_man = get_option('man')
+want_html = get_option('html')
+xsltproc = find_program('xsltproc',
+ required : want_man == 'true' or want_html == 'true')
+want_man = want_man != 'false' and xsltproc.found()
+want_html = want_html != 'false' and xsltproc.found()
+
+xsltproc_flags = [
+ '--nonet',
+ '--xinclude',
+ '--stringparam', 'man.output.quietly', '1',
+ '--stringparam', 'funcsynopsis.style', 'ansi',
+ '--stringparam', 'man.authors.section.enabled', '0',
+ '--stringparam', 'man.copyright.section.enabled', '0',
+ '--stringparam', 'systemd.version', '@0@'.format(meson.project_version()),
+ '--path',
+ '@0@:@1@'.format(meson.current_build_dir(), meson.current_source_dir())]
+
+custom_man_xsl = files('custom-man.xsl')
+custom_html_xsl = files('custom-html.xsl')
+xslt_cmd = [xsltproc, '-o', '@OUTPUT0@'] + xsltproc_flags
+
+custom_entities_ent = configure_file(
+ input : 'custom-entities.ent.in',
+ output : 'custom-entities.ent',
+ configuration : conf)
+
+man_pages = []
+html_pages = []
+source_xml_files = []
+foreach tuple : manpages
+ stem = tuple[0]
+ section = tuple[1]
+ aliases = tuple[2]
+ condition = tuple[3]
+
+ xml = stem + '.xml'
+ html = stem + '.html'
+ man = stem + '.' + section
+
+ manaliases = []
+ htmlaliases = []
+ foreach alias : aliases
+ manaliases += [alias + '.' + section]
+ htmlaliases += [alias + '.html']
+ endforeach
+
+ mandirn = join_paths(get_option('mandir'), 'man' + section)
+
+ if condition == '' or conf.get(condition, false)
+ p1 = custom_target(
+ man,
+ input : xml,
+ output : [man] + manaliases,
+ command : xslt_cmd + [custom_man_xsl, '@INPUT@'],
+ depend_files : custom_entities_ent,
+ install : want_man,
+ install_dir : mandirn)
+ man_pages += [p1]
+
+ p2 = []
+ foreach htmlalias : htmlaliases
+ link = custom_target(
+ htmlalias,
+ input : p2,
+ output : htmlalias,
+ command : ['ln', '-fs', html, '@OUTPUT@'])
+ if want_html
+ dst = join_paths(docdir, 'html', htmlalias)
+ cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
+ meson.add_install_script('sh', '-c', cmd)
+ p2 += [link]
+ endif
+ html_pages += [link]
+ endforeach
+
+ p3 = custom_target(
+ html,
+ input : xml,
+ output : html,
+ command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
+ depend_files : custom_entities_ent,
+ depends : p2,
+ install : want_html,
+ install_dir : join_paths(docdir, 'html'))
+ html_pages += [p3]
+
+ source_xml_files += files(tuple[0] + '.xml')
+ else
+ message('Skipping @0@.@1@ because @2@ is false'.format(stem, section, condition))
+ endif
+endforeach
+
+############################################################
+
+have_lxml = run_command(xml_helper_py).returncode() == 0
+if not have_lxml
+ message('python-lxml not available, not making man page indices')
+endif
+
+systemd_directives_xml = custom_target(
+ 'systemd.directives.xml',
+ input : source_xml_files,
+ output : 'systemd.directives.xml',
+ command : [make_directive_index_py, '@OUTPUT@'] + source_xml_files)
+
+nonindex_xml_files = source_xml_files + [systemd_directives_xml]
+systemd_index_xml = custom_target(
+ 'systemd.index.xml',
+ input : nonindex_xml_files,
+ output : 'systemd.index.xml',
+ command : [make_man_index_py, '@OUTPUT@'] + nonindex_xml_files)
+
+foreach tuple : [['systemd.directives', '7', systemd_directives_xml],
+ ['systemd.index', '7', systemd_index_xml]]
+ stem = tuple[0]
+ section = tuple[1]
+ xml = tuple[2]
+
+ html = stem + '.html'
+ man = stem + '.' + section
+
+ mandirn = join_paths(get_option('mandir'), 'man' + section)
+
+ p1 = custom_target(
+ man,
+ input : xml,
+ output : man,
+ command : xslt_cmd + [custom_man_xsl, '@INPUT@'],
+ install : want_man and have_lxml,
+ install_dir : mandirn)
+ man_pages += [p1]
+
+ p2 = []
+ if html == 'systemd.index.html'
+ htmlalias = 'index.html'
+ link = custom_target(
+ htmlalias,
+ input : p2,
+ output : htmlalias,
+ command : ['ln', '-fs', html, '@OUTPUT@'])
+ if want_html
+ dst = join_paths(docdir, 'html', htmlalias)
+ cmd = 'ln -fs @0@ $DESTDIR@1@'.format(html, dst)
+ meson.add_install_script('sh', '-c', cmd)
+ p2 += [link]
+ endif
+ html_pages += [link]
+ endif
+
+ p3 = custom_target(
+ html,
+ input : xml,
+ output : html,
+ command : xslt_cmd + [custom_html_xsl, '@INPUT@'],
+ depend_files : custom_entities_ent,
+ depends : p2,
+ install : want_html and have_lxml,
+ install_dir : join_paths(docdir, 'html'))
+ html_pages += [p3]
+endforeach
+
+# cannot use run_target until https://github.com/mesonbuild/meson/issues/1644 is resolved
+man = custom_target(
+ 'man',
+ output : 'man',
+ depends : man_pages,
+ command : ['echo'])
+
+html = run_target(
+ 'html',
+ depends : html_pages,
+ output : 'html',
+ command : ['echo'])
+
+run_target(
+ 'doc-sync',
+ depends : man_pages + html_pages,
+ command : ['rsync', '-rlv',
+ '--delete-excluded',
+ '--include=man',
+ '--include=*.html',
+ '--exclude=*',
+ '--omit-dir-times',
+ meson.current_build_dir(),
+ get_option('www-target')])
+
+############################################################
+
+if git.found()
+ run_target(
+ 'update-man-rules',
+ # slightly strange syntax because of
+ # https://github.com/mesonbuild/meson/issues/1643
+ # and https://github.com/mesonbuild/meson/issues/1512
+ command : ['sh', '-c',
+ 'cd @0@ && '.format(meson.build_root()) +
+ 'python3 @0@/tools/make-man-rules.py --meson `git ls-files ":/man/*.xml"` >t && '.format(meson.source_root()) +
+ 'mv t @0@/rules/meson.build'.format(meson.current_source_dir())],
+ depend_files : custom_entities_ent)
+endif
1 neighbors listed.</programlisting></para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ <command>label</command>
+ </term>
+
+ <listitem><para>Show numerical address labels that can be used for address selection.
+ This is the same information that
+ <citerefentry><refentrytitle>ip-addrlabel</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ shows. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>
+ for a discussion of address labels.</para>
+
+ <para>Produces output similar to:
+ <programlisting>Prefix/Prefixlen Label
+ ::/0 1
+ fc00::/7 5
+ fec0::/10 11
+ 2002::/16 2
+ 3ffe::/16 12
+ 2001:10::/28 7
+ 2001::/32 6
+::ffff:0.0.0.0/96 4
+ ::/96 3
+ ::1/128 0</programlisting></para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
- <para>On success, 0 is returned, a non-zero failure
- code otherwise.</para>
+ <para>On success, 0 is returned, a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
<para>
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
hostnames via DNS.</para>
<para>To activate the NSS module, add <literal>resolve</literal> to the line starting with
- <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>. Specifcally, it is recommended to place
- <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>' <literal>hosts:</literal> line (but
+ <literal>hosts:</literal> in <filename>/etc/nsswitch.conf</filename>. Specifically, it is recommended to place
+ <literal>resolve</literal> early in <filename>/etc/nsswitch.conf</filename>'s <literal>hosts:</literal> line (but
after the <literal>files</literal> or <literal>mymachines</literal> entries), right before the
<literal>dns</literal> entry if it exists, followed by <literal>[!UNAVAIL=return]</literal>, to ensure DNS queries
are always routed via
<citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry> if it is
running, but are routed to <command>nss-dns</command> if this service is not available.</para>
+
+ <para>Note that <command>systemd-resolved</command> will synthesize DNS resource
+ records in a few cases, for example for <literal>localhost</literal> and the
+ current hostname, see
+ <citerefentry><refentrytitle>systemd-resolved</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for the full list. This duplicates the functionality of
+ <citerefentry><refentrytitle>nss-myhostname</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ but it is still recommended (see examples below) to keep
+ <command>nss-myhostname</command> configured in
+ <filename>/etc/nsswitch.conf</filename>, to keep those names resolveable if
+ <command>systemd-resolved</command> is not running.</para>
</refsect1>
<refsect1>
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="nss-systemd">
+<refentry id="nss-systemd" conditional='ENABLE_NSS_SYSTEMD'>
<refentryinfo>
<title>nss-systemd</title>
and so will the user's slice unit.</para></listitem>
<listitem><para>If the last concurrent session of a user ends,
- the <varname>$XDG_RUNTIME_DIR</varname> directory and all its
+ the user runtime directory <filename>/run/user/$UID</filename> and all its
contents are removed, too.</para></listitem>
</orderedlist>
offers the greatest possible file system feature set the
operating system provides. For further details, see the <ulink
url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
- Base Directory Specification</ulink>.</para></listitem>
+ Base Directory Specification</ulink>. <varname>$XDG_RUNTIME_DIR</varname>
+ is not set if the current user is not the original user of the session.</para></listitem>
</varlistentry>
</variablelist>
global setting is on.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>MulticastDNS=</varname></term>
+ <listitem><para>Takes a boolean argument or
+ <literal>resolve</literal>. Controls Multicast DNS support (<ulink
+ url="https://tools.ietf.org/html/rfc6762">RFC 6762</ulink>) on
+ the local host. If true, enables full Multicast DNS responder and
+ resolver support. If false, disables both. If set to
+ <literal>resolve</literal>, only resolution support is enabled,
+ but responding is disabled. Note that
+ <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ also maintains per-link Multicast DNS settings. Multicast DNS will be
+ enabled on a link only if the per-link and the
+ global setting is on.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>DNSSEC=</varname></term>
<listitem><para>Takes a boolean argument or
--- /dev/null
+# Do not edit. Generated by make-man-rules.py.
+manpages = [
+['binfmt.d', '5', [], 'ENABLE_BINFMT'],
+ ['bootctl', '1', [], 'ENABLE_EFI'],
+ ['bootup', '7', [], ''],
+ ['busctl', '1', [], ''],
+ ['coredump.conf', '5', ['coredump.conf.d'], 'ENABLE_COREDUMP'],
+ ['coredumpctl', '1', [], 'ENABLE_COREDUMP'],
+ ['crypttab', '5', [], 'HAVE_LIBCRYPTSETUP'],
+ ['daemon', '7', [], ''],
+ ['dnssec-trust-anchors.d',
+ '5',
+ ['systemd.negative', 'systemd.positive'],
+ 'ENABLE_RESOLVED'],
+ ['environment.d', '5', [], 'ENABLE_ENVIRONMENT_D'],
+ ['file-hierarchy', '7', [], ''],
+ ['halt', '8', ['poweroff', 'reboot'], ''],
+ ['hostname', '5', [], ''],
+ ['hostnamectl', '1', [], 'ENABLE_HOSTNAMED'],
+ ['hwdb', '7', [], 'ENABLE_HWDB'],
+ ['journal-remote.conf', '5', ['journal-remote.conf.d'], 'HAVE_MICROHTTPD'],
+ ['journal-upload.conf', '5', ['journal-upload.conf.d'], 'HAVE_MICROHTTPD'],
+ ['journalctl', '1', [], ''],
+ ['journald.conf', '5', ['journald.conf.d'], ''],
+ ['kernel-command-line', '7', [], ''],
+ ['kernel-install', '8', [], ''],
+ ['libudev', '3', [], ''],
+ ['locale.conf', '5', [], ''],
+ ['localectl', '1', [], 'ENABLE_LOCALED'],
+ ['localtime', '5', [], ''],
+ ['loginctl', '1', [], 'ENABLE_LOGIND'],
+ ['logind.conf', '5', ['logind.conf.d'], 'ENABLE_LOGIND'],
+ ['machine-id', '5', [], ''],
+ ['machine-info', '5', [], ''],
+ ['machinectl', '1', [], 'ENABLE_MACHINED'],
+ ['modules-load.d', '5', [], 'HAVE_KMOD'],
+ ['networkctl', '1', [], 'ENABLE_NETWORKD'],
+ ['networkd.conf', '5', ['networkd.conf.d'], 'ENABLE_NETWORKD'],
+ ['nss-myhostname', '8', ['libnss_myhostname.so.2'], 'HAVE_MYHOSTNAME'],
+ ['nss-mymachines', '8', ['libnss_mymachines.so.2'], 'ENABLE_MACHINED'],
+ ['nss-resolve', '8', ['libnss_resolve.so.2'], 'ENABLE_RESOLVED'],
+ ['nss-systemd', '8', ['libnss_systemd.so.2'], 'ENABLE_NSS_SYSTEMD'],
+ ['os-release', '5', [], ''],
+ ['pam_systemd', '8', [], 'HAVE_PAM'],
+ ['resolved.conf', '5', ['resolved.conf.d'], 'ENABLE_RESOLVED'],
+ ['runlevel', '8', [], 'HAVE_UTMP'],
+ ['sd-bus-errors',
+ '3',
+ ['SD_BUS_ERROR_ACCESS_DENIED',
+ 'SD_BUS_ERROR_ADDRESS_IN_USE',
+ 'SD_BUS_ERROR_AUTH_FAILED',
+ 'SD_BUS_ERROR_BAD_ADDRESS',
+ 'SD_BUS_ERROR_DISCONNECTED',
+ 'SD_BUS_ERROR_FAILED',
+ 'SD_BUS_ERROR_FILE_EXISTS',
+ 'SD_BUS_ERROR_FILE_NOT_FOUND',
+ 'SD_BUS_ERROR_INCONSISTENT_MESSAGE',
+ 'SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED',
+ 'SD_BUS_ERROR_INVALID_ARGS',
+ 'SD_BUS_ERROR_INVALID_SIGNATURE',
+ 'SD_BUS_ERROR_IO_ERROR',
+ 'SD_BUS_ERROR_LIMITS_EXCEEDED',
+ 'SD_BUS_ERROR_MATCH_RULE_INVALID',
+ 'SD_BUS_ERROR_MATCH_RULE_NOT_FOUND',
+ 'SD_BUS_ERROR_NAME_HAS_NO_OWNER',
+ 'SD_BUS_ERROR_NOT_SUPPORTED',
+ 'SD_BUS_ERROR_NO_MEMORY',
+ 'SD_BUS_ERROR_NO_NETWORK',
+ 'SD_BUS_ERROR_NO_REPLY',
+ 'SD_BUS_ERROR_NO_SERVER',
+ 'SD_BUS_ERROR_PROPERTY_READ_ONLY',
+ 'SD_BUS_ERROR_SERVICE_UNKNOWN',
+ 'SD_BUS_ERROR_TIMEOUT',
+ 'SD_BUS_ERROR_UNIX_PROCESS_ID_UNKNOWN',
+ 'SD_BUS_ERROR_UNKNOWN_INTERFACE',
+ 'SD_BUS_ERROR_UNKNOWN_METHOD',
+ 'SD_BUS_ERROR_UNKNOWN_OBJECT',
+ 'SD_BUS_ERROR_UNKNOWN_PROPERTY'],
+ ''],
+ ['sd-bus', '3', [], ''],
+ ['sd-daemon',
+ '3',
+ ['SD_ALERT',
+ 'SD_CRIT',
+ 'SD_DEBUG',
+ 'SD_EMERG',
+ 'SD_ERR',
+ 'SD_INFO',
+ 'SD_NOTICE',
+ 'SD_WARNING'],
+ ''],
+ ['sd-event', '3', [], ''],
+ ['sd-id128',
+ '3',
+ ['SD_ID128_CONST_STR',
+ 'SD_ID128_FORMAT_STR',
+ 'SD_ID128_FORMAT_VAL',
+ 'SD_ID128_MAKE',
+ 'SD_ID128_MAKE_STR',
+ 'SD_ID128_NULL',
+ 'sd_id128_equal',
+ 'sd_id128_is_null',
+ 'sd_id128_t'],
+ ''],
+ ['sd-journal', '3', [], ''],
+ ['sd-login', '3', [], 'HAVE_PAM'],
+ ['sd_booted', '3', [], ''],
+ ['sd_bus_add_match', '3', [], ''],
+ ['sd_bus_creds_get_pid',
+ '3',
+ ['sd_bus_creds_get_audit_login_uid',
+ 'sd_bus_creds_get_audit_session_id',
+ 'sd_bus_creds_get_cgroup',
+ 'sd_bus_creds_get_cmdline',
+ 'sd_bus_creds_get_comm',
+ 'sd_bus_creds_get_description',
+ 'sd_bus_creds_get_egid',
+ 'sd_bus_creds_get_euid',
+ 'sd_bus_creds_get_exe',
+ 'sd_bus_creds_get_fsgid',
+ 'sd_bus_creds_get_fsuid',
+ 'sd_bus_creds_get_gid',
+ 'sd_bus_creds_get_owner_uid',
+ 'sd_bus_creds_get_ppid',
+ 'sd_bus_creds_get_selinux_context',
+ 'sd_bus_creds_get_session',
+ 'sd_bus_creds_get_sgid',
+ 'sd_bus_creds_get_slice',
+ 'sd_bus_creds_get_suid',
+ 'sd_bus_creds_get_supplementary_gids',
+ 'sd_bus_creds_get_tid',
+ 'sd_bus_creds_get_tid_comm',
+ 'sd_bus_creds_get_tty',
+ 'sd_bus_creds_get_uid',
+ 'sd_bus_creds_get_unique_name',
+ 'sd_bus_creds_get_unit',
+ 'sd_bus_creds_get_user_slice',
+ 'sd_bus_creds_get_user_unit',
+ 'sd_bus_creds_get_well_known_names',
+ 'sd_bus_creds_has_bounding_cap',
+ 'sd_bus_creds_has_effective_cap',
+ 'sd_bus_creds_has_inheritable_cap',
+ 'sd_bus_creds_has_permitted_cap'],
+ ''],
+ ['sd_bus_creds_new_from_pid',
+ '3',
+ ['sd_bus_creds_get_augmented_mask',
+ 'sd_bus_creds_get_mask',
+ 'sd_bus_creds_ref',
+ 'sd_bus_creds_unref',
+ 'sd_bus_creds_unrefp'],
+ ''],
+ ['sd_bus_default',
+ '3',
+ ['sd_bus_default_system',
+ 'sd_bus_default_user',
+ 'sd_bus_open',
+ 'sd_bus_open_system',
+ 'sd_bus_open_system_machine',
+ 'sd_bus_open_system_remote',
+ 'sd_bus_open_user'],
+ ''],
+ ['sd_bus_error',
+ '3',
+ ['SD_BUS_ERROR_MAKE_CONST',
+ 'SD_BUS_ERROR_NULL',
+ 'sd_bus_error_copy',
+ 'sd_bus_error_free',
+ 'sd_bus_error_get_errno',
+ 'sd_bus_error_has_name',
+ 'sd_bus_error_is_set',
+ 'sd_bus_error_set',
+ 'sd_bus_error_set_const',
+ 'sd_bus_error_set_errno',
+ 'sd_bus_error_set_errnof',
+ 'sd_bus_error_set_errnofv',
+ 'sd_bus_error_setf'],
+ ''],
+ ['sd_bus_error_add_map',
+ '3',
+ ['SD_BUS_ERROR_END', 'SD_BUS_ERROR_MAP', 'sd_bus_error_map'],
+ ''],
+ ['sd_bus_get_fd', '3', [], ''],
+ ['sd_bus_message_append', '3', ['sd_bus_message_appendv'], ''],
+ ['sd_bus_message_append_array',
+ '3',
+ ['sd_bus_message_append_array_iovec',
+ 'sd_bus_message_append_array_memfd',
+ 'sd_bus_message_append_array_space'],
+ ''],
+ ['sd_bus_message_append_basic', '3', [], ''],
+ ['sd_bus_message_append_string_memfd',
+ '3',
+ ['sd_bus_message_append_string_iovec', 'sd_bus_message_append_string_space'],
+ ''],
+ ['sd_bus_message_append_strv', '3', [], ''],
+ ['sd_bus_message_get_cookie', '3', ['sd_bus_message_get_reply_cookie'], ''],
+ ['sd_bus_message_get_monotonic_usec',
+ '3',
+ ['sd_bus_message_get_realtime_usec', 'sd_bus_message_get_seqnum'],
+ ''],
+ ['sd_bus_message_read_basic', '3', [], ''],
+ ['sd_bus_negotiate_fds',
+ '3',
+ ['sd_bus_negotiate_creds', 'sd_bus_negotiate_timestamp'],
+ ''],
+ ['sd_bus_new', '3', ['sd_bus_ref', 'sd_bus_unref', 'sd_bus_unrefp'], ''],
+ ['sd_bus_path_encode',
+ '3',
+ ['sd_bus_path_decode', 'sd_bus_path_decode_many', 'sd_bus_path_encode_many'],
+ ''],
+ ['sd_bus_process', '3', [], ''],
+ ['sd_bus_request_name', '3', ['sd_bus_release_name'], ''],
+ ['sd_bus_track_add_name',
+ '3',
+ ['sd_bus_track_add_sender',
+ 'sd_bus_track_contains',
+ 'sd_bus_track_count',
+ 'sd_bus_track_count_name',
+ 'sd_bus_track_count_sender',
+ 'sd_bus_track_first',
+ 'sd_bus_track_next',
+ 'sd_bus_track_remove_name',
+ 'sd_bus_track_remove_sender'],
+ ''],
+ ['sd_bus_track_new',
+ '3',
+ ['sd_bus_track_get_bus',
+ 'sd_bus_track_get_recursive',
+ 'sd_bus_track_get_userdata',
+ 'sd_bus_track_ref',
+ 'sd_bus_track_set_recursive',
+ 'sd_bus_track_set_userdata',
+ 'sd_bus_track_unref',
+ 'sd_bus_track_unrefp'],
+ ''],
+ ['sd_event_add_child',
+ '3',
+ ['sd_event_child_handler_t', 'sd_event_source_get_child_pid'],
+ ''],
+ ['sd_event_add_defer',
+ '3',
+ ['sd_event_add_exit', 'sd_event_add_post', 'sd_event_handler_t'],
+ ''],
+ ['sd_event_add_io',
+ '3',
+ ['sd_event_io_handler_t',
+ 'sd_event_source',
+ 'sd_event_source_get_io_events',
+ 'sd_event_source_get_io_fd',
+ 'sd_event_source_get_io_revents',
+ 'sd_event_source_set_io_events',
+ 'sd_event_source_set_io_fd'],
+ ''],
+ ['sd_event_add_signal',
+ '3',
+ ['sd_event_signal_handler_t', 'sd_event_source_get_signal'],
+ ''],
+ ['sd_event_add_time',
+ '3',
+ ['sd_event_source_get_time',
+ 'sd_event_source_get_time_accuracy',
+ 'sd_event_source_get_time_clock',
+ 'sd_event_source_set_time',
+ 'sd_event_source_set_time_accuracy',
+ 'sd_event_time_handler_t'],
+ ''],
+ ['sd_event_exit', '3', ['sd_event_get_exit_code'], ''],
+ ['sd_event_get_fd', '3', [], ''],
+ ['sd_event_new',
+ '3',
+ ['sd_event',
+ 'sd_event_default',
+ 'sd_event_get_tid',
+ 'sd_event_ref',
+ 'sd_event_unref',
+ 'sd_event_unrefp'],
+ ''],
+ ['sd_event_now', '3', [], ''],
+ ['sd_event_run', '3', ['sd_event_loop'], ''],
+ ['sd_event_set_watchdog', '3', ['sd_event_get_watchdog'], ''],
+ ['sd_event_source_get_event', '3', [], ''],
+ ['sd_event_source_get_pending', '3', [], ''],
+ ['sd_event_source_set_description',
+ '3',
+ ['sd_event_source_get_description'],
+ ''],
+ ['sd_event_source_set_enabled',
+ '3',
+ ['SD_EVENT_OFF',
+ 'SD_EVENT_ON',
+ 'SD_EVENT_ONESHOT',
+ 'sd_event_source_get_enabled'],
+ ''],
+ ['sd_event_source_set_prepare', '3', [], ''],
+ ['sd_event_source_set_priority',
+ '3',
+ ['SD_EVENT_PRIORITY_IDLE',
+ 'SD_EVENT_PRIORITY_IMPORTANT',
+ 'SD_EVENT_PRIORITY_NORMAL',
+ 'sd_event_source_get_priority'],
+ ''],
+ ['sd_event_source_set_userdata', '3', ['sd_event_source_get_userdata'], ''],
+ ['sd_event_source_unref',
+ '3',
+ ['sd_event_source_ref', 'sd_event_source_unrefp'],
+ ''],
+ ['sd_event_wait',
+ '3',
+ ['SD_EVENT_ARMED',
+ 'SD_EVENT_EXITING',
+ 'SD_EVENT_FINISHED',
+ 'SD_EVENT_INITIAL',
+ 'SD_EVENT_PENDING',
+ 'SD_EVENT_PREPARING',
+ 'SD_EVENT_RUNNING',
+ 'sd_event_dispatch',
+ 'sd_event_get_iteration',
+ 'sd_event_get_state',
+ 'sd_event_prepare'],
+ ''],
+ ['sd_get_seats',
+ '3',
+ ['sd_get_machine_names', 'sd_get_sessions', 'sd_get_uids'],
+ 'HAVE_PAM'],
+ ['sd_id128_get_machine',
+ '3',
+ ['sd_id128_get_boot',
+ 'sd_id128_get_invocation',
+ 'sd_id128_get_machine_app_specific'],
+ ''],
+ ['sd_id128_randomize', '3', [], ''],
+ ['sd_id128_to_string', '3', ['sd_id128_from_string'], ''],
+ ['sd_is_fifo',
+ '3',
+ ['sd_is_mq',
+ 'sd_is_socket',
+ 'sd_is_socket_inet',
+ 'sd_is_socket_sockaddr',
+ 'sd_is_socket_unix',
+ 'sd_is_special'],
+ ''],
+ ['sd_journal_add_match',
+ '3',
+ ['sd_journal_add_conjunction',
+ 'sd_journal_add_disjunction',
+ 'sd_journal_flush_matches'],
+ ''],
+ ['sd_journal_enumerate_fields',
+ '3',
+ ['SD_JOURNAL_FOREACH_FIELD', 'sd_journal_restart_fields'],
+ ''],
+ ['sd_journal_get_catalog', '3', ['sd_journal_get_catalog_for_message_id'], ''],
+ ['sd_journal_get_cursor', '3', ['sd_journal_test_cursor'], ''],
+ ['sd_journal_get_cutoff_realtime_usec',
+ '3',
+ ['sd_journal_get_cutoff_monotonic_usec'],
+ ''],
+ ['sd_journal_get_data',
+ '3',
+ ['SD_JOURNAL_FOREACH_DATA',
+ 'sd_journal_enumerate_data',
+ 'sd_journal_get_data_threshold',
+ 'sd_journal_restart_data',
+ 'sd_journal_set_data_threshold'],
+ ''],
+ ['sd_journal_get_fd',
+ '3',
+ ['SD_JOURNAL_APPEND',
+ 'SD_JOURNAL_INVALIDATE',
+ 'SD_JOURNAL_NOP',
+ 'sd_journal_get_events',
+ 'sd_journal_get_timeout',
+ 'sd_journal_process',
+ 'sd_journal_reliable_fd',
+ 'sd_journal_wait'],
+ ''],
+ ['sd_journal_get_realtime_usec', '3', ['sd_journal_get_monotonic_usec'], ''],
+ ['sd_journal_get_usage', '3', [], ''],
+ ['sd_journal_has_runtime_files', '3', ['sd_journal_has_persistent_files'], ''],
+ ['sd_journal_next',
+ '3',
+ ['SD_JOURNAL_FOREACH',
+ 'SD_JOURNAL_FOREACH_BACKWARDS',
+ 'sd_journal_next_skip',
+ 'sd_journal_previous',
+ 'sd_journal_previous_skip'],
+ ''],
+ ['sd_journal_open',
+ '3',
+ ['SD_JOURNAL_CURRENT_USER',
+ 'SD_JOURNAL_LOCAL_ONLY',
+ 'SD_JOURNAL_OS_ROOT',
+ 'SD_JOURNAL_RUNTIME_ONLY',
+ 'SD_JOURNAL_SYSTEM',
+ 'sd_journal',
+ 'sd_journal_close',
+ 'sd_journal_open_directory',
+ 'sd_journal_open_directory_fd',
+ 'sd_journal_open_files',
+ 'sd_journal_open_files_fd'],
+ ''],
+ ['sd_journal_print',
+ '3',
+ ['SD_JOURNAL_SUPPRESS_LOCATION',
+ 'sd_journal_perror',
+ 'sd_journal_printv',
+ 'sd_journal_send',
+ 'sd_journal_sendv'],
+ ''],
+ ['sd_journal_query_unique',
+ '3',
+ ['SD_JOURNAL_FOREACH_UNIQUE',
+ 'sd_journal_enumerate_unique',
+ 'sd_journal_restart_unique'],
+ ''],
+ ['sd_journal_seek_head',
+ '3',
+ ['sd_journal_seek_cursor',
+ 'sd_journal_seek_monotonic_usec',
+ 'sd_journal_seek_realtime_usec',
+ 'sd_journal_seek_tail'],
+ ''],
+ ['sd_journal_stream_fd', '3', [], ''],
+ ['sd_listen_fds',
+ '3',
+ ['SD_LISTEN_FDS_START', 'sd_listen_fds_with_names'],
+ ''],
+ ['sd_login_monitor_new',
+ '3',
+ ['sd_login_monitor',
+ 'sd_login_monitor_flush',
+ 'sd_login_monitor_get_events',
+ 'sd_login_monitor_get_fd',
+ 'sd_login_monitor_get_timeout',
+ 'sd_login_monitor_unref',
+ 'sd_login_monitor_unrefp'],
+ 'HAVE_PAM'],
+ ['sd_machine_get_class', '3', ['sd_machine_get_ifindices'], ''],
+ ['sd_notify',
+ '3',
+ ['sd_notifyf', 'sd_pid_notify', 'sd_pid_notify_with_fds', 'sd_pid_notifyf'],
+ ''],
+ ['sd_pid_get_session',
+ '3',
+ ['sd_peer_get_cgroup',
+ 'sd_peer_get_machine_name',
+ 'sd_peer_get_owner_uid',
+ 'sd_peer_get_session',
+ 'sd_peer_get_slice',
+ 'sd_peer_get_unit',
+ 'sd_peer_get_user_slice',
+ 'sd_peer_get_user_unit',
+ 'sd_pid_get_cgroup',
+ 'sd_pid_get_machine_name',
+ 'sd_pid_get_owner_uid',
+ 'sd_pid_get_slice',
+ 'sd_pid_get_unit',
+ 'sd_pid_get_user_slice',
+ 'sd_pid_get_user_unit'],
+ 'HAVE_PAM'],
+ ['sd_seat_get_active',
+ '3',
+ ['sd_seat_can_graphical',
+ 'sd_seat_can_multi_session',
+ 'sd_seat_can_tty',
+ 'sd_seat_get_sessions'],
+ 'HAVE_PAM'],
+ ['sd_session_is_active',
+ '3',
+ ['sd_session_get_class',
+ 'sd_session_get_desktop',
+ 'sd_session_get_display',
+ 'sd_session_get_remote_host',
+ 'sd_session_get_remote_user',
+ 'sd_session_get_seat',
+ 'sd_session_get_service',
+ 'sd_session_get_state',
+ 'sd_session_get_tty',
+ 'sd_session_get_type',
+ 'sd_session_get_uid',
+ 'sd_session_get_vt',
+ 'sd_session_is_remote'],
+ 'HAVE_PAM'],
+ ['sd_uid_get_state',
+ '3',
+ ['sd_uid_get_display',
+ 'sd_uid_get_seats',
+ 'sd_uid_get_sessions',
+ 'sd_uid_is_on_seat'],
+ 'HAVE_PAM'],
+ ['sd_watchdog_enabled', '3', [], ''],
+ ['shutdown', '8', [], ''],
+ ['sysctl.d', '5', [], ''],
+ ['systemctl', '1', [], ''],
+ ['systemd-analyze', '1', [], ''],
+ ['systemd-ask-password-console.service',
+ '8',
+ ['systemd-ask-password-console.path',
+ 'systemd-ask-password-wall.path',
+ 'systemd-ask-password-wall.service'],
+ ''],
+ ['systemd-ask-password', '1', [], ''],
+ ['systemd-backlight@.service', '8', ['systemd-backlight'], 'ENABLE_BACKLIGHT'],
+ ['systemd-binfmt.service', '8', ['systemd-binfmt'], 'ENABLE_BINFMT'],
+ ['systemd-cat', '1', [], ''],
+ ['systemd-cgls', '1', [], ''],
+ ['systemd-cgtop', '1', [], ''],
+ ['systemd-coredump',
+ '8',
+ ['systemd-coredump.socket', 'systemd-coredump@.service'],
+ 'ENABLE_COREDUMP'],
+ ['systemd-cryptsetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-cryptsetup@.service',
+ '8',
+ ['systemd-cryptsetup'],
+ 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-debug-generator', '8', [], ''],
+ ['systemd-delta', '1', [], ''],
+ ['systemd-detect-virt', '1', [], ''],
+ ['systemd-environment-d-generator',
+ '8',
+ ['30-systemd-environment-d-generator'],
+ 'ENABLE_ENVIRONMENT_D'],
+ ['systemd-escape', '1', [], ''],
+ ['systemd-firstboot', '1', ['systemd-firstboot.service'], 'ENABLE_FIRSTBOOT'],
+ ['systemd-fsck@.service',
+ '8',
+ ['systemd-fsck', 'systemd-fsck-root.service'],
+ ''],
+ ['systemd-fstab-generator', '8', [], ''],
+ ['systemd-getty-generator', '8', [], ''],
+ ['systemd-gpt-auto-generator', '8', [], ''],
+ ['systemd-halt.service',
+ '8',
+ ['systemd-kexec.service',
+ 'systemd-poweroff.service',
+ 'systemd-reboot.service',
+ 'systemd-shutdown'],
+ ''],
+ ['systemd-hibernate-resume-generator', '8', [], 'ENABLE_HIBERNATE'],
+ ['systemd-hibernate-resume@.service',
+ '8',
+ ['systemd-hibernate-resume'],
+ 'ENABLE_HIBERNATE'],
+ ['systemd-hostnamed.service', '8', ['systemd-hostnamed'], 'ENABLE_HOSTNAMED'],
+ ['systemd-hwdb', '8', [], 'ENABLE_HWDB'],
+ ['systemd-importd.service', '8', ['systemd-importd'], 'ENABLE_IMPORTD'],
+ ['systemd-inhibit', '1', [], ''],
+ ['systemd-initctl.service',
+ '8',
+ ['systemd-initctl', 'systemd-initctl.socket'],
+ ''],
+ ['systemd-journal-gatewayd.service',
+ '8',
+ ['systemd-journal-gatewayd', 'systemd-journal-gatewayd.socket'],
+ 'HAVE_MICROHTTPD'],
+ ['systemd-journal-remote', '8', [], 'HAVE_MICROHTTPD'],
+ ['systemd-journal-upload', '8', [], 'HAVE_MICROHTTPD'],
+ ['systemd-journald.service',
+ '8',
+ ['systemd-journald',
+ 'systemd-journald-audit.socket',
+ 'systemd-journald-dev-log.socket',
+ 'systemd-journald.socket'],
+ ''],
+ ['systemd-localed.service', '8', ['systemd-localed'], 'ENABLE_LOCALED'],
+ ['systemd-logind.service', '8', ['systemd-logind'], 'ENABLE_LOGIND'],
+ ['systemd-machine-id-commit.service', '8', [], ''],
+ ['systemd-machine-id-setup', '1', [], ''],
+ ['systemd-machined.service', '8', ['systemd-machined'], 'ENABLE_MACHINED'],
+ ['systemd-modules-load.service', '8', ['systemd-modules-load'], 'HAVE_KMOD'],
+ ['systemd-mount', '1', ['systemd-umount'], ''],
+ ['systemd-networkd-wait-online.service',
+ '8',
+ ['systemd-networkd-wait-online'],
+ 'ENABLE_NETWORKD'],
+ ['systemd-networkd.service', '8', ['systemd-networkd'], 'ENABLE_NETWORKD'],
+ ['systemd-notify', '1', [], ''],
+ ['systemd-nspawn', '1', [], ''],
+ ['systemd-path', '1', [], ''],
+ ['systemd-quotacheck.service',
+ '8',
+ ['systemd-quotacheck'],
+ 'ENABLE_QUOTACHECK'],
+ ['systemd-random-seed.service',
+ '8',
+ ['systemd-random-seed'],
+ 'ENABLE_RANDOMSEED'],
+ ['systemd-remount-fs.service', '8', ['systemd-remount-fs'], ''],
+ ['systemd-resolve', '1', [], 'ENABLE_RESOLVED'],
+ ['systemd-resolved.service', '8', ['systemd-resolved'], 'ENABLE_RESOLVED'],
+ ['systemd-rfkill.service',
+ '8',
+ ['systemd-rfkill', 'systemd-rfkill.socket'],
+ 'ENABLE_RFKILL'],
+ ['systemd-run', '1', [], ''],
+ ['systemd-sleep.conf', '5', ['sleep.conf.d'], ''],
+ ['systemd-socket-activate', '1', [], ''],
+ ['systemd-socket-proxyd', '8', [], ''],
+ ['systemd-suspend.service',
+ '8',
+ ['systemd-hibernate.service',
+ 'systemd-hybrid-sleep.service',
+ 'systemd-sleep'],
+ ''],
+ ['systemd-sysctl.service', '8', ['systemd-sysctl'], ''],
+ ['systemd-system-update-generator', '8', [], ''],
+ ['systemd-system.conf',
+ '5',
+ ['system.conf.d', 'systemd-user.conf', 'user.conf.d'],
+ ''],
+ ['systemd-sysusers', '8', ['systemd-sysusers.service'], ''],
+ ['systemd-sysv-generator', '8', [], 'HAVE_SYSV_COMPAT'],
+ ['systemd-timedated.service', '8', ['systemd-timedated'], 'ENABLE_TIMEDATED'],
+ ['systemd-timesyncd.service', '8', ['systemd-timesyncd'], 'ENABLE_TIMESYNCD'],
+ ['systemd-tmpfiles',
+ '8',
+ ['systemd-tmpfiles-clean.service',
+ 'systemd-tmpfiles-clean.timer',
+ 'systemd-tmpfiles-setup-dev.service',
+ 'systemd-tmpfiles-setup.service'],
+ ''],
+ ['systemd-tty-ask-password-agent', '1', [], ''],
+ ['systemd-udevd.service',
+ '8',
+ ['systemd-udevd',
+ 'systemd-udevd-control.socket',
+ 'systemd-udevd-kernel.socket'],
+ ''],
+ ['systemd-update-done.service', '8', ['systemd-update-done'], ''],
+ ['systemd-update-utmp.service',
+ '8',
+ ['systemd-update-utmp', 'systemd-update-utmp-runlevel.service'],
+ 'HAVE_UTMP'],
+ ['systemd-user-sessions.service', '8', ['systemd-user-sessions'], 'HAVE_PAM'],
+ ['systemd-vconsole-setup.service',
+ '8',
+ ['systemd-vconsole-setup'],
+ 'ENABLE_VCONSOLE'],
+ ['systemd-veritysetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-veritysetup@.service',
+ '8',
+ ['systemd-veritysetup'],
+ 'HAVE_LIBCRYPTSETUP'],
+ ['systemd-volatile-root.service', '8', ['systemd-volatile-root'], ''],
+ ['systemd', '1', ['init'], ''],
+ ['systemd.automount', '5', [], ''],
+ ['systemd.device', '5', [], ''],
+ ['systemd.environment-generator', '7', [], 'ENABLE_ENVIRONMENT_D'],
+ ['systemd.exec', '5', [], ''],
+ ['systemd.generator', '7', [], ''],
+ ['systemd.journal-fields', '7', [], ''],
+ ['systemd.kill', '5', [], ''],
+ ['systemd.link', '5', [], ''],
+ ['systemd.mount', '5', [], ''],
+ ['systemd.netdev', '5', [], 'ENABLE_NETWORKD'],
+ ['systemd.network', '5', [], 'ENABLE_NETWORKD'],
+ ['systemd.nspawn', '5', [], ''],
+ ['systemd.offline-updates', '7', [], ''],
+ ['systemd.path', '5', [], ''],
+ ['systemd.preset', '5', [], ''],
+ ['systemd.resource-control', '5', [], ''],
+ ['systemd.scope', '5', [], ''],
+ ['systemd.service', '5', [], ''],
+ ['systemd.slice', '5', [], ''],
+ ['systemd.socket', '5', [], ''],
+ ['systemd.special', '7', [], ''],
+ ['systemd.swap', '5', [], ''],
+ ['systemd.target', '5', [], ''],
+ ['systemd.time', '7', [], ''],
+ ['systemd.timer', '5', [], ''],
+ ['systemd.unit', '5', [], ''],
+ ['sysusers.d', '5', [], 'ENABLE_SYSUSERS'],
+ ['telinit', '8', [], ''],
+ ['timedatectl', '1', [], 'ENABLE_TIMEDATED'],
+ ['timesyncd.conf', '5', ['timesyncd.conf.d'], 'ENABLE_TIMESYNCD'],
+ ['tmpfiles.d', '5', [], ''],
+ ['udev', '7', [], ''],
+ ['udev.conf', '5', [], ''],
+ ['udev_device_get_syspath',
+ '3',
+ ['udev_device_get_action',
+ 'udev_device_get_devnode',
+ 'udev_device_get_devnum',
+ 'udev_device_get_devpath',
+ 'udev_device_get_devtype',
+ 'udev_device_get_driver',
+ 'udev_device_get_is_initialized',
+ 'udev_device_get_parent',
+ 'udev_device_get_parent_with_subsystem_devtype',
+ 'udev_device_get_subsystem',
+ 'udev_device_get_sysname',
+ 'udev_device_get_sysnum',
+ 'udev_device_get_udev'],
+ ''],
+ ['udev_device_has_tag',
+ '3',
+ ['udev_device_get_devlinks_list_entry',
+ 'udev_device_get_properties_list_entry',
+ 'udev_device_get_property_value',
+ 'udev_device_get_sysattr_list_entry',
+ 'udev_device_get_sysattr_value',
+ 'udev_device_get_tags_list_entry',
+ 'udev_device_set_sysattr_value'],
+ ''],
+ ['udev_device_new_from_syspath',
+ '3',
+ ['udev_device_new_from_device_id',
+ 'udev_device_new_from_devnum',
+ 'udev_device_new_from_environment',
+ 'udev_device_new_from_subsystem_sysname',
+ 'udev_device_ref',
+ 'udev_device_unref'],
+ ''],
+ ['udev_enumerate_add_match_subsystem',
+ '3',
+ ['udev_enumerate_add_match_is_initialized',
+ 'udev_enumerate_add_match_parent',
+ 'udev_enumerate_add_match_property',
+ 'udev_enumerate_add_match_sysattr',
+ 'udev_enumerate_add_match_sysname',
+ 'udev_enumerate_add_match_tag',
+ 'udev_enumerate_add_nomatch_subsystem',
+ 'udev_enumerate_add_nomatch_sysattr'],
+ ''],
+ ['udev_enumerate_new',
+ '3',
+ ['udev_enumerate_ref', 'udev_enumerate_unref'],
+ ''],
+ ['udev_enumerate_scan_devices',
+ '3',
+ ['udev_enumerate_add_syspath',
+ 'udev_enumerate_get_list_entry',
+ 'udev_enumerate_get_udev',
+ 'udev_enumerate_scan_subsystems'],
+ ''],
+ ['udev_list_entry',
+ '3',
+ ['udev_list_entry_get_by_name',
+ 'udev_list_entry_get_name',
+ 'udev_list_entry_get_next',
+ 'udev_list_entry_get_value'],
+ ''],
+ ['udev_monitor_filter_update',
+ '3',
+ ['udev_monitor_filter_add_match_subsystem_devtype',
+ 'udev_monitor_filter_add_match_tag',
+ 'udev_monitor_filter_remove'],
+ ''],
+ ['udev_monitor_new_from_netlink',
+ '3',
+ ['udev_monitor_ref', 'udev_monitor_unref'],
+ ''],
+ ['udev_monitor_receive_device',
+ '3',
+ ['udev_monitor_enable_receiving',
+ 'udev_monitor_get_fd',
+ 'udev_monitor_get_udev',
+ 'udev_monitor_set_receive_buffer_size'],
+ ''],
+ ['udev_new', '3', ['udev_ref', 'udev_unref'], ''],
+ ['udevadm', '8', [], ''],
+ ['vconsole.conf', '5', [], 'ENABLE_VCONSOLE']
+]
+# Really, do not edit.
<title>Description</title>
<para>
- <function>sd_bus_add_match()</function> adds a match rule used to dispatch
- incoming messages. The syntax of the rule passed in
- <parameter>match</parameter> is described in the
- <ulink url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus Specification</ulink>.
+ <function>sd_bus_add_match()</function> installs a match rule for incoming messages received on the specified bus
+ connection object <parameter>bus</parameter>. The syntax of the match rule expression passed in
+ <parameter>match</parameter> is described in the <ulink
+ url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus Specification</ulink>. The specified handler
+ function <parameter>callback</parameter> is called for eaching incoming message matching the specified
+ expression, the <parameter>userdata</parameter> parameter is passed as-is to the callback function.
</para>
<para>
- The message <parameter>m</parameter> passed to the callback is only
- borrowed, that is, the callback should not call
- <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- on it. If the callback wants to hold on to the message beyond the lifetime
- of the callback, it needs to call
- <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- to create a new reference.
+ On success, and if non-<constant>NULL</constant>, the <parameter>slot</parameter> return parameter will be set to
+ a slot object that may be used as a reference to the installed match, and may be utilized to remove it again at a
+ later time with
+ <citerefentry><refentrytitle>sd_bus_slot_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
+ specified as <constant>NULL</constant> the lifetime of the match is bound to the lifetime of the bus object itself, and the match
+ cannot be removed independently.
</para>
<para>
- If an error occurs during the callback invocation, the callback should
- return a negative error number. If it wants other callbacks that match the
- same rule to be called, it should return 0. Otherwise it should return a
+ The message <parameter>m</parameter> passed to the callback is only borrowed, that is, the callback should not
+ call <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry> on
+ it. If the callback wants to hold on to the message beyond the lifetime of the callback, it needs to call
+ <citerefentry><refentrytitle>sd_bus_message_ref</refentrytitle><manvolnum>3</manvolnum></citerefentry> to create
+ a new reference.
+ </para>
+
+ <para>
+ If an error occurs during the callback invocation, the callback should return a negative error number. If it
+ wants other callbacks that match the same rule to be called, it should return 0. Otherwise it should return a
positive integer.
</para>
</refsect1>
<title>Return Value</title>
<para>
- On success, <function>sd_bus_add_match()</function> returns 0 or a
- positive integer. On failure, it returns a negative errno-style error
- code.
+ On success, <function>sd_bus_add_match()</function> returns 0 or a positive integer. On failure, it returns a
+ negative errno-style error code.
</para>
</refsect1>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
<parameter>dst</parameter> using the values in
<parameter>e</parameter>. If the strings in
<parameter>e</parameter> were set using
- <function>sd_bus_set_error_const()</function>, they will be shared.
+ <function>sd_bus_error_set_const()</function>, they will be shared.
Otherwise, they will be copied. Returns a converted
<varname>errno</varname>-like, negative error code.</para>
<refnamediv>
<refname>sd_bus_message_append</refname>
+ <refname>sd_bus_message_appendv</refname>
<refpurpose>Attach fields to a D-Bus message based on a type
string</refpurpose>
<paramdef>const char *<parameter>types</parameter></paramdef>
<paramdef>…</paramdef>
</funcprototype>
+
+ <funcprototype>
+ <funcdef>int sd_bus_message_appendv</funcdef>
+ <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+ <paramdef>const char *<parameter>types</parameter></paramdef>
+ <paramdef>va_list <parameter>ap</parameter></paramdef>
+ </funcprototype>
+
</funcsynopsis>
</refsynopsisdiv>
values for each entry matching the element type of
the dictionary entries.</para>
+ <para>The <function>sd_bus_message_appendv()</function> is equivalent to
+ the function <function>sd_bus_message_append()</function>,
+ except that it is called with a <literal>va_list</literal> instead of
+ a variable number of arguments. This function does not call the
+ <function>va_end()</function> macro. Because it invokes the
+ <function>va_arg()</function> macro, the value of ap
+ is undefined after the call.</para>
+
<para>For further details on the D-Bus type system, please consult
the <ulink
url="http://dbus.freedesktop.org/doc/dbus-specification.html#type-system">D-Bus
<refsect1>
<title>Return Value</title>
- <para>On success, this call returns 0 or a positive
- integer. On failure, this call returns a negative
+ <para>On success, these functions return 0 or a positive
+ integer. On failure, these functions return a negative
errno-style error code.</para>
</refsect1>
<title>Description</title>
<para><function>sd_get_seats()</function> may be used to determine
- all currently available local seats. Returns a
- <constant>NULL</constant> terminated array of seat identifiers.
+ all currently available local seats. Returns the number of seat
+ identifiers and if the input pointer is non-NULL, a
+ <constant>NULL</constant>-terminated array of seat identifiers
+ is stored at the address.
The returned array and all strings it references need to be freed
with the libc
<citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<variablelist>
- <varlistentry>
- <term><constant>-EINVAL</constant></term>
-
- <listitem><para>An input parameter was invalid (out of range,
- or NULL, where that is not accepted).</para></listitem>
- </varlistentry>
-
<varlistentry>
<term><constant>-ENOMEM</constant></term>
<citerefentry><refentrytitle>sd-id128</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para><citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
- <option>--new-id</option> option may be used as a command line
+ <option>--new-id128</option> option may be used as a command line
front-end for <function>sd_id128_randomize()</function>.</para>
</refsect1>
<para>Function <function>sd_journal_get_catalog()</function> is thread-agnostic and only a
single thread may operate on a given <structname>sd_journal</structname> object. Function
- <function>sd_journal_get_catalog_for_message_id() is thread-safe.</function></para>
+ <function>sd_journal_get_catalog_for_message_id()</function> is thread-safe.</para>
<para>The <function>sd_journal_get_catalog()</function> and
<function>sd_journal_get_catalog_for_message_id()</function>
else {
struct timespec ts;
uint64_t n;
- clock_getttime(CLOCK_MONOTONIC, &ts);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}</programlisting>
else {
struct timespec ts;
uint64_t n;
- clock_getttime(CLOCK_MONOTONIC, &ts);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}
else {
struct timespec ts;
uint64_t n;
- clock_getttime(CLOCK_MONOTONIC, &ts);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
}</programlisting>
<varlistentry>
<term>FDSTORE=1</term>
- <listitem><para>Stores additional file descriptors in the service manager. File
- descriptors sent this way will be maintained per-service by the service manager
- and will be passed again using the usual file descriptor passing logic on the next
- invocation of the service, see
- <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- This is useful for implementing service restart schemes where services serialize
- their state to <filename>/run</filename>, push their file descriptors to the
- system manager, and are then restarted, retrieving their state again via socket
- passing and <filename>/run</filename>. Note that the service manager will accept
- messages for a service only if <varname>FileDescriptorStoreMax=</varname> is set
- to non-zero for it (defaults to zero, see
- <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
- File descriptors must be pollable, see
- <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
- Multiple arrays of file descriptors may be sent in separate messages, in which
- case the arrays are combined. Note that the service manager removes duplicate
- file descriptors before passing them to the service. Use
- <function>sd_pid_notify_with_fds()</function> to send messages with
- <literal>FDSTORE=1</literal>, see below.</para></listitem>
+ <listitem><para>Stores additional file descriptors in the service manager. File descriptors sent this way will
+ be maintained per-service by the service manager and will later be handed back using the usual file descriptor
+ passing logic at the next invocation of the service, see
+ <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This is
+ useful for implementing services that can restart after an explicit request or a crash without losing
+ state. Any open sockets and other file descriptors which should not be closed during the restart may be stored
+ this way. Application state can either be serialized to a file in <filename>/run</filename>, or better, stored
+ in a <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory
+ file descriptor. Note that the service manager will accept messages for a service only if its
+ <varname>FileDescriptorStoreMax=</varname> setting is non-zero (defaults to zero, see
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>). If file
+ descriptors sent are pollable (see
+ <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>), then any
+ <constant>EPOLLHUP</constant> or <constant>EPOLLERR</constant> event seen on them will result in their
+ automatic removal from the store. Multiple arrays of file descriptors may be sent in separate messages, in
+ which case the arrays are combined. Note that the service manager removes duplicate (pointing to the same
+ object) file descriptors before passing them to the service. Use <function>sd_pid_notify_with_fds()</function>
+ to send messages with <literal>FDSTORE=1</literal>, see below.</para></listitem>
</varlistentry>
<varlistentry>
<refsect1>
<title>Return Value</title>
- <para>On failure, these calls return a negative errno-style error
- code. If <varname>$NOTIFY_SOCKET</varname> was not set and hence
- no status data could be sent, 0 is returned. If the status was
- sent, these functions return with a positive return value. In
- order to support both, init systems that implement this scheme and
- those which do not, it is generally recommended to ignore the
- return value of this call.</para>
+ <para>On failure, these calls return a negative errno-style error code. If <varname>$NOTIFY_SOCKET</varname> was
+ not set and hence no status message could be sent, 0 is returned. If the status was sent, these functions return a
+ positive value. In order to support both service managers that implement this scheme and those which do not, it is
+ generally recommended to ignore the return value of this call. Note that the return value simply indicates whether
+ the notification message was enqueued properly, it does not reflect whether the message could be processed
+ successfully. Specifically, no error is returned when a file descriptor is attempted to be stored using
+ <varname>FDSTORE=1</varname> but the service is not actually configured to permit storing of file descriptors (see
+ above).</para>
</refsect1>
<refsect1>
processes, user processes that are shared between multiple
sessions of the same user, or kernel threads). For processes not
being part of a login session, this function will fail with
- -ENODATA. The returned string needs to be freed with the libc
+ <constant>-ENODATA</constant>. The returned string needs to be freed with the libc
<citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>
paths. Note that not all processes are part of a system
unit/service (e.g. user processes, or kernel threads). For
processes not being part of a systemd system unit, this function
- will fail with -ENODATA. (More specifically, this call will not
+ will fail with <constant>-ENODATA</constant>. (More specifically, this call will not
work for kernel threads.) The returned string needs to be freed
with the libc <citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
multiple login sessions of the same user, whereas
<function>sd_pid_get_session()</function> will fail. For processes
not being part of a login session and not being a shared process
- of a user, this function will fail with -ENODATA.</para>
+ of a user, this function will fail with <constant>-ENODATA</constant>.</para>
<para><function>sd_pid_get_machine_name()</function> may be used
to determine the name of the VM or container is a member of. The
<citerefentry
project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use. For processes not part of a VM or containers, this
- function fails with -ENODATA.</para>
+ function fails with <constant>-ENODATA</constant>.</para>
<para><function>sd_pid_get_slice()</function> may be used to
determine the slice unit the process is a member of. See
</varlistentry>
<varlistentry>
- <term><constant>-BADF</constant></term>
+ <term><constant>-EBADF</constant></term>
<listitem><para>The specified socket file descriptor was
invalid.</para></listitem>
one (<constant>NULL</constant> terminated) with the session
identifiers of the sessions and one with the user identifiers of
the Unix users the sessions belong to. An additional parameter may
- be used to return the number of entries in the latter array. The
- two arrays and the latter parameter may be passed as
+ be used to return the number of entries in the latter array. This
+ value is the same the return value, if the latter is nonnegative.
+ The two arrays and the last parameter may be passed as
<constant>NULL</constant> in case these values need not to be
determined. The arrays and the strings referenced by them need to
be freed with the libc
<para><function>sd_session_get_seat()</function> may be used to
determine the seat identifier of the seat the session identified
by the specified session identifier belongs to. Note that not all
- sessions are attached to a seat, this call will fail for them. The
- returned string needs to be freed with the libc
+ sessions are attached to a seat, this call will fail (returning
+ <constant>-ENODATA</constant>) for them. The returned string needs
+ to be freed with the libc
<citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
call after use.</para>
<programlisting>$ systemctl status bluetooth
● bluetooth.service - Bluetooth service
- Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
+ Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2017-01-04 13:54:04 EST; 1 weeks 0 days ago
Docs: man:bluetoothd(8)
Main PID: 930 (bluetoothd)
<term><command>show-environment</command></term>
<listitem>
- <para>Dump the systemd manager environment block. The
- environment block will be dumped in straight-forward form
- suitable for sourcing into a shell script. This environment
- block will be passed to all processes the manager
- spawns.</para>
+ <para>Dump the systemd manager environment block. This is the environment
+ block that is passed to all processes the manager spawns. The environment
+ block will be dumped in straight-forward form suitable for sourcing into
+ most shells. If no special characters or whitespace is present in the variable
+ values, no escaping is performed, and the assignments have the form
+ <literal>VARIABLE=value</literal>. If whitespace or characters which have
+ special meaning to the shell are present, dollar-single-quote escaping is
+ used, and assignments have the form <literal>VARIABLE=$'value'</literal>.
+ This syntax is known to be supported by
+ <citerefentry project='die-net'><refentrytitle>bash</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>zsh</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>ksh</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ and
+ <citerefentry project='die-net'><refentrytitle>busybox</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+ <citerefentry project='die-net'><refentrytitle>ash</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ but not
+ <citerefentry project='die-net'><refentrytitle>dash</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ or
+ <citerefentry project='die-net'><refentrytitle>fish</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-ask-password-console.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd-tty-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-tty-ask-password-agent</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>keyctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>plymouth</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>wall</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<para>In order to by used in the <option>--backtrace</option> mode, an appropriate backtrace
handler must be installed on the sender side. For example, in case of
- <citerefentry><refentrytitle>python</refentrytitle><manvolnum>1</manvolnum></citerefentry>, this
+ <citerefentry project='die-net'><refentrytitle>python</refentrytitle><manvolnum>1</manvolnum></citerefentry>, this
means a <varname>sys.excepthook</varname> must installed, see
<ulink url="https://github.com/keszybz/systemd-coredump-python">systemd-coredump-python</ulink>.
</para>
compare configuration files that override other configuration
files. Files in <filename>/etc</filename> have highest priority,
files in <filename>/run</filename> have the second highest
- priority, …, files in <filename>/lib</filename> have lowest
+ priority, …, files in <filename>/usr/lib</filename> have lowest
priority. Files in a directory with higher priority override files
with the same name in directories of lower priority. In addition,
certain configuration files can have <literal>.d</literal>
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd-environment-d-generator">
+<refentry id="systemd-environment-d-generator" conditional='ENABLE_ENVIRONMENT_D'>
<refentryinfo>
<title>systemd-environment-d-generator</title>
for more information about special <filename>/etc/fstab</filename>
mount options this generator understands.</para>
+ <para>One special topic is handling of symbolic links. Historical init
+ implementations supported symlinks in <filename>/etc/fstab</filename>.
+ Because mount units will refuse mounts where the target is a symbolic link,
+ this generator will resolve any symlinks as far as possible when processing
+ <filename>/etc/fstab</filename> in order to enhance backwards compatibility.
+ If a symlink target does not exist at the time that this generator runs, it
+ is assumed that the symlink target is the final target of the mount.</para>
+
<para><filename>systemd-fstab-generator</filename> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect1>
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd-hibernate-resume-generator">
+<refentry id="systemd-hibernate-resume-generator" conditional='ENABLE_HIBERNATE'>
<refentryinfo>
<title>systemd-hibernate-resume-generator</title>
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd-hibernate-resume@.service">
+<refentry id="systemd-hibernate-resume@.service" conditional='ENABLE_HIBERNATE'>
<refentryinfo>
<title>systemd-hibernate-resume@.service</title>
<arg choice="plain"><option>--list</option></arg>
</cmdsynopsis>
<cmdsynopsis>
- <command>systemd-umount</command>
+ <command>systemd-mount</command>
<arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
- <arg choice="plain" rep="repeat"><replaceable>WHERE</replaceable></arg>
+ <arg choice="plain"><option>--umount</option></arg>
+ <arg choice="plain" rep="repeat"><replaceable>WHAT|WHERE</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<replaceable>WHERE</replaceable>.</para>
<para>In many ways, <command>systemd-mount</command> is similar to the lower-level
- <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> command, however instead
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> command, however instead
of executing the mount operation directly and immediately, <command>systemd-mount</command> schedules it through
the service manager job queue, so that it may pull in further dependencies (such as parent mounts, or a file system
checker to execute a priori), and may make use of the auto-mounting logic.</para>
<para>The command takes either one or two arguments. If only one argument is specified it should refer to a block
- device containing a file system (e.g. <literal>/dev/sdb1</literal>), which is then probed for a label and other
+ device or regular file containing a file system (e.g. <literal>/dev/sdb1</literal> or
+ <literal>/path/to/disk.img</literal>). If it is a block device, which is then probed for a label and other
metadata, and is mounted to a directory whose name is generated from the label. In this mode the block device must
exist at the time of invocation of the command, so that it may be probed. If the device is found to be a removable
block device (e.g. a USB stick) an automount point instead of a regular mount point is created (i.e. the
<term><option>--umount</option></term>
<listitem><para>Stop the mount and automount units corresponding to the specified mount points
- <replaceable>WHERE</replaceable>.</para>
- </listitem>
+ <replaceable>WHERE</replaceable> or the devices <replaceable>WHAT</replaceable>.
+ <command>systemd-mount</command> with this option or <command>systemd-umount</command> can take multiple arguments
+ which can be mount points, devices, <filename>/etc/fstab</filename> style node names, or backing files
+ corresponding to loop devices, like
+ <command>systemd-mount --umount /path/to/umount /dev/sda1 UUID=xxxxxx-xxxx LABEL=xxxxx /path/to/disk.img</command>.
+ Note that when <option>-H</option> or <option>-M</option> is specified, only absolute paths to mount points are
+ supported.</para></listitem>
</varlistentry>
<xi:include href="user-system-options.xml" xpointer="user" />
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<varlistentry>
<term><option>--slice=</option></term>
- <listitem><para>Make the container part of the specified
- slice, instead of the default
- <filename>machine.slice</filename>. This is only applies if
- the machine is run in its own scope unit, i.e. if
- <option>--keep-unit</option> is not used.</para>
+ <listitem><para>Make the container part of the specified slice, instead of the default
+ <filename>machine.slice</filename>. This applies only if the machine is run in its own scope unit, i.e. if
+ <option>--keep-unit</option> isn't used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--property=</option></term>
- <listitem><para>Set a unit property on the scope unit to
- register for the machine. This only applies if the machine is
- run in its own scope unit, i.e. if
- <option>--keep-unit</option> is not used. Takes unit property
- assignments in the same format as <command>systemctl
- set-property</command>. This is useful to set memory limits
- and similar for machines.</para>
+ <listitem><para>Set a unit property on the scope unit to register for the machine. This applies only if the
+ machine is run in its own scope unit, i.e. if <option>--keep-unit</option> isn't used. Takes unit property
+ assignments in the same format as <command>systemctl set-property</command>. This is useful to set memory
+ limits and similar for container.</para>
</listitem>
</varlistentry>
broadcast domain, here called a "zone". Each container may only be part of one zone, but each zone may contain
any number of containers. Each zone is referenced by its name. Names may be chosen freely (as long as they form
valid network interface names when prefixed with <literal>vz-</literal>), and it is sufficient to pass the same
- name to the <option>--network-zones=</option> switch of the various concurrently running containers to join
+ name to the <option>--network-zone=</option> switch of the various concurrently running containers to join
them in one zone.</para>
<para>Note that
<varlistentry>
<term><option>--register=</option></term>
- <listitem><para>Controls whether the container is registered
- with
- <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
- Takes a boolean argument, which defaults to <literal>yes</literal>.
- This option should be enabled when the container runs a full
- Operating System (more specifically: an init system), and is
- useful to ensure that the container is accessible via
- <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- and shown by tools such as
- <citerefentry project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
- If the container does not run an init system, it is
- recommended to set this option to <literal>no</literal>.</para></listitem>
+ <listitem><para>Controls whether the container is registered with
+ <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Takes a
+ boolean argument, which defaults to <literal>yes</literal>. This option should be enabled when the container
+ runs a full Operating System (more specifically: a system and service manager as PID 1), and is useful to
+ ensure that the container is accessible via
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> and shown by
+ tools such as <citerefentry
+ project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If the container
+ does not run a service manager, it is recommended to set this option to
+ <literal>no</literal>.</para></listitem>
</varlistentry>
<varlistentry>
service unit, and the service unit's sole purpose is to run a
single <command>systemd-nspawn</command> container. This
option is not available if run from a user
- session.</para></listitem>
+ session.</para>
+ <para>Note that passing <option>--keep-unit</option> disables the effect of <option>--slice=</option> and
+ <option>--property=</option>.</para></listitem>
</varlistentry>
<varlistentry>
in a namespace container in it.</para>
</example>
+ <example>
+ <title>Install the OpenSUSE Tumbleweed rolling distribution</title>
+
+ <programlisting># zypper --root=/var/lib/machines/tumbleweed ar -c \
+ https://download.opensuse.org/tumbleweed/repo/oss tumbleweed
+# zypper --root=/var/lib/machines/tumbleweed refresh
+# zypper --root=/var/lib/machines/tumbleweed install --no-recommends \
+ systemd shadow zypper openSUSE-release vim
+# systemd-nspawn -M tumbleweed passwd root
+# systemd-nspawn -M tumbleweed -b</programlisting>
+ </example>
+
<example>
<title>Boot into an ephemeral snapshot of the host system</title>
<citerefentry project='mankier'><refentrytitle>dnf</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='archlinux'><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry project='mankier'><refentrytitle>zypper</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>btrfs</refentrytitle><manvolnum>8</manvolnum></citerefentry>
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd-resolve"
+<refentry id="systemd-resolve" conditional='ENABLE_RESOLVED'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
reboots to ensure it monotonically advances even if the system
lacks a battery-buffered RTC chip.</para>
+ <para>The <filename>systemd-timesyncd</filename> service
+ specifically implements only SNTP. This minimalistic
+ service will set the system clock for large offsets or
+ slowly adjust it for smaller deltas. More complex use
+ cases are not covered by <filename>systemd-timesyncd</filename>.</para>
+
<para>The NTP servers contacted are determined from the global
settings in
<citerefentry><refentrytitle>timesyncd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<para><filename>systemd-vconsole-setup</filename> is a helper used to prepare either all virtual consoles, or — if
the optional <replaceable>TTY</replaceable> parameter is provided — a specific one. When the system is booting up
- it's called by <citerefentry><command>udev</command></citerefentry> during vtconsole subsystem initialization.
+ it's called by <citerefentry><refentrytitle>systemd-udevd</refentrytitle><manvolnum>8</manvolnum></citerefentry> during vtconsole subsystem initialization.
<productname>Systemd</productname> also calls it internally as needed via
<filename>systemd-vconsole-setup.service</filename>. The helper calls
<citerefentry project='mankier'><refentrytitle>loadkeys</refentrytitle><manvolnum>1</manvolnum></citerefentry> and
along with systemd; If not, see <http://www.gnu.org/licenses/>.
-->
-<refentry id="systemd.environment-generator" xmlns:xi="http://www.w3.org/2001/XInclude">
+<refentry id="systemd.environment-generator" conditional='ENABLE_ENVIRONMENT_D'
+ xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd.environment-generator</title>
<productname>systemd</productname>
<varlistentry>
<term><varname>RootImage=</varname></term>
<listitem><para>Takes a path to a block device node or regular file as argument. This call is similar to
- <varname>RootDirectory=</varname> however mounts a file system hierarchy from a block device node or loopack
+ <varname>RootDirectory=</varname> however mounts a file system hierarchy from a block device node or loopback
file instead of a directory. The device node or file system image file needs to contain a file system without a
partition table, or a file system within an MBR/MS-DOS or GPT partition table with only a single
Linux-compatible partition, or a set of file systems within a GPT partition table that follows the <ulink
<term><varname>Group=</varname></term>
<listitem><para>Set the UNIX user or group that the processes are executed as, respectively. Takes a single
- user or group name, or numeric ID as argument. For system services (services run by the system service manager,
+ user or group name, or a numeric ID as argument. For system services (services run by the system service manager,
i.e. managed by PID 1) and for user services of the root user (services managed by root's instance of
<command>systemd --user</command>), the default is <literal>root</literal>, but <varname>User=</varname> may be
used to specify a different user. For user services of any other user, switching user identity is not
permitted, hence the only valid setting is the same user the user's service manager is running as. If no group
is set, the default group of the user is used. This setting does not affect commands whose command line is
- prefixed with <literal>+</literal>.</para></listitem>
+ prefixed with <literal>+</literal>.</para>
+
+ <para>Note that restrictions on the user/group name syntax are enforced: the specified name must consist only
+ of the characters a-z, A-Z, 0-9, <literal>_</literal> and <literal>-</literal>, except for the first character
+ which must be one of a-z, A-Z or <literal>_</literal> (i.e. numbers and <literal>-</literal> are not permitted
+ as first character). The user/group name must have at least one character, and at most 31. These restrictions
+ are enforced in order to avoid ambiguities and to ensure user/group names and unit files remain portable among
+ Linux systems.</para>
+
+ <para>When used in conjunction with <varname>DynamicUser=</varname> the user/group name specified is
+ dynamically allocated at the time the service is started, and released at the time the service is stopped —
+ unless it is already allocated statically (see below). If <varname>DynamicUser=</varname> is not used the
+ specified user and group must have been created statically in the user database no later than the moment the
+ service is started, for example using the
+ <citerefentry><refentrytitle>sysusers.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> facility, which
+ is applied at boot or package install time.</para></listitem>
</varlistentry>
<varlistentry>
assignments have no effect. Variable expansion is not
performed inside the strings, however, specifier expansion is
possible. The $ character has no special meaning. If you need
- to assign a value containing spaces to a variable, use double
+ to assign a value containing spaces or the equals sign to a variable, use double
quotes (") for the assignment.</para>
<para>Example:
<varname>After=</varname> dependencies on all mount units necessary to access <filename>/tmp</filename> and
<filename>/var/tmp</filename>. Moreover an implicitly <varname>After=</varname> ordering on
<citerefentry><refentrytitle>systemd-tmpfiles-setup.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- is added.</para></listitem>
+ is added.</para>
+
+ <para>Note that the implementation of this setting might be impossible (for example if mount namespaces
+ are not available), and the unit should be written in a way that does not solely rely on this setting for
+ security.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>PrivateDevices=</varname></term>
- <listitem><para>Takes a boolean argument. If true, sets up a new /dev namespace for the executed processes and
- only adds API pseudo devices such as <filename>/dev/null</filename>, <filename>/dev/zero</filename> or
+ <listitem><para>Takes a boolean argument. If true, sets up a new <filename>/dev</filename> mount for the
+ executed processes and only adds API pseudo devices such as <filename>/dev/null</filename>,
+ <filename>/dev/zero</filename> or
<filename>/dev/random</filename> (as well as the pseudo TTY subsystem) to it, but no physical devices such as
<filename>/dev/sda</filename>, system memory <filename>/dev/mem</filename>, system ports
<filename>/dev/port</filename> and others. This is useful to securely turn off physical device access by the
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details). Note that using this setting will disconnect propagation of mounts from the service to the host
(propagation in the opposite direction continues to work). This means that this setting may not be used for
- services which shall be able to install mount points in the main mount namespace. The /dev namespace will be
- mounted read-only and 'noexec'. The latter may break old programs which try to set up executable memory by
+ services which shall be able to install mount points in the main mount namespace. The new <filename>/dev</filename>
+ will be mounted read-only and 'noexec'. The latter may break old programs which try to set up executable memory by
using <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> of
<filename>/dev/zero</filename> instead of using <constant>MAP_ANON</constant>. This setting is implied if
<varname>DynamicUser=</varname> is set. For this setting the same restrictions regarding mount propagation and
If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
is implied.
- </para></listitem>
+ </para>
+
+ <para>Note that the implementation of this setting might be impossible (for example if mount namespaces
+ are not available), and the unit should be written in a way that does not solely rely on this setting for
+ security.</para></listitem>
</varlistentry>
<varlistentry>
configures only the loopback network device
<literal>lo</literal> inside it. No other network devices will
be available to the executed process. This is useful to
- securely turn off network access by the executed process.
+ turn off network access by the executed process.
Defaults to false. It is possible to run two or more units
within the same private network namespace by using the
<varname>JoinsNamespaceOf=</varname> directive, see
The latter has the effect that AF_UNIX sockets in the abstract
socket namespace will become unavailable to the processes
(however, those located in the file system will continue to be
- accessible).</para></listitem>
+ accessible).</para>
+
+ <para>Note that the implementation of this setting might be impossible (for example if network namespaces
+ are not available), and the unit should be written in a way that does not solely rely on this setting for
+ security.</para></listitem>
</varlistentry>
<varlistentry>
<para>This setting is particularly useful in conjunction with
<varname>RootDirectory=</varname>/<varname>RootImage=</varname>, as the need to synchronize the user and group
databases in the root directory and on the host is reduced, as the only users and groups who need to be matched
- are <literal>root</literal>, <literal>nobody</literal> and the unit's own user and group.</para></listitem>
+ are <literal>root</literal>, <literal>nobody</literal> and the unit's own user and group.</para>
+
+ <para>Note that the implementation of this setting might be impossible (for example if user namespaces
+ are not available), and the unit should be written in a way that does not solely rely on this setting for
+ security.</para></listitem>
</varlistentry>
<varlistentry>
<listitem><para>Restricts access to Linux namespace functionality for the processes of this unit. For details
about Linux namespaces, see
- <citerefentry><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Either takes a
+ <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Either takes a
boolean argument, or a space-separated list of namespace type identifiers. If false (the default), no
restrictions on namespace creation and switching are made. If true, access to any kind of namespacing is
prohibited. Otherwise, a space-separated list of namespace type identifiers must be specified, consisting of
the specified flags parameters into account. Note that — if this option is used — in addition to restricting
creation and switching of the specified types of namespaces (or all of them, if true) access to the
<function>setns()</function> system call with a zero flags parameter is prohibited. This setting is only
- supported on x86, x86-64, s390 and s390x, and enforces no restrictions on other architectures. If running in user
+ supported on x86, x86-64, mips, mips-le, mips64, mips64-le, mips64-n32, mips64-le-n32, ppc64, ppc64-le,
+ s390 and s390x, and enforces no restrictions on other architectures. If running in user
mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. setting
<varname>User=</varname>), <varname>NoNewPrivileges=yes</varname> is implied. </para></listitem>
</varlistentry>
<varlistentry>
<term><varname>RuntimeDirectory=</varname></term>
- <term><varname>RuntimeDirectoryMode=</varname></term>
<listitem><para>Takes a list of directory names. If set, one
or more directories by the specified names will be created
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>RuntimeDirectoryMode=</varname></term>
+
+ <listitem><para>Specifies the access mode of the directories specified in
+ <varname>RuntimeDirectory=</varname> as an octal number. Defaults to
+ <constant>0755</constant>. See "Permissions" in
+ <citerefentry project='man-pages'><refentrytitle>path_resolution</refentrytitle><manvolnum>7</manvolnum></citerefentry> for a discussion of the meaning of permission bits.
+ </para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>MemoryDenyWriteExecute=</varname></term>
<citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
<constant>PROT_EXEC</constant> set and
<citerefentry><refentrytitle>shmat</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with
- <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs that generate program
- code dynamically at runtime, such as JIT execution engines, or programs compiled making use of the code
+ <constant>SHM_EXEC</constant> set. Note that this option is incompatible with programs and libraries that
+ generate program code dynamically at runtime, including JIT execution engines, executable stacks, and code
"trampoline" feature of various C compilers. This option improves service security, as it makes harder for
software exploits to change running code dynamically. Note that this feature is fully available on x86-64, and
partially on x86. Specifically, the <function>shmat()</function> protection is not available on x86. Note that
recommended to be a UUID-compatible ID, but this is not
enforced, and formatted differently. Developers can generate
a new ID for this purpose with <command>journalctl
- <option>--new-id</option></command>.
+ <option>--new-id128</option></command>.
</para>
</listitem>
</varlistentry>
<listitem>
<para>The process, user, and group ID of the process the
journal entry originates from formatted as a decimal
- string.</para>
+ string. Note that entries obtained via <literal>stdout</literal> or
+ <literal>stderr</literal> of forked processes will contain credentials valid for a parent
+ process (that initiated the connection to <command>systemd-journald</command>).</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>Port=</varname></term>
+ <listitem>
+ <para>The port option is used to select the device port. The
+ supported values are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>tp</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Twisted-Pair cable as the medium.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>aui</literal></term>
+ <listitem>
+ <para>Attachment Unit Interface (AUI). Normally used with hubs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>bnc</literal></term>
+ <listitem>
+ <para>An Ethernet interface using BNC connectors and co-axial cable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>mii</literal></term>
+ <listitem>
+ <para>An Ethernet interface using a Media Independent Interface (MII).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>fibre</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Optical Fibre as the medium.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>TCPSegmentationOffload=</varname></term>
<listitem>
<para>The NFS mount option <option>bg</option> for NFS background mounts
as documented in <citerefentry project='man-pages'><refentrytitle>nfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- is not supported in <filename>/etc/fstab</filename> entries. The systemd mount option <option>nofail</option>
- provides similar functionality and should be used instead.</para>
+ is detected by <command>systemd-fstab-generator</command> and the options
+ are transformed so that systemd fulfills the job-control implications of
+ that option. Specifically <command>systemd-fstab-generator</command> acts
+ as though <literal>x-systemd.mount-timout=infinity,retry=10000</literal> was
+ prepended to the option list, and <literal>fg,nofail</literal> was appended.
+ Depending on specific requirements, it may be appropriate to provide some of
+ these options explicitly, or to make use of the
+ <literal>x-systemd.automount</literal> option described below instead
+ of using <literal>bg</literal>.</para>
<para>When reading <filename>/etc/fstab</filename> a few special
mount options are understood by systemd which influence how
<listitem><para>The block device backed file system will be upgraded
to <varname>BindsTo=</varname> dependency. This option is only useful
when mounting file systems manually with
- <citerefentry><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
as the default dependency in this case is <varname>Requires=</varname>.
This option is already implied by entries in <filename>/etc/fstab</filename>
or by mount units.
<varlistentry>
<term><varname>Where=</varname></term>
- <listitem><para>Takes an absolute path of a directory of the
- mount point. If the mount point does not exist at the time of
+ <listitem><para>Takes an absolute path of a directory for the
+ mount point; in particular, the destination cannot be a symbolic
+ link. If the mount point does not exist at the time of
mounting, it is created. This string must be reflected in the
unit filename. (See above.) This option is
mandatory.</para></listitem>
<row><entry><varname>vxlan</varname></entry>
<entry>A virtual extensible LAN (vxlan), for connecting Cloud computing deployments.</entry></row>
+ <row><entry><varname>geneve</varname></entry>
+ <entry>A GEneric NEtwork Virtualization Encapsulation (GENEVE) netdev driver.</entry></row>
+
<row><entry><varname>vrf</varname></entry>
<entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create separate routing and forwarding domains.</entry></row>
<varlistentry>
<term><varname>DefaultPVID=</varname></term>
<listitem>
- <para>This specifies the default port VLAN ID of a newly attached bridge port.</para>
+ <para>This specifies the default port VLAN ID of a newly attached bridge port.
+ Set this to an integer in the range 1–4094 or <literal>none</literal> to disable the PVID.</para>
</listitem>
</varlistentry>
<varlistentry>
This option is compulsory.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>GVRP=</varname></term>
+ <listitem>
+ <para>The Generic VLAN Registration Protocol (GVRP) is a protocol that
+ allows automatic learning of VLANs on a network. A boolean. When unset,
+ the kernel's default setting applies.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>MVRP=</varname></term>
+ <listitem>
+ <para>Multiple VLAN Registration Protocol (MVRP) formerly known as GARP VLAN
+ Registration Protocol (GVRP) is a standards-based Layer 2 network protocol,
+ for automatic configuration of VLAN information on switches. It was defined
+ in the 802.1ak amendment to 802.1Q-2005. A boolean. When unset, the kernel's
+ default setting applies.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>LooseBinding=</varname></term>
+ <listitem>
+ <para>The VLAN loose binding mode, in which only the operational state is passed
+ from the parent to the associated VLANs, but the VLAN device state is not changed.
+ A boolean. When unset, the kernel's default setting applies.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>ReorderHeader=</varname></term>
+ <listitem>
+ <para>The VLAN reorder header is set VLAN interfaces behave like physical interfaces.
+ A boolean. When unset, the kernel's default setting applies.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
-
</refsect1>
<refsect1>
<listitem>
<para>Configures the default destination UDP port on a per-device basis.
If destination port is not specified then Linux kernel default will be used.
- Set destination port 4789 to get the IANA assigned value,
- and destination port 0 to get default values.</para>
+ Set destination port 4789 to get the IANA assigned value. If not set or if the
+ destination port is assigned the empty string the default port of 4789 is used.</para>
</listitem>
</varlistentry>
<varlistentry>
ports, and allows overriding via configuration.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>FlowLabel=</varname></term>
+ <listitem>
+ <para>Specifies the flow label to use in outgoing packets.
+ The valid range is 0-1048575.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>[GENEVE] Section Options</title>
+ <para>The <literal>[GENEVE]</literal> section only applies for
+ netdevs of kind <literal>geneve</literal>, and accepts the
+ following keys:</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>Id=</varname></term>
+ <listitem>
+ <para>Specifies the Virtual Network Identifer (VNI) to use. Ranges [0-16777215].</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Remote=</varname></term>
+ <listitem>
+ <para>Specifies the unicast destination IP address to use in outgoing packets.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>TOS=</varname></term>
+ <listitem>
+ <para>Specifies the TOS value to use in outgoing packets. Ranges [1-255].</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>TTL=</varname></term>
+ <listitem>
+ <para>Specifies the TTL value to use in outgoing packets. Ranges [1-255].</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>UDPChecksum=</varname></term>
+ <listitem>
+ <para>A boolean. When true, specifies if UDP checksum is calculated for transmitted packets over IPv4.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>UDP6ZeroChecksumTx=</varname></term>
+ <listitem>
+ <para>A boolean. When true, skip UDP checksum calculation for transmitted packets over IPv6.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>UDP6ZeroChecksumRx=</varname></term>
+ <listitem>
+ <para>A boolean. When true, allows incoming UDP packets over IPv6 with zero checksum field.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>DestinationPort=</varname></term>
+ <listitem>
+ <para>Specifies destination port. Defaults to 6081. If not set or assigned the empty string, the default
+ port of 6081 is used.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>FlowLabel=</varname></term>
+ <listitem>
+ <para>Specifies the flow label to use in outgoing packets.</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<refsect1>
<para>This setting is read by
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
"Search domains" correspond to the <varname>domain</varname> and <varname>search</varname> entries in
- <citerefentry><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ <citerefentry project='man-pages'><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
Domain name routing has no equivalent in the traditional glibc API, which has no concept of domain
name servers limited to a specific link.</para>
</listitem>
</para></listitem>
</varlistentry>
<varlistentry>
- <term><varname>IPv6ProxyNDPAddress=</varname></term>
- <listitem><para>An IPv6 address, for which Neighbour Advertisement
- messages will be proxied.
- Proxy NDP (Neighbor Discovery Protocol) is a technique for IPv6 to
- allow routing of addresses to a different destination when peers expect them
- to be present on a certain physical link.
+ <term><varname>IPv6ProxyNDP=</varname></term>
+ <listitem><para>A boolean. Configures proxy NDP for IPv6. Proxy NDP (Neighbor Discovery
+ Protocol) is a technique for IPv6 to allow routing of addresses to a different
+ destination when peers expect them to be present on a certain physical link.
In this case a router answers Neighbour Advertisement messages intended for
another machine by offering its own MAC address as destination.
- Unlike proxy ARP for IPv4, is not enabled globally, but will only send Neighbour
+ Unlike proxy ARP for IPv4, it is not enabled globally, but will only send Neighbour
Advertisement messages for addresses in the IPv6 neighbor proxy table,
- which can also be shown by <command>ip -6 neighbour show proxy</command>
- This option may be specified more than once. systemd-networkd will control the
- per-interface `proxy_ndp` switch for each configured interface, depending on whether
- there are <option>IPv6ProxyNDPAddress=</option> entries configured and add these to
- the kernels IPv6 neighbor proxy table.
- Defaults to unset.
+ which can also be shown by <command>ip -6 neighbour show proxy</command>.
+ systemd-networkd will control the per-interface `proxy_ndp` switch for each configured
+ interface depending on this option.
+ Defautls to unset.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>IPv6ProxyNDPAddress=</varname></term>
+ <listitem><para>An IPv6 address, for which Neighbour Advertisement messages will be
+ proxied. This option may be specified more than once. systemd-networkd will add the
+ <option>IPv6ProxyNDPAddress=</option> entries to the kernel's IPv6 neighbor proxy table.
+ This option implies <option>IPv6ProxyNDP=true</option> but has no effect if
+ <option>IPv6ProxyNDP</option> has been set to false. Defaults to unset.
</para></listitem>
</varlistentry>
<varlistentry>
</variablelist>
</refsect1>
+ <refsect1>
+ <title>[IPv6AddressLabel] Section Options</title>
+
+ <para>An <literal>[IPv6AddressLabel]</literal> section accepts the
+ following keys. Specify several <literal>[IPv6AddressLabel]</literal>
+ sections to configure several addresse labels. IPv6 address labels are
+ used for address selection. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>.
+ Precedence is managed by userspace, and only the label itself is stored in the kernel</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>Label=</varname></term>
+ <listitem>
+ <para> The label for the prefix (an unsigned integer) ranges 0 to 4294967294.
+ 0xffffffff is reserved. This key is mandatory.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Prefix=</varname></term>
+ <listitem>
+ <para>IPv6 prefix is an address with a prefix length, separated by a slash <literal>/</literal> character.
+ This key is mandatory. </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
<refsect1>
<title>[Route] Section Options</title>
<para>The <literal>[Route]</literal> section accepts the
<para>As in the <literal>[Network]</literal> section.</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>GatewayOnlink=</varname></term>
+ <listitem>
+ <para>The <literal>GatewayOnlink</literal> option tells the kernel that it does not have
+ to check if the gateway is reachable directly by the current machine (i.e., the kernel does
+ not need to check if the gateway is attached to the local network), so that we can insert the
+ route in the kernel table without it being complained about. A boolean, defaults to <literal>no</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>Destination=</varname></term>
<listitem>
<para>The metric of the route (an unsigned integer).</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>IPv6Preference=</varname></term>
+ <listitem>
+ <para>Specifies the route preference as defined in <ulink
+ url="https://tools.ietf.org/html/rfc4191">RFC4191</ulink> for Router Discovery messages.
+ Which can be one of <literal>low</literal> the route has a lowest priority,
+ <literal>medium</literal> the route has a default priority or
+ <literal>high</literal> the route has a highest priority.</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>Scope=</varname></term>
<listitem>
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>Protocol=</varname></term>
+ <listitem>
+ <para>The Protocol identifier for the route. Takes a number between 0 and 255 or the special values
+ <literal>kernel</literal>, <literal>boot</literal> and <literal>static</literal>. Defaults to
+ <literal>static</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
<varlistentry>
<term><varname>UseRoutes=</varname></term>
<listitem>
- <para>When true (the default), the static routes will be
- requested from the DHCP server and added to the routing
- table with a metric of 1024.</para>
+ <para>When true (the default), the static routes will be requested from the DHCP server and added to the
+ routing table with a metric of 1024, and a scope of "global", "link" or "host", depending on the route's
+ destination and gateway. If the destination is on the local host, e.g., 127.x.x.x, or the same as the
+ link's own address, the scope will be set to "host". Otherwise if the gateway is null (a direct route), a
+ "link" scope will be used. For anything else, scope defaults to "global".</para>
</listitem>
</varlistentry>
<para>Sets the "cost" of sending packets of this interface.
Each port in a bridge may have a different speed and the cost
is used to decide which link to use. Faster interfaces
- should have lower costs.</para>
+ should have lower costs. It is an interger value between 1 and
+ 65535.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>Priority=</varname></term>
+ <listitem>
+ <para>Sets the "priority" of sending packets on this interface.
+ Each port in a bridge may have a different priority which is used
+ to decide which link to use. Lower value means higher priority.
+ It is an interger value between 0 to 63. Networkd does not set any
+ default, meaning the kernel default value of 32 is used.</para>
</listitem>
</varlistentry>
</variablelist>
<title>MacVTap</title>
<para>This brings up a network interface <literal>macvtap-test</literal>
and attaches it to <literal>enp0s25</literal>.</para>
- <programlisting># /lib/systemd/network/25-macvtap.network
+ <programlisting># /usr/lib/systemd/network/25-macvtap.network
[Match]
Name=enp0s25
process has to exit before systemd starts follow-up units.
<varname>RemainAfterExit=</varname> is particularly useful for
this type of service. This is the implied default if neither
- <varname>Type=</varname> or <varname>ExecStart=</varname> are
+ <varname>Type=</varname> nor <varname>ExecStart=</varname> are
specified.</para>
<para>Behavior of <option>dbus</option> is similar to
all <varname>ExecStartPre=</varname> commands that were not prefixed
with a <literal>-</literal> exit successfully.</para>
- <para><varname>ExecStartPost=</varname> commands are only run after
- the service has started successfully, as determined by <varname>Type=</varname>
- (i.e. the process has been started for <varname>Type=simple</varname>
- or <varname>Type=idle</varname>, the process exits successfully for
- <varname>Type=oneshot</varname>, the initial process exits successfully
- for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent
- for <varname>Type=notify</varname>, or the <varname>BusName=</varname>
- has been taken for <varname>Type=dbus</varname>).</para>
+ <para><varname>ExecStartPost=</varname> commands are only run after the commands specified in
+ <varname>ExecStart=</varname> have been invoked successfully, as determined by <varname>Type=</varname>
+ (i.e. the process has been started for <varname>Type=simple</varname> or <varname>Type=idle</varname>, the last
+ <varname>ExecStart=</varname> process exited successfully for <varname>Type=oneshot</varname>, the initial
+ process exited successfully for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent for
+ <varname>Type=notify</varname>, or the <varname>BusName=</varname> has been taken for
+ <varname>Type=dbus</varname>).</para>
<para>Note that <varname>ExecStartPre=</varname> may not be
used to start long-running processes. All processes forked
multiple command lines, following the same scheme as described
for <varname>ExecStart=</varname> above. Use of this setting
is optional. After the commands configured in this option are
- run, all processes remaining for a service are terminated
+ run, it is implied that the service is stopped, and any processes
+ remaining for it are terminated
according to the <varname>KillMode=</varname> setting (see
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
If this option is not specified, the process is terminated by
<para>As exceptions to the setting above, the service will not
be restarted if the exit code or signal is specified in
- <varname>RestartPreventExitStatus=</varname> (see below).
- Also, the services will always be restarted if the exit code
- or signal is specified in
+ <varname>RestartPreventExitStatus=</varname> (see below) or
+ the service is stopped with <command>systemctl stop</command>
+ or an equivalent operation. Also, the services will always be
+ restarted if the exit code or signal is specified in
<varname>RestartForceExitStatus=</varname> (see below).</para>
<para>Note that service restart is subject to unit start rate
<varlistentry>
<term><varname>NonBlocking=</varname></term>
- <listitem><para>Set the <constant>O_NONBLOCK</constant> flag
- for all file descriptors passed via socket-based activation.
- If true, all file descriptors >= 3 (i.e. all except stdin,
- stdout, and stderr) will have the
- <constant>O_NONBLOCK</constant> flag set and hence are in
- non-blocking mode. This option is only useful in conjunction
- with a socket unit, as described in
- <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- Defaults to false.</para></listitem>
+ <listitem><para>Set the <constant>O_NONBLOCK</constant> flag for all file descriptors passed via socket-based
+ activation. If true, all file descriptors >= 3 (i.e. all except stdin, stdout, stderr), excluding those passed
+ in via the file descriptor storage logic (see <varname>FileDescriptorStoreMax=</varname> for details), will
+ have the <constant>O_NONBLOCK</constant> flag set and hence are in non-blocking mode. This option is only
+ useful in conjunction with a socket unit, as described in
+ <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> and has no
+ effect on file descriptors which were previously saved in the file-descriptor store for example. Defaults to
+ false.</para></listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term><varname>FileDescriptorStoreMax=</varname></term>
- <listitem><para>Configure how many file descriptors may be
- stored in the service manager for the service using
+ <listitem><para>Configure how many file descriptors may be stored in the service manager for the service using
<citerefentry><refentrytitle>sd_pid_notify_with_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
- <literal>FDSTORE=1</literal> messages. This is useful for
- implementing service restart schemes where the state is
- serialized to <filename>/run</filename> and the file
- descriptors passed to the service manager, to allow restarts
- without losing state. Defaults to 0, i.e. no file descriptors
- may be stored in the service manager. All file
- descriptors passed to the service manager from a specific
- service are passed back to the service's main process on the
- next service restart. Any file descriptors passed to the
- service manager are automatically closed when POLLHUP or
- POLLERR is seen on them, or when the service is fully stopped
- and no job is queued or being executed for it.</para></listitem>
+ <literal>FDSTORE=1</literal> messages. This is useful for implementing services that can restart after an
+ explicit request or a crash without losing state. Any open sockets and other file descriptors which should not
+ be closed during the restart may be stored this way. Application state can either be serialized to a file in
+ <filename>/run</filename>, or better, stored in a
+ <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory file
+ descriptor. Defaults to 0, i.e. no file descriptors may be stored in the service manager. All file descriptors
+ passed to the service manager from a specific service are passed back to the service's main process on the next
+ service restart. Any file descriptors passed to the service manager are automatically closed when
+ <constant>POLLHUP</constant> or <constant>POLLERR</constant> is seen on them, or when the service is fully
+ stopped and no job is queued or being executed for it.</para></listitem>
</varlistentry>
<varlistentry>
<para>Each command line is split on whitespace, with the first item being the command to
execute, and the subsequent items being the arguments. Double quotes ("…") and single quotes
- ('…') may be used, in which case everything until the next matching quote becomes part of the
- same argument. Quotes themselves are removed. C-style escapes are also supported. The table
- below contains the list of known escape patterns. Only escape patterns which match the syntax in
- the table are allowed; other patterns may be added in the future and unknown patterns will
- result in a warning. In particular, any backslashes should be doubled. Finally, a trailing
- backslash (<literal>\</literal>) may be used to merge lines.</para>
-
- <para>This syntax is intended to be very similar to shell syntax,
- but only the meta-characters and expansions described in the
- following paragraphs are understood. Specifically, redirection
- using
+ ('…') may be used to wrap a whole item (the opening quote may appear only at the beginning or
+ after whitespace that is not quoted, and the closing quote must be followed by whitespace or the
+ end of line), in which case everything until the next matching quote becomes part of the same
+ argument. Quotes themselves are removed. C-style escapes are also supported. The table below
+ contains the list of known escape patterns. Only escape patterns which match the syntax in the
+ table are allowed; other patterns may be added in the future and unknown patterns will result in
+ a warning. In particular, any backslashes should be doubled. Finally, a trailing backslash
+ (<literal>\</literal>) may be used to merge lines.</para>
+
+ <para>This syntax is inspired by shell syntax, but only the meta-characters and expansions
+ described in the following paragraphs are understood, and the expansion of variables is
+ different. Specifically, redirection using
<literal><</literal>,
<literal><<</literal>,
<literal>></literal>, and
<refsect1>
<title>Special Passive User Units</title>
- <refsect2>
- <title>graphical-session.target</title>
-
- <para>This target is active whenever any graphical session is running. It
- is used to stop user services which only apply to a graphical (X,
- Wayland, etc.) session when the session is terminated. Such services
- should have <literal>PartOf=graphical-session.target</literal> in their
- <literal>[Unit]</literal> section. A target for a particular session
- (e. g. <filename>gnome-session.target</filename>) starts and stops
- <literal>graphical-session.target</literal> with
- <literal>BindsTo=graphical-session.target</literal>.</para>
-
- <para>Which services are started by a session target is determined by the
- <literal>Wants=</literal> and <literal>Requires=</literal> dependencies.
- For services that can be enabled independently, symlinks in
- <literal>.wants/</literal> and <literal>.requires/</literal> should be
- used, see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- Those symlinks should either be shipped in packages, or should be added
- dynamically after installation, for example using <literal>systemctl add-wants</literal>, see
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
- </para>
+ <variablelist>
+ <varlistentry>
+ <term><filename>graphical-session.target</filename></term>
+ <listitem>
+ <para>This target is active whenever any graphical session is running. It is used to stop user services which
+ only apply to a graphical (X, Wayland, etc.) session when the session is terminated. Such services should
+ have <literal>PartOf=graphical-session.target</literal> in their <literal>[Unit]</literal> section. A target
+ for a particular session (e. g. <filename>gnome-session.target</filename>) starts and stops
+ <literal>graphical-session.target</literal> with <literal>BindsTo=graphical-session.target</literal>.</para>
+
+ <para>Which services are started by a session target is determined by the <literal>Wants=</literal> and
+ <literal>Requires=</literal> dependencies. For services that can be enabled independently, symlinks in
+ <literal>.wants/</literal> and <literal>.requires/</literal> should be used, see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. Those
+ symlinks should either be shipped in packages, or should be added dynamically after installation, for example
+ using <literal>systemctl add-wants</literal>, see
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+ </para>
- <example>
- <title>Nautilus as part of a GNOME session</title>
+ <example>
+ <title>Nautilus as part of a GNOME session</title>
- <para><literal>gnome-session.target</literal> pulls in Nautilus as
- top-level service:</para>
+ <para><literal>gnome-session.target</literal> pulls in Nautilus as top-level service:</para>
- <programlisting>[Unit]
+ <programlisting>[Unit]
Description=User systemd services for GNOME graphical session
Wants=nautilus.service
-BindsTo=graphical-session.target
- </programlisting>
+BindsTo=graphical-session.target</programlisting>
- <para><literal>nautilus.service</literal> gets stopped when the session stops:</para>
+ <para><literal>nautilus.service</literal> gets stopped when the session stops:</para>
- <programlisting>[Unit]
+ <programlisting>[Unit]
Description=Render the desktop icons with Nautilus
PartOf=graphical-session.target
[Service]
-…
- </programlisting>
- </example>
- </refsect2>
-
- <refsect2>
- <title>graphical-session-pre.target</title>
-
- <para>This target contains services which set up the environment or
- global configuration of a graphical session, such as SSH/GPG agents
- (which need to export an environment variable into all desktop processes)
- or migration of obsolete d-conf keys after an OS upgrade (which needs to
- happen before starting any process that might use them). This target must
- be started before starting a graphical session
- like <filename>gnome-session.target</filename>.</para>
- </refsect2>
+…</programlisting>
+ </example>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>graphical-session-pre.target</filename></term>
+ <listitem>
+ <para>This target contains services which set up the environment or global configuration of a graphical
+ session, such as SSH/GPG agents (which need to export an environment variable into all desktop processes) or
+ migration of obsolete d-conf keys after an OS upgrade (which needs to happen before starting any process that
+ might use them). This target must be started before starting a graphical session like
+ <filename>gnome-session.target</filename>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</refsect1>
</refsect1>
+ <refsect1>
+ <title>Example</title>
+
+ <example>
+ <title>Simple standalone target</title>
+
+ <programlisting># emergency-net.target
+
+[Unit]
+Description=Emergency Mode with Networking
+Requires=emergency.target systemd-networkd.service
+After=emergency.target systemd-networkd.service
+AllowIsolate=yes</programlisting>
+
+ <para>When adding dependencies to other units, it's important to check if they set
+ <varname>DefaultDependencies=</varname>. Service units, unless they set
+ <varname>DefaultDependencies=no</varname>, automatically get a dependency on
+ <filename>sysinit.target</filename>. In this case, both
+ <filename>emergency.target</filename> and <filename>systemd-networkd.service</filename>
+ have <varname>DefaultDependencies=no</varname>, so they are suitable for use
+ in this target, and do not pull in <filename>sysinit.target</filename>.</para>
+
+ <para>You can now switch into this emergency mode by running <varname>systemctl
+ isolate emergency-net.target</varname> or by passing the option
+ <varname>systemd.unit=emergency-net.target</varname> on the kernel command
+ line.</para>
+
+ <para>Other units can have <varname>WantedBy=emergency-net.target</varname> in the
+ <varname>[Install]</varname> section. After they are enabled using
+ <command>systemctl enable</command>, they will be started before
+ <varname>emergency-net.target</varname> is started. It is also possible to add
+ arbitrary units as dependencies of <filename>emergency.target</filename> without
+ modifying them by using <command>systemctl add-wants</command>.
+ </para>
+ </example>
+ </refsect1>
+
<refsect1>
<title>See Also</title>
<para>
the local timezone, similar to the supported syntax of timestamps (see above). Non-local timezones except for UTC
are not supported.</para>
- <para>The special expressions
- <literal>minutely</literal>,
- <literal>hourly</literal>, <literal>daily</literal>,
- <literal>monthly</literal>, <literal>weekly</literal>,
- <literal>yearly</literal>,
- <literal>quarterly</literal>,
- <literal>semiannually</literal> may be used as
- calendar events which refer to
- <literal>*-*-* *:*:00</literal>,
- <literal>*-*-* *:00:00</literal>,
- <literal>*-*-* 00:00:00</literal>,
- <literal>*-*-01 00:00:00</literal>,
- <literal>Mon *-*-* 00:00:00</literal>,
- <literal>*-01-01 00:00:00</literal>,
- <literal>*-01,04,07,10-01 00:00:00</literal> and
- <literal>*-01,07-01 00:00:00</literal>, respectively.
- </para>
+ <para>The following special expressions may be used as shorthands for longer normalized forms:</para>
+
+ <programlisting> minutely → *-*-* *:*:00
+ hourly → *-*-* *:00:00
+ daily → *-*-* 00:00:00
+ monthly → *-*-01 00:00:00
+ weekly → Mon *-*-* 00:00:00
+ yearly → *-01-01 00:00:00
+ quarterly → *-01,04,07,10-01 00:00:00
+semiannually → *-01,07-01 00:00:00
+ </programlisting>
<para>Examples for valid timestamps and their
normalized form:</para>
on <filename>timers.target</filename>, as well as <varname>Conflicts=</varname> and <varname>Before=</varname> on
<filename>shutdown.target</filename> to ensure that they are stopped cleanly prior to system shutdown. Timer units
with at least one <varname>OnCalendar=</varname> directive will have an additional <varname>After=</varname>
- dependency on <filename>timer-sync.target</filename> to avoid being started before the system clock has been
+ dependency on <filename>time-sync.target</filename> to avoid being started before the system clock has been
correctly set. Only timer units involved with early boot or late system shutdown should disable the
<varname>DefaultDependencies=</varname> option.</para>
</refsect1>
<para>Note that timers do not necessarily expire at the
precise time configured with this setting, as it is subject to
the <varname>AccuracySec=</varname> setting
- below.</para></listitem>
+ below.</para>
+
+ <para>May be specified more than once.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Before=</varname></term>
<term><varname>After=</varname></term>
- <listitem><para>A space-separated list of unit names. Configures ordering dependencies between units. If a
- unit <filename>foo.service</filename> contains a setting <option>Before=bar.service</option> and both units are
- being started, <filename>bar.service</filename>'s start-up is delayed until <filename>foo.service</filename> is
- started up. Note that this setting is independent of and orthogonal to the requirement dependencies as
- configured by <varname>Requires=</varname>, <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a
- common pattern to include a unit name in both the <varname>After=</varname> and <varname>Requires=</varname>
- option, in which case the unit listed will be started before the unit that is configured with these
- options. This option may be specified more than once, in which case ordering dependencies for all listed names
- are created. <varname>After=</varname> is the inverse of <varname>Before=</varname>, i.e. while
- <varname>After=</varname> ensures that the configured unit is started after the listed unit finished starting
- up, <varname>Before=</varname> ensures the opposite, i.e. that the configured unit is fully started up before
- the listed unit is started. Note that when two units with an ordering dependency between them are shut down,
- the inverse of the start-up order is applied. i.e. if a unit is configured with <varname>After=</varname> on
- another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering
- dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before
- the start-up. It doesn't matter if the ordering dependency is <varname>After=</varname> or
- <varname>Before=</varname>, in this case. It also doesn't matter which of the two is shut down, as long as one
- is shut down and the other is started up. The shutdown is ordered before the start-up in all cases. If two
- units have no ordering dependencies between them, they are shut down or started up simultaneously, and no
- ordering takes place. </para></listitem>
+ <listitem><para>These two settings expect a space-separated list of unit names. They configure ordering
+ dependencies between units. If a unit <filename>foo.service</filename> contains a setting
+ <option>Before=bar.service</option> and both units are being started, <filename>bar.service</filename>'s
+ start-up is delayed until <filename>foo.service</filename> has finished starting up. Note that this setting is
+ independent of and orthogonal to the requirement dependencies as configured by <varname>Requires=</varname>,
+ <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a common pattern to include a unit name in both
+ the <varname>After=</varname> and <varname>Requires=</varname> options, in which case the unit listed will be
+ started before the unit that is configured with these options. This option may be specified more than once, in
+ which case ordering dependencies for all listed names are created. <varname>After=</varname> is the inverse of
+ <varname>Before=</varname>, i.e. while <varname>After=</varname> ensures that the configured unit is started
+ after the listed unit finished starting up, <varname>Before=</varname> ensures the opposite, that the
+ configured unit is fully started up before the listed unit is started. Note that when two units with an
+ ordering dependency between them are shut down, the inverse of the start-up order is applied. i.e. if a unit is
+ configured with <varname>After=</varname> on another unit, the former is stopped before the latter if both are
+ shut down. Given two units with any ordering dependency between them, if one unit is shut down and the other is
+ started up, the shutdown is ordered before the start-up. It doesn't matter if the ordering dependency is
+ <varname>After=</varname> or <varname>Before=</varname>, in this case. It also doesn't matter which of the two
+ is shut down, as long as one is shut down and the other is started up. The shutdown is ordered before the
+ start-up in all cases. If two units have no ordering dependencies between them, they are shut down or started
+ up simultaneously, and no ordering takes place. It depends on the unit type when precisely a unit has finished
+ starting up. Most importantly, for service units start-up is considered completed for the purpose of
+ <varname>Before=</varname>/<varname>After=</varname> when all its configured start-up commands have been
+ invoked and they either failed or reported start-up success.</para></listitem>
</varlistentry>
<varlistentry>
<varlistentry>
<term><varname>JobTimeoutSec=</varname></term>
+ <term><varname>JobRunningTimeoutSec=</varname></term>
<term><varname>JobTimeoutAction=</varname></term>
<term><varname>JobTimeoutRebootArgument=</varname></term>
- <listitem><para>When a job for this unit is queued, a time-out may be configured. If this time limit is
- reached, the job will be cancelled, the unit however will not change state or even enter the
- <literal>failed</literal> mode. This value defaults to <literal>infinity</literal> (job timeouts disabled),
- except for device units. NB: this timeout is independent from any unit-specific timeout (for example, the
- timeout set with <varname>TimeoutStartSec=</varname> in service units) as the job timeout has no effect on the
- unit itself, only on the job that might be pending for it. Or in other words: unit-specific timeouts are useful
- to abort unit state changes, and revert them. The job timeout set with this option however is useful to abort
- only the job waiting for the unit state to change.</para>
+ <listitem><para>When a job for this unit is queued, a time-out <varname>JobTimeoutSec=</varname> may be
+ configured. Similarly, <varname>JobRunningTimeoutSec=</varname> starts counting when the queued job is actually
+ started. If either time limit is reached, the job will be cancelled, the unit however will not change state or
+ even enter the <literal>failed</literal> mode. This value defaults to <literal>infinity</literal> (job timeouts
+ disabled), except for device units (<varname>JobRunningTimeoutSec=</varname> defaults to
+ <varname>DefaultTimeoutStartSec=</varname>). NB: this timeout is independent from any unit-specific timeout
+ (for example, the timeout set with <varname>TimeoutStartSec=</varname> in service units) as the job timeout has
+ no effect on the unit itself, only on the job that might be pending for it. Or in other words: unit-specific
+ timeouts are useful to abort unit state changes, and revert them. The job timeout set with this option however
+ is useful to abort only the job waiting for the unit state to change.</para>
<para><varname>JobTimeoutAction=</varname>
optionally configures an additional
<term><varname>ConditionDirectoryNotEmpty=</varname></term>
<term><varname>ConditionFileNotEmpty=</varname></term>
<term><varname>ConditionFileIsExecutable=</varname></term>
+ <term><varname>ConditionUser=</varname></term>
+ <term><varname>ConditionGroup=</varname></term>
<!-- We do not document ConditionNull=
here, as it is not particularly
<varname>arm64-be</varname>,
<varname>sh</varname>,
<varname>sh64</varname>,
- <varname>m86k</varname>,
+ <varname>m68k</varname>,
<varname>tilegx</varname>,
- <varname>cris</varname> to test
+ <varname>cris</varname>,
+ <varname>arc</varname>,
+ <varname>arc-be</varname> to test
against a specific architecture. The architecture is
determined from the information returned by
<citerefentry project='man-pages'><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>
to make sure they run before the stamp file's modification
time gets reset indicating a completed update.</para>
- <para><varname>ConditionFirstBoot=</varname> takes a boolean
- argument. This condition may be used to conditionalize units
- on whether the system is booting up with an unpopulated
- <filename>/etc</filename> directory. This may be used to
- populate <filename>/etc</filename> on the first boot after
- factory reset, or when a new system instances boots up for the
- first time.</para>
+ <para><varname>ConditionFirstBoot=</varname> takes a boolean argument. This condition may be used to
+ conditionalize units on whether the system is booting up with an unpopulated <filename>/etc</filename>
+ directory (specifically: an <filename>/etc</filename> with no <filename>/etc/machine-id</filename>). This may
+ be used to populate <filename>/etc</filename> on the first boot after factory reset, or when a new system
+ instance boots up for the first time.</para>
<para>With <varname>ConditionPathExists=</varname> a file
existence condition is checked before a unit is started. If
whether a certain path exists, is a regular file and marked
executable.</para>
+ <para><varname>ConditionUser=</varname> takes a numeric
+ <literal>UID</literal>, a UNIX user name, or the special value
+ <literal>@system</literal>. This condition may be used to check
+ whether the service manager is running as the given user. The
+ special value <literal>@system</literal> can be used to check
+ if the user id is within the system user range. This option is not
+ useful for system services, as the system manager exclusively
+ runs as the root user, and thus the test result is constant.</para>
+
+ <para><varname>ConditionGroup=</varname> is similar
+ to <varname>ConditionUser=</varname> but verifies that the
+ service manager's real or effective group, or any of its
+ auxiliary groups match the specified group or GID. This setting
+ does not have a special value <literal>@system</literal>.</para>
+
<para>If multiple conditions are specified, the unit will be
executed if all of them apply (i.e. a logical AND is applied).
Condition checks can be prefixed with a pipe symbol (|) in
<term><varname>AssertDirectoryNotEmpty=</varname></term>
<term><varname>AssertFileNotEmpty=</varname></term>
<term><varname>AssertFileIsExecutable=</varname></term>
+ <term><varname>AssertUser=</varname></term>
+ <term><varname>AssertGroup=</varname></term>
<listitem><para>Similar to the <varname>ConditionArchitecture=</varname>,
<varname>ConditionVirtualization=</varname>, …, condition settings described above, these settings add
ordered appropriately (<varname>After=</varname>). Thirdly, in
order to harden the service a bit more, the administrator would
like to set the <varname>PrivateTmp=</varname> setting (see
- <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details). And lastly, the administrator would like to reset
the niceness of the service to its default value of 0.</para>
<refsect1>
<title>Description</title>
- <para><command>systemd-sysusers</command> uses the files from
- <filename>sysusers.d</filename> directory to create system users
- and groups at package installation or boot time. This tool may be
- used to allocate system users and groups only, it is not useful
- for creating non-system users and groups, as it accesses
- <filename>/etc/passwd</filename> and
- <filename>/etc/group</filename> directly, bypassing any more
- complex user databases, for example any database involving NIS or
- LDAP.</para>
+ <para><command>systemd-sysusers</command> uses the files from <filename>sysusers.d</filename> directory to create
+ system users and groups at package installation or boot time. This tool may be used to allocate system users and
+ groups only, it is not useful for creating non-system (i.e. regular, "human") users and groups, as it accesses
+ <filename>/etc/passwd</filename> and <filename>/etc/group</filename> directly, bypassing any more complex user
+ databases, for example any database involving NIS or LDAP.</para>
</refsect1>
<refsect1>
m authd input
u root 0 "Superuser" /root</programlisting>
+ <para>Empty lines and lines beginning with the <literal>#</literal> character are ignored, and may be used for
+ commenting.</para>
+
<refsect2>
<title>Type</title>
<refsect2>
<title>Name</title>
- <para>The name field specifies the user or group name. It should
- be shorter than 31 characters and avoid any non-ASCII
- characters, and not begin with a numeric character. It is
- strongly recommended to pick user and group names that are
- unlikely to clash with normal users created by the
- administrator. A good scheme to guarantee this is by prefixing
- all system and group names with the underscore, and avoiding too
- generic names.</para>
+ <para>The name field specifies the user or group name. The specified name must consist only of the characters a-z,
+ A-Z, 0-9, <literal>_</literal> and <literal>-</literal>, except for the first character which must be one of a-z,
+ A-Z or <literal>_</literal> (i.e. numbers and <literal>-</literal> are not permitted as first character). The
+ user/group name must have at least one character, and at most 31.</para>
+
+ <para>It is strongly recommended to pick user and group names that are unlikely to clash with normal users
+ created by the administrator. A good scheme to guarantee this is by prefixing all system and group names with the
+ underscore, and avoiding too generic names.</para>
<para>For <varname>m</varname> lines, this field should contain
the user name to add to a group.</para>
<term><option>-s</option></term>
<term><option>--subsystem-match=<replaceable>string[/string]</replaceable></option></term>
<listitem>
- <para>Filter events by subsystem[/devtype]. Only udev events with a matching subsystem value will pass.</para>
+ <para>Filter kernel uevents and udev events by subsystem[/devtype]. Only events with a matching subsystem value will pass.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-t</option></term>
<term><option>--tag-match=<replaceable>string</replaceable></option></term>
<listitem>
- <para>Filter events by property. Only udev events with a given tag attached will pass.</para>
+ <para>Filter udev events by tag. Only udev events with a given tag attached will pass.</para>
</listitem>
</varlistentry>
<varlistentry>
<para>Depending on the operating system other configuration files
might be checked for configuration of the virtual console as well,
however only as fallback.</para>
+
+ <para><filename>/etc/vconsole.conf</filename> is usually created and updated
+ using
+ <citerefentry><refentrytitle>systemd-localed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ <citerefentry><refentrytitle>localectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ may be used to instruct <command>systemd-localed.service</command> to
+ query or update configuration.</para>
</refsect1>
<refsect1>
--- /dev/null
+project('systemd', 'c',
+ version : '234',
+ license : 'LGPLv2+',
+ default_options: [
+ 'c_std=gnu99',
+ 'prefix=/usr',
+ 'sysconfdir=/etc',
+ 'localstatedir=/var',
+ ],
+ meson_version : '>= 0.40',
+ )
+
+# We need the same data in three different formats, ugh!
+# Also, for hysterical reasons, we use different variable
+# names, sometimes. Not all variables are included in every
+# set. Ugh, ugh, ugh!
+conf = configuration_data()
+conf.set_quoted('PACKAGE_STRING', meson.project_name() + ' ' + meson.project_version())
+conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+
+substs = configuration_data()
+substs.set('PACKAGE_URL', 'https://www.freedesktop.org/wiki/Software/systemd')
+substs.set('PACKAGE_VERSION', meson.project_version())
+
+m4_defines = []
+
+#####################################################################
+
+rootprefixdir = get_option('rootprefix')
+if get_option('split-usr')
+ conf.set('HAVE_SPLIT_USR', true)
+ rootprefixdir = rootprefixdir != '' ? rootprefixdir : '/'
+else
+ rootprefixdir = rootprefixdir != '' ? rootprefixdir : '/usr'
+endif
+
+sysvinit_path = get_option('sysvinit-path')
+sysvrcnd_path = get_option('sysvrcnd-path')
+if sysvinit_path != '' or sysvrcnd_path != ''
+ conf.set('HAVE_SYSV_COMPAT', true,
+ description : 'SysV init scripts and rcN.d links are supported')
+ m4_defines += ['-DHAVE_SYSV_COMPAT']
+endif
+
+# join_paths ignore the preceding arguments if an absolute component is
+# encountered, so this should canonicalize various paths when they are
+# absolute or relative.
+prefixdir = get_option('prefix')
+if not prefixdir.startswith('/')
+ error('Prefix is not absolute: "@0@"'.format(prefixdir))
+endif
+bindir = join_paths(prefixdir, get_option('bindir'))
+libdir = join_paths(prefixdir, get_option('libdir'))
+sysconfdir = join_paths(prefixdir, get_option('sysconfdir'))
+includedir = join_paths(prefixdir, get_option('includedir'))
+datadir = join_paths(prefixdir, get_option('datadir'))
+localstatedir = join_paths('/', get_option('localstatedir'))
+
+rootbindir = join_paths(rootprefixdir, 'bin')
+rootlibexecdir = join_paths(rootprefixdir, 'lib/systemd')
+
+rootlibdir = get_option('rootlibdir')
+if rootlibdir == ''
+ rootlibdir = join_paths(rootprefixdir, libdir.split('/')[-1])
+endif
+
+# Dirs of external packages
+pkgconfigdatadir = join_paths(datadir, 'pkgconfig')
+pkgconfiglibdir = join_paths(libdir, 'pkgconfig')
+polkitpolicydir = join_paths(datadir, 'polkit-1/actions')
+polkitrulesdir = join_paths(datadir, 'polkit-1/rules.d')
+polkitpkladir = join_paths(localstatedir, 'lib/polkit-1/localauthority/10-vendor.d')
+varlogdir = join_paths(localstatedir, 'log')
+xinitrcdir = join_paths(sysconfdir, 'X11/xinit/xinitrc.d')
+rpmmacrosdir = get_option('rpmmacrosdir')
+
+# Our own paths
+pkgdatadir = join_paths(datadir, 'systemd')
+environmentdir = join_paths(prefixdir, 'lib/environment.d')
+pkgsysconfdir = join_paths(sysconfdir, 'systemd')
+userunitdir = join_paths(prefixdir, 'lib/systemd/user')
+userpresetdir = join_paths(prefixdir, 'lib/systemd/user-preset')
+tmpfilesdir = join_paths(prefixdir, 'lib/tmpfiles.d')
+sysusersdir = join_paths(prefixdir, 'lib/sysusers.d')
+sysctldir = join_paths(prefixdir, 'lib/sysctl.d')
+binfmtdir = join_paths(prefixdir, 'lib/binfmt.d')
+modulesloaddir = join_paths(prefixdir, 'lib/modules-load.d')
+networkdir = join_paths(rootprefixdir, 'lib/systemd/network')
+pkgincludedir = join_paths(includedir, 'systemd')
+systemgeneratordir = join_paths(rootlibexecdir, 'system-generators')
+usergeneratordir = join_paths(prefixdir, 'lib/systemd/user-generators')
+systemenvgeneratordir = join_paths(prefixdir, 'lib/systemd/system-environment-generators')
+userenvgeneratordir = join_paths(prefixdir, 'lib/systemd/user-environment-generators')
+systemshutdowndir = join_paths(rootlibexecdir, 'system-shutdown')
+systemsleepdir = join_paths(rootlibexecdir, 'system-sleep')
+systemunitdir = join_paths(rootprefixdir, 'lib/systemd/system')
+systempresetdir = join_paths(rootprefixdir, 'lib/systemd/system-preset')
+udevlibexecdir = join_paths(rootprefixdir, 'lib/udev')
+udevhomedir = udevlibexecdir
+udevrulesdir = join_paths(udevlibexecdir, 'rules.d')
+udevhwdbdir = join_paths(udevlibexecdir, 'hwdb.d')
+catalogdir = join_paths(prefixdir, 'lib/systemd/catalog')
+kernelinstalldir = join_paths(prefixdir, 'lib/kernel/install.d')
+factorydir = join_paths(datadir, 'factory')
+docdir = join_paths(datadir, 'doc/systemd')
+bootlibdir = join_paths(prefixdir, 'lib/systemd/boot/efi')
+testsdir = join_paths(prefixdir, 'lib/systemd/tests')
+systemdstatedir = join_paths(localstatedir, 'lib/systemd')
+catalogstatedir = join_paths(systemdstatedir, 'catalog')
+randomseeddir = join_paths(localstatedir, 'lib/systemd')
+
+dbuspolicydir = get_option('dbuspolicydir')
+if dbuspolicydir == ''
+ dbuspolicydir = join_paths(datadir, 'dbus-1/system.d')
+endif
+
+dbussessionservicedir = get_option('dbussessionservicedir')
+if dbussessionservicedir == ''
+ dbussessionservicedir = join_paths(datadir, 'dbus-1/services')
+endif
+
+dbussystemservicedir = get_option('dbussystemservicedir')
+if dbussystemservicedir == ''
+ dbussystemservicedir = join_paths(datadir, 'dbus-1/system-services')
+endif
+
+pamlibdir = get_option('pamlibdir')
+if pamlibdir == ''
+ pamlibdir = join_paths(rootlibdir, 'security')
+endif
+
+pamconfdir = get_option('pamconfdir')
+if pamconfdir == ''
+ pamconfdir = join_paths(sysconfdir, 'pam.d')
+endif
+
+conf.set_quoted('PKGSYSCONFDIR', pkgsysconfdir)
+conf.set_quoted('SYSTEM_CONFIG_UNIT_PATH', join_paths(pkgsysconfdir, 'system'))
+conf.set_quoted('SYSTEM_DATA_UNIT_PATH', systemunitdir)
+conf.set_quoted('SYSTEM_SYSVINIT_PATH', sysvinit_path)
+conf.set_quoted('SYSTEM_SYSVRCND_PATH', sysvrcnd_path)
+conf.set_quoted('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-local'))
+conf.set_quoted('RC_LOCAL_SCRIPT_PATH_STOP', get_option('halt-local'))
+conf.set_quoted('USER_CONFIG_UNIT_PATH', join_paths(pkgsysconfdir, 'user'))
+conf.set_quoted('USER_DATA_UNIT_PATH', userunitdir)
+conf.set_quoted('CERTIFICATE_ROOT', get_option('certificate-root'))
+conf.set_quoted('CATALOG_DATABASE', join_paths(catalogstatedir, 'database'))
+conf.set_quoted('SYSTEMD_CGROUP_AGENT_PATH', join_paths(rootlibexecdir, 'systemd-cgroups-agent'))
+conf.set_quoted('SYSTEMD_BINARY_PATH', join_paths(rootlibexecdir, 'systemd'))
+conf.set_quoted('SYSTEMD_FSCK_PATH', join_paths(rootlibexecdir, 'systemd-fsck'))
+conf.set_quoted('SYSTEMD_SHUTDOWN_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-shutdown'))
+conf.set_quoted('SYSTEMD_SLEEP_BINARY_PATH', join_paths(rootlibexecdir, 'systemd-sleep'))
+conf.set_quoted('SYSTEMCTL_BINARY_PATH', join_paths(rootbindir, 'systemctl'))
+conf.set_quoted('SYSTEMD_TTY_ASK_PASSWORD_AGENT_BINARY_PATH', join_paths(rootbindir, 'systemd-tty-ask-password-agent'))
+conf.set_quoted('SYSTEMD_STDIO_BRIDGE_BINARY_PATH', join_paths(bindir, 'systemd-stdio-bridge'))
+conf.set_quoted('ROOTPREFIX', rootprefixdir)
+conf.set_quoted('RANDOM_SEED_DIR', randomseeddir)
+conf.set_quoted('RANDOM_SEED', join_paths(randomseeddir, 'random-seed'))
+conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', join_paths(rootlibexecdir, 'systemd-cryptsetup'))
+conf.set_quoted('SYSTEM_GENERATOR_PATH', systemgeneratordir)
+conf.set_quoted('USER_GENERATOR_PATH', usergeneratordir)
+conf.set_quoted('SYSTEM_ENV_GENERATOR_PATH', systemenvgeneratordir)
+conf.set_quoted('USER_ENV_GENERATOR_PATH', userenvgeneratordir)
+conf.set_quoted('SYSTEM_SHUTDOWN_PATH', systemshutdowndir)
+conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir)
+conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', join_paths(pkgdatadir, 'kbd-model-map'))
+conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', join_paths(pkgdatadir, 'language-fallback-map'))
+conf.set_quoted('UDEVLIBEXECDIR', udevlibexecdir)
+conf.set_quoted('POLKIT_AGENT_BINARY_PATH', join_paths(bindir, 'pkttyagent'))
+conf.set_quoted('LIBDIR', libdir)
+conf.set_quoted('ROOTLIBDIR', rootlibdir)
+conf.set_quoted('ROOTLIBEXECDIR', rootlibexecdir)
+conf.set_quoted('BOOTLIBDIR', bootlibdir)
+conf.set_quoted('SYSTEMD_PULL_PATH', join_paths(rootlibexecdir, 'systemd-pull'))
+conf.set_quoted('SYSTEMD_IMPORT_PATH', join_paths(rootlibexecdir, 'systemd-import'))
+conf.set_quoted('SYSTEMD_EXPORT_PATH', join_paths(rootlibexecdir, 'systemd-export'))
+conf.set_quoted('VENDOR_KEYRING_PATH', join_paths(rootlibexecdir, 'import-pubring.gpg'))
+conf.set_quoted('USER_KEYRING_PATH', join_paths(pkgsysconfdir, 'import-pubring.gpg'))
+conf.set_quoted('DOCUMENT_ROOT', join_paths(pkgdatadir, 'gatewayd'))
+
+conf.set_quoted('ABS_BUILD_DIR', meson.build_root())
+conf.set_quoted('ABS_SRC_DIR', meson.source_root())
+
+substs.set('prefix', prefixdir)
+substs.set('exec_prefix', prefixdir)
+substs.set('libdir', libdir)
+substs.set('rootlibdir', rootlibdir)
+substs.set('includedir', includedir)
+substs.set('pkgsysconfdir', pkgsysconfdir)
+substs.set('bindir', bindir)
+substs.set('rootbindir', rootbindir)
+substs.set('rootlibexecdir', rootlibexecdir)
+substs.set('systemunitdir', systemunitdir)
+substs.set('userunitdir', userunitdir)
+substs.set('systempresetdir', systempresetdir)
+substs.set('userpresetdir', userpresetdir)
+substs.set('udevhwdbdir', udevhwdbdir)
+substs.set('udevrulesdir', udevrulesdir)
+substs.set('udevlibexecdir', udevlibexecdir)
+substs.set('catalogdir', catalogdir)
+substs.set('tmpfilesdir', tmpfilesdir)
+substs.set('sysusersdir', sysusersdir)
+substs.set('sysctldir', sysctldir)
+substs.set('binfmtdir', binfmtdir)
+substs.set('modulesloaddir', modulesloaddir)
+substs.set('systemgeneratordir', systemgeneratordir)
+substs.set('usergeneratordir', usergeneratordir)
+substs.set('systemenvgeneratordir', systemenvgeneratordir)
+substs.set('userenvgeneratordir', userenvgeneratordir)
+substs.set('systemshutdowndir', systemshutdowndir)
+substs.set('systemsleepdir', systemsleepdir)
+substs.set('VARLOGDIR', varlogdir)
+substs.set('CERTIFICATEROOT', get_option('certificate-root'))
+substs.set('SYSTEMCTL', join_paths(rootbindir, 'systemctl'))
+substs.set('RANDOM_SEED', join_paths(randomseeddir, 'random-seed'))
+substs.set('SYSTEM_SYSVINIT_PATH', sysvinit_path)
+substs.set('SYSTEM_SYSVRCND_PATH', sysvrcnd_path)
+substs.set('RC_LOCAL_SCRIPT_PATH_START', get_option('rc-local'))
+substs.set('RC_LOCAL_SCRIPT_PATH_STOP', get_option('halt-local'))
+
+#####################################################################
+
+cc = meson.get_compiler('c')
+pkgconfig = import('pkgconfig')
+check_compilation_sh = find_program('tools/meson-check-compilation.sh')
+
+cxx = find_program('c++', required : false)
+if cxx.found()
+ # Used only for tests
+ add_languages('cpp')
+endif
+
+foreach arg : ['-Wextra',
+ '-Wundef',
+ '-Wlogical-op',
+ '-Wmissing-include-dirs',
+ '-Wold-style-definition',
+ '-Wpointer-arith',
+ '-Winit-self',
+ '-Wdeclaration-after-statement',
+ '-Wfloat-equal',
+ '-Wsuggest-attribute=noreturn',
+ '-Werror=missing-prototypes',
+ '-Werror=implicit-function-declaration',
+ '-Werror=missing-declarations',
+ '-Werror=return-type',
+ '-Werror=incompatible-pointer-types',
+ '-Werror=format=2',
+ '-Wstrict-prototypes',
+ '-Wredundant-decls',
+ '-Wmissing-noreturn',
+ '-Wshadow',
+ '-Wendif-labels',
+ '-Wstrict-aliasing=2',
+ '-Wwrite-strings',
+ '-Werror=overflow',
+ '-Wdate-time',
+ '-Wnested-externs',
+ '-ffast-math',
+ '-fno-common',
+ '-fdiagnostics-show-option',
+ '-fno-strict-aliasing',
+ '-fvisibility=hidden',
+ '-fstack-protector',
+ '-fstack-protector-strong',
+ '-fPIE',
+ '--param=ssp-buffer-size=4',
+ ]
+ if cc.has_argument(arg)
+ add_project_arguments(arg, language : 'c')
+ endif
+endforeach
+
+# "negative" arguments: gcc on purpose does not return an error for "-Wno-"
+# arguments, just emits a warnings. So test for the "positive" version instead.
+foreach arg : ['unused-parameter',
+ 'missing-field-initializers',
+ 'unused-result',
+ 'format-signedness']
+ if cc.has_argument('-W' + arg)
+ add_project_arguments('-Wno-' + arg, language : 'c')
+ endif
+endforeach
+
+if cc.compiles('
+ #include <time.h>
+ #include <inttypes.h>
+ typedef uint64_t usec_t;
+ usec_t now(clockid_t clock);
+ int main(void) {
+ struct timespec now;
+ return 0;
+ }
+', name : '-Werror=shadow with local shadowing')
+ add_project_arguments('-Werror=shadow', language : 'c')
+endif
+
+if cc.get_id() == 'clang'
+ foreach arg : ['-Wno-typedef-redefinition',
+ '-Wno-gnu-variable-sized-type-not-at-end',
+ ]
+ if cc.has_argument(arg,
+ name : '@0@ is supported'.format(arg))
+ add_project_arguments(arg, language : 'c')
+ endif
+ endforeach
+endif
+
+link_test_c = files('tools/meson-link-test.c')
+
+# --as-needed and --no-undefined are provided by meson by default,
+# run mesonconf to see what is enabled
+foreach arg : ['-Wl,-z,relro',
+ '-Wl,-z,now',
+ '-pie',
+ ]
+
+ have = run_command(check_compilation_sh,
+ cc.cmd_array(), '-x', 'c', arg,
+ '-include', link_test_c).returncode() == 0
+ message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
+ if have
+ add_project_link_arguments(arg, language : 'c')
+ endif
+endforeach
+
+if get_option('buildtype') != 'debug'
+ foreach arg : ['-ffunction-sections',
+ '-fdata-sections']
+ if cc.has_argument(arg,
+ name : '@0@ is supported'.format(arg))
+ add_project_arguments(arg, language : 'c')
+ endif
+ endforeach
+
+ foreach arg : ['-Wl,--gc-sections']
+ have = run_command(check_compilation_sh,
+ cc.cmd_array(), '-x', 'c', arg,
+ '-include', link_test_c).returncode() == 0
+ message('Linking with @0@ supported: @1@'.format(arg, have ? 'yes' : 'no'))
+ if have
+ add_project_link_arguments(arg, language : 'c')
+ endif
+ endforeach
+endif
+
+cpp = ' '.join(cc.cmd_array()) + ' -E'
+
+#####################################################################
+# compilation result tests
+
+conf.set('_GNU_SOURCE', true)
+conf.set('__SANE_USERSPACE_TYPES__', true)
+
+conf.set('SIZEOF_PID_T', cc.sizeof('pid_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_UID_T', cc.sizeof('uid_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_GID_T', cc.sizeof('gid_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_DEV_T', cc.sizeof('dev_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_INO_T', cc.sizeof('ino_t', prefix : '#include <sys/types.h>'))
+conf.set('SIZEOF_TIME_T', cc.sizeof('time_t', prefix : '#include <sys/time.h>'))
+conf.set('SIZEOF_RLIM_T', cc.sizeof('rlim_t', prefix : '#include <sys/resource.h>'))
+
+decl_headers = '''
+#include <uchar.h>
+#include <linux/ethtool.h>
+'''
+# FIXME: key_serial_t is only defined in keyutils.h, this is bound to fail
+
+foreach decl : ['char16_t',
+ 'char32_t',
+ 'key_serial_t',
+ 'struct ethtool_link_settings',
+ ]
+
+ # We get -1 if the size cannot be determined
+ have = cc.sizeof(decl, prefix : decl_headers) > 0
+ conf.set('HAVE_' + decl.underscorify().to_upper(), have)
+endforeach
+
+foreach decl : [['IFLA_INET6_ADDR_GEN_MODE', 'linux/if_link.h'],
+ ['IN6_ADDR_GEN_MODE_STABLE_PRIVACY', 'linux/if_link.h'],
+ ['IFLA_VRF_TABLE', 'linux/if_link.h'],
+ ['IFLA_MACVLAN_FLAGS', 'linux/if_link.h'],
+ ['IFLA_IPVLAN_MODE', 'linux/if_link.h'],
+ ['IFLA_PHYS_PORT_ID', 'linux/if_link.h'],
+ ['IFLA_BOND_AD_INFO', 'linux/if_link.h'],
+ ['IFLA_VLAN_PROTOCOL', 'linux/if_link.h'],
+ ['IFLA_VXLAN_REMCSUM_NOPARTIAL', 'linux/if_link.h'],
+ ['IFLA_VXLAN_GPE', 'linux/if_link.h'],
+ ['IFLA_GENEVE_LABEL', 'linux/if_link.h'],
+ # if_tunnel.h is buggy and cannot be included on its own
+ ['IFLA_VTI_REMOTE', 'linux/if_tunnel.h', '#include <net/if.h>'],
+ ['IFLA_IPTUN_ENCAP_DPORT', 'linux/if_tunnel.h', '#include <net/if.h>'],
+ ['IFLA_GRE_ENCAP_DPORT', 'linux/if_tunnel.h', '#include <net/if.h>'],
+ ['IFLA_BRIDGE_VLAN_INFO', 'linux/if_bridge.h'],
+ ['IFLA_BRPORT_PROXYARP', 'linux/if_link.h'],
+ ['IFLA_BRPORT_LEARNING_SYNC', 'linux/if_link.h'],
+ ['IFLA_BR_VLAN_DEFAULT_PVID', 'linux/if_link.h'],
+ ['NDA_IFINDEX', 'linux/neighbour.h'],
+ ['IFA_FLAGS', 'linux/if_addr.h'],
+ ['LO_FLAGS_PARTSCAN', 'linux/loop.h'],
+ ]
+ prefix = decl.length() > 2 ? decl[2] : ''
+ have = cc.has_header_symbol(decl[1], decl[0], prefix : prefix)
+ conf.set10('HAVE_DECL_' + decl[0], have)
+endforeach
+
+skip = false
+foreach ident : ['secure_getenv', '__secure_getenv']
+ if not skip and cc.has_function(ident)
+ conf.set('HAVE_' + ident.to_upper(), true)
+ skip = true
+ endif
+endforeach
+
+foreach ident : [
+ ['memfd_create', '''#include <sys/memfd.h>'''],
+ ['gettid', '''#include <sys/types.h>'''],
+ ['pivot_root', '''#include <stdlib.h>'''], # no known header declares pivot_root
+ ['name_to_handle_at', '''#define _GNU_SOURCE
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>'''],
+ ['setns', '''#define _GNU_SOURCE
+ #include <sched.h>'''],
+ ['renameat2', '''#include <stdio.h>'''],
+ ['kcmp', '''#include <linux/kcmp.h>'''],
+ ['keyctl', '''#include <sys/types.h>
+ #include <keyutils.h>'''],
+ ['copy_file_range', '''#include <sys/syscall.h>
+ #include <unistd.h>'''],
+ ['explicit_bzero' , '''#include <string.h>'''],
+]
+
+ have = cc.has_function(ident[0], prefix : ident[1])
+ conf.set10('HAVE_DECL_' + ident[0].to_upper(), have)
+endforeach
+
+if cc.has_function('getrandom', prefix : '''#include <sys/random.h>''')
+ conf.set('USE_SYS_RANDOM_H', true)
+ conf.set10('HAVE_DECL_GETRANDOM', true)
+else
+ have = cc.has_function('getrandom', prefix : '''#include <linux/random.h>''')
+ conf.set10('HAVE_DECL_GETRANDOM', have)
+endif
+
+#####################################################################
+
+sed = find_program('sed')
+grep = find_program('grep')
+awk = find_program('awk')
+m4 = find_program('m4')
+stat = find_program('stat')
+git = find_program('git', required : false)
+
+meson_make_symlink = meson.source_root() + '/tools/meson-make-symlink.sh'
+mkdir_p = 'mkdir -p $DESTDIR/@0@'
+test_efi_create_disk_sh = find_program('test/test-efi-create-disk.sh')
+splash_bmp = files('test/splash.bmp')
+
+# if -Dxxx-path option is found, use that. Otherwise, check in $PATH,
+# /usr/sbin, /sbin, and fall back to the default from middle column.
+progs = [['telinit', '/lib/sysvinit/telinit'],
+ ['quotaon', '/usr/sbin/quotaon' ],
+ ['quotacheck', '/usr/sbin/quotacheck' ],
+ ['kill', '/usr/bin/kill' ],
+ ['kmod', '/usr/bin/kmod' ],
+ ['kexec', '/usr/sbin/kexec' ],
+ ['sulogin', '/usr/sbin/sulogin' ],
+ ['mount', '/usr/bin/mount', 'MOUNT_PATH'],
+ ['umount', '/usr/bin/umount', 'UMOUNT_PATH'],
+ ['loadkeys', '/usr/bin/loadkeys', 'KBD_LOADKEYS'],
+ ['setfont', '/usr/bin/setfont', 'KBD_SETFONT'],
+ ]
+foreach prog : progs
+ path = get_option(prog[0] + '-path')
+ if path != ''
+ message('Using @1@ for @0@'.format(prog[0], path))
+ else
+ exe = find_program(prog[0],
+ '/usr/sbin/' + prog[0],
+ '/sbin/' + prog[0],
+ required: false)
+ path = exe.found() ? exe.path() : prog[1]
+ endif
+ name = prog.length() > 2 ? prog[2] : prog[0].to_upper()
+ conf.set_quoted(name, path)
+ substs.set(name, path)
+endforeach
+
+if run_command('ln', '--relative', '--help').returncode() != 0
+ error('ln does not support --relative')
+endif
+
+############################################################
+
+gperf = find_program('gperf')
+
+gperf_test_format = '''
+#include <string.h>
+const char * in_word_set(const char *, @0@);
+@1@
+'''
+gperf_snippet_format = 'echo foo,bar | @0@ -L ANSI-C'
+gperf_snippet = run_command('sh', '-c', gperf_snippet_format.format(gperf.path()))
+gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout())
+if cc.compiles(gperf_test)
+ gperf_len_type = 'size_t'
+else
+ gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout())
+ if cc.compiles(gperf_test)
+ gperf_len_type = 'unsigned'
+ else
+ error('unable to determine gperf len type')
+ endif
+endif
+message('gperf len type is @0@'.format(gperf_len_type))
+conf.set('GPERF_LEN_TYPE', gperf_len_type,
+ description : 'The type of gperf "len" parameter')
+
+############################################################
+
+if not cc.has_header('sys/capability.h')
+ error('POSIX caps headers not found')
+endif
+foreach header : ['linux/btrfs.h',
+ 'linux/memfd.h',
+ 'linux/vm_sockets.h',
+ 'valgrind/memcheck.h',
+ 'valgrind/valgrind.h',
+ ]
+
+ conf.set('HAVE_' + header.underscorify().to_upper(),
+ cc.has_header(header))
+endforeach
+
+############################################################
+
+conf.set_quoted('FALLBACK_HOSTNAME', get_option('fallback-hostname'))
+
+default_hierarchy = get_option('default-hierarchy')
+conf.set_quoted('DEFAULT_HIERARCHY_NAME', default_hierarchy,
+ description : 'default cgroup hierarchy as string')
+if default_hierarchy == 'legacy'
+ conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_NONE')
+elif default_hierarchy == 'hybrid'
+ conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_SYSTEMD')
+else
+ conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL')
+endif
+
+time_epoch = get_option('time-epoch')
+if time_epoch == ''
+ NEWS = files('NEWS')
+ time_epoch = run_command(stat, '-c', '%Y', NEWS).stdout()
+endif
+time_epoch = time_epoch.to_int()
+conf.set('TIME_EPOCH', time_epoch)
+
+system_uid_max = get_option('system-uid-max')
+if system_uid_max == ''
+ system_uid_max = run_command(
+ awk,
+ 'BEGIN { uid=999 } /^\s*SYS_UID_MAX\s+/ { uid=$2 } END { print uid }',
+ '/etc/login.defs').stdout()
+endif
+system_uid_max = system_uid_max.to_int()
+conf.set('SYSTEM_UID_MAX', system_uid_max)
+substs.set('systemuidmax', system_uid_max)
+message('maximum system UID is @0@'.format(system_uid_max))
+
+conf.set_quoted('NOBODY_USER_NAME', get_option('nobody-user'))
+conf.set_quoted('NOBODY_GROUP_NAME', get_option('nobody-group'))
+
+system_gid_max = get_option('system-gid-max')
+if system_gid_max == ''
+ system_gid_max = run_command(
+ awk,
+ 'BEGIN { gid=999 } /^\s*SYS_GID_MAX\s+/ { gid=$2 } END { print gid }',
+ '/etc/login.defs').stdout()
+endif
+system_gid_max = system_gid_max.to_int()
+conf.set('SYSTEM_GID_MAX', system_gid_max)
+substs.set('systemgidmax', system_gid_max)
+message('maximum system GID is @0@'.format(system_gid_max))
+
+tty_gid = get_option('tty-gid')
+conf.set('TTY_GID', tty_gid)
+substs.set('TTY_GID', tty_gid)
+
+if get_option('adm-group')
+ m4_defines += ['-DENABLE_ADM_GROUP']
+endif
+
+if get_option('wheel-group')
+ m4_defines += ['-DENABLE_WHEEL_GROUP']
+endif
+
+substs.set('DEV_KVM_MODE', get_option('dev-kvm-mode'))
+
+kill_user_processes = get_option('default-kill-user-processes')
+conf.set10('KILL_USER_PROCESSES', kill_user_processes)
+substs.set('KILL_USER_PROCESSES', kill_user_processes ? 'yes' : 'no')
+
+dns_servers = get_option('dns-servers')
+conf.set_quoted('DNS_SERVERS', dns_servers)
+substs.set('DNS_SERVERS', dns_servers)
+
+ntp_servers = get_option('ntp-servers')
+conf.set_quoted('NTP_SERVERS', ntp_servers)
+substs.set('NTP_SERVERS', ntp_servers)
+
+conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
+
+substs.set('SUSHELL', get_option('debug-shell'))
+substs.set('DEBUGTTY', get_option('debug-tty'))
+
+debug = get_option('debug')
+if debug != ''
+ foreach name : debug.split(',')
+ if name == 'hashmap'
+ conf.set('ENABLE_DEBUG_HASHMAP', true)
+ elif name == 'mmap-cache'
+ conf.set('ENABLE_DEBUG_MMAP_CACHE', true)
+ else
+ message('unknown debug option "@0@", ignoring'.format(name))
+ endif
+ endforeach
+endif
+
+#####################################################################
+
+threads = dependency('threads')
+librt = cc.find_library('rt')
+libm = cc.find_library('m')
+libdl = cc.find_library('dl')
+libcrypt = cc.find_library('crypt')
+
+libcap = dependency('libcap', required : false)
+if not libcap.found()
+ # Compat with Ubuntu 14.04 which ships libcap w/o .pc file
+ libcap = cc.find_library('cap')
+endif
+
+libmount = dependency('mount',
+ version : '>= 2.27')
+
+want_seccomp = get_option('seccomp')
+if want_seccomp != 'false'
+ libseccomp = dependency('libseccomp',
+ version : '>= 2.3.1',
+ required : want_seccomp == 'true')
+ if libseccomp.found()
+ conf.set('HAVE_SECCOMP', true)
+ m4_defines += ['-DHAVE_SECCOMP']
+ endif
+else
+ libseccomp = []
+endif
+
+want_selinux = get_option('selinux')
+if want_selinux != 'false'
+ libselinux = dependency('libselinux',
+ version : '>= 2.1.9',
+ required : want_selinux == 'true')
+ if libselinux.found()
+ conf.set('HAVE_SELINUX', true)
+ m4_defines += ['-DHAVE_SELINUX']
+ endif
+else
+ libselinux = []
+endif
+
+want_apparmor = get_option('apparmor')
+if want_apparmor != 'false'
+ libapparmor = dependency('libapparmor',
+ required : want_apparmor == 'true')
+ if libapparmor.found()
+ conf.set('HAVE_APPARMOR', true)
+ m4_defines += ['-DHAVE_APPARMOR']
+ endif
+else
+ libapparmor = []
+endif
+
+smack_run_label = get_option('smack-run-label')
+if smack_run_label != ''
+ conf.set_quoted('SMACK_RUN_LABEL', smack_run_label)
+ m4_defines += ['-DHAVE_SMACK_RUN_LABEL']
+endif
+
+want_polkit = get_option('polkit')
+install_polkit = false
+install_polkit_pkla = false
+if want_polkit != 'false'
+ conf.set('ENABLE_POLKIT', true)
+ install_polkit = true
+
+ libpolkit = dependency('polkit-gobject-1',
+ required : false)
+ if libpolkit.found() and libpolkit.version().version_compare('< 0.106')
+ message('Old polkit detected, will install pkla files')
+ install_polkit_pkla = true
+ endif
+endif
+
+want_acl = get_option('acl')
+if want_acl != 'false'
+ libacl = cc.find_library('acl', required : want_acl == 'true')
+ if libacl.found()
+ conf.set('HAVE_ACL', true)
+ m4_defines += ['-DHAVE_ACL']
+ endif
+else
+ libacl = []
+endif
+
+want_audit = get_option('audit')
+if want_audit != 'false'
+ libaudit = dependency('audit', required : want_audit == 'true')
+ conf.set('HAVE_AUDIT', libaudit.found())
+else
+ libaudit = []
+endif
+
+want_blkid = get_option('blkid')
+if want_blkid != 'false'
+ libblkid = dependency('blkid', required : want_blkid == 'true')
+ conf.set('HAVE_BLKID', libblkid.found())
+else
+ libblkid = []
+endif
+
+want_kmod = get_option('kmod')
+if want_kmod != 'false'
+ libkmod = dependency('libkmod',
+ version : '>= 15',
+ required : want_kmod == 'true')
+ conf.set('HAVE_KMOD', libkmod.found())
+else
+ libkmod = []
+endif
+
+want_pam = get_option('pam')
+if want_pam != 'false'
+ libpam = cc.find_library('pam', required : want_pam == 'true')
+ libpam_misc = cc.find_library('pam_misc', required : want_pam == 'true')
+ if libpam.found() and libpam_misc.found()
+ conf.set('HAVE_PAM', true)
+ m4_defines += ['-DHAVE_PAM']
+ endif
+else
+ libpam = []
+ libpam_misc = []
+endif
+
+want_microhttpd = get_option('microhttpd')
+if want_microhttpd != 'false'
+ libmicrohttpd = dependency('libmicrohttpd',
+ version : '>= 0.9.33',
+ required : want_microhttpd == 'true')
+ if libmicrohttpd.found()
+ conf.set('HAVE_MICROHTTPD', true)
+ m4_defines += ['-DHAVE_MICROHTTPD']
+ endif
+else
+ libmicrohttpd = []
+endif
+
+want_libcryptsetup = get_option('libcryptsetup')
+if want_libcryptsetup != 'false'
+ libcryptsetup = dependency('libcryptsetup',
+ version : '>= 1.6.0',
+ required : want_libcryptsetup == 'true')
+ conf.set('HAVE_LIBCRYPTSETUP', libcryptsetup.found())
+else
+ libcryptsetup = []
+endif
+
+want_libcurl = get_option('libcurl')
+if want_libcurl != 'false'
+ libcurl = dependency('libcurl',
+ version : '>= 7.32.0',
+ required : want_libcurl == 'true')
+ if libcurl.found()
+ conf.set('HAVE_LIBCURL', true)
+ m4_defines += ['-DHAVE_LIBCURL']
+ endif
+else
+ libcurl = []
+endif
+
+want_libidn = get_option('libidn')
+want_libidn2 = get_option('libidn2')
+if want_libidn == 'true' and want_libidn2 == 'true'
+ error('libidn and libidn2 cannot be requested simultaneously')
+endif
+
+if want_libidn != 'false' and want_libidn2 != 'true'
+ libidn = dependency('libidn',
+ required : want_libidn == 'true')
+ if libidn.found()
+ conf.set('HAVE_LIBIDN', true)
+ m4_defines += ['-DHAVE_LIBIDN']
+ endif
+else
+ libidn = []
+endif
+if not conf.get('HAVE_LIBIDN', false) and want_libidn2 != 'false'
+ # libidn is used for both libidn and libidn2 objects
+ libidn = dependency('libidn2',
+ required : want_libidn2 == 'true')
+ if libidn.found()
+ conf.set('HAVE_LIBIDN2', true)
+ m4_defines += ['-DHAVE_LIBIDN2']
+ endif
+endif
+
+want_libiptc = get_option('libiptc')
+if want_libiptc != 'false'
+ libiptc = dependency('libiptc',
+ required : want_libiptc == 'true')
+ if libiptc.found()
+ conf.set('HAVE_LIBIPTC', true)
+ m4_defines += ['-DHAVE_LIBIPTC']
+ endif
+else
+ libiptc = []
+endif
+
+want_qrencode = get_option('qrencode')
+if want_qrencode != 'false'
+ libqrencode = dependency('libqrencode',
+ required : want_qrencode == 'true')
+ conf.set('HAVE_QRENCODE', libqrencode.found())
+else
+ libqrencode = []
+endif
+
+want_gnutls = get_option('gnutls')
+if want_gnutls != 'false'
+ libgnutls = dependency('gnutls',
+ version : '>= 3.1.4',
+ required : want_gnutls == 'true')
+ conf.set('HAVE_GNUTLS', libgnutls.found())
+else
+ libgnutls = []
+endif
+
+want_elfutils = get_option('elfutils')
+if want_elfutils != 'false'
+ libdw = dependency('libdw',
+ required : want_elfutils == 'true')
+ conf.set('HAVE_ELFUTILS', libdw.found())
+else
+ libdw = []
+endif
+
+want_zlib = get_option('zlib')
+if want_zlib != 'false'
+ libz = dependency('zlib',
+ required : want_zlib == 'true')
+ conf.set('HAVE_ZLIB', libz.found())
+else
+ libz = []
+endif
+
+want_bzip2 = get_option('bzip2')
+if want_bzip2 != 'false'
+ libbzip2 = cc.find_library('bz2',
+ required : want_bzip2 == 'true')
+ conf.set('HAVE_BZIP2', libbzip2.found())
+else
+ libbzip2 = []
+endif
+
+want_xz = get_option('xz')
+if want_xz != 'false'
+ libxz = dependency('liblzma',
+ required : want_xz == 'true')
+ conf.set('HAVE_XZ', libxz.found())
+else
+ libxz = []
+endif
+
+want_lz4 = get_option('lz4')
+if want_lz4 != 'false'
+ liblz4 = dependency('liblz4',
+ required : want_lz4 == 'true')
+ conf.set('HAVE_LZ4', liblz4.found())
+else
+ liblz4 = []
+endif
+
+want_glib = get_option('glib')
+if want_glib != 'false'
+ libglib = dependency('glib-2.0',
+ version : '>= 2.22.0',
+ required : want_glib == 'true')
+ libgobject = dependency('gobject-2.0',
+ version : '>= 2.22.0',
+ required : want_glib == 'true')
+ libgio = dependency('gio-2.0',
+ required : want_glib == 'true')
+ have = libglib.found() and libgobject.found() and libgio.found()
+ conf.set('HAVE_GLIB', have)
+else
+ libglib = []
+ libgobject = []
+ libgio = []
+endif
+
+want_xkbcommon = get_option('xkbcommon')
+if want_xkbcommon != 'false'
+ libxkbcommon = dependency('xkbcommon',
+ version : '>= 0.3.0',
+ required : want_xkbcommon == 'true')
+ conf.set('HAVE_XKBCOMMON', libxkbcommon.found())
+else
+ libxkbcommon = []
+endif
+
+want_dbus = get_option('dbus')
+if want_dbus != 'false'
+ libdbus = dependency('dbus-1',
+ version : '>= 1.3.2',
+ required : want_dbus == 'true')
+ conf.set('HAVE_DBUS', libdbus.found())
+else
+ libdbus = []
+endif
+
+want_gcrypt = get_option('gcrypt')
+if want_gcrypt != 'false'
+ libgcrypt = cc.find_library('gcrypt', required : want_gcrypt == 'true')
+ libgpg_error = cc.find_library('gpg-error', required : want_gcrypt == 'true')
+
+ have_deps = libgcrypt.found() and libgpg_error.found()
+ conf.set('HAVE_GCRYPT', have_deps)
+ if not have_deps
+ # link to neither of the libs if one is not found
+ libgcrypt = []
+ libgpg_error = []
+ endif
+else
+ libgcrypt = []
+ libgpg_error = []
+endif
+
+default_dnssec = get_option('default-dnssec')
+if default_dnssec != 'no' and not conf.get('HAVE_GCRYPT', false)
+ message('default-dnssec cannot be set to yes or allow-downgrade when gcrypt is disabled. Setting default-dnssec to no.')
+ default_dnssec = 'no'
+endif
+conf.set('DEFAULT_DNSSEC_MODE',
+ 'DNSSEC_' + default_dnssec.underscorify().to_upper())
+substs.set('DEFAULT_DNSSEC_MODE', default_dnssec)
+
+want_importd = get_option('importd')
+if want_importd != 'false'
+ have_deps = (conf.get('HAVE_LIBCURL', false) and
+ conf.get('HAVE_ZLIB', false) and
+ conf.get('HAVE_BZIP2', false) and
+ conf.get('HAVE_XZ', false) and
+ conf.get('HAVE_GCRYPT', false))
+ conf.set('ENABLE_IMPORTD', have_deps)
+ if want_importd == 'true' and not have_deps
+ error('importd support was requested, but dependencies are not available')
+ endif
+endif
+
+want_remote = get_option('remote')
+if want_remote != 'false'
+ have_deps = [conf.get('HAVE_MICROHTTPD', false),
+ conf.get('HAVE_LIBCURL', false)]
+ # sd-j-remote requires µhttpd, and sd-j-upload requires libcurl, so
+ # it's possible to build one without the other. Complain only if
+ # support was explictly requested. The auxiliary files like sysusers
+ # config should be installed when any of the programs are built.
+ if want_remote == 'true' and not (have_deps[0] and have_deps[1])
+ error('remote support was requested, but dependencies are not available')
+ endif
+ conf.set('ENABLE_REMOTE', have_deps[0] or have_deps[1])
+endif
+
+foreach pair : [['utmp', 'HAVE_UTMP'],
+ ['hibernate', 'ENABLE_HIBERNATE'],
+ ['environment-d', 'ENABLE_ENVIRONMENT_D'],
+ ['binfmt', 'ENABLE_BINFMT'],
+ ['coredump', 'ENABLE_COREDUMP'],
+ ['resolve', 'ENABLE_RESOLVED'],
+ ['logind', 'ENABLE_LOGIND'],
+ ['hostnamed', 'ENABLE_HOSTNAMED'],
+ ['localed', 'ENABLE_LOCALED'],
+ ['machined', 'ENABLE_MACHINED'],
+ ['networkd', 'ENABLE_NETWORKD'],
+ ['timedated', 'ENABLE_TIMEDATED'],
+ ['timesyncd', 'ENABLE_TIMESYNCD'],
+ ['myhostname', 'HAVE_MYHOSTNAME'],
+ ['firstboot', 'ENABLE_FIRSTBOOT'],
+ ['randomseed', 'ENABLE_RANDOMSEED'],
+ ['backlight', 'ENABLE_BACKLIGHT'],
+ ['vconsole', 'ENABLE_VCONSOLE'],
+ ['quotacheck', 'ENABLE_QUOTACHECK'],
+ ['sysusers', 'ENABLE_SYSUSERS'],
+ ['tmpfiles', 'ENABLE_TMPFILES'],
+ ['hwdb', 'ENABLE_HWDB'],
+ ['rfkill', 'ENABLE_RFKILL'],
+ ['ldconfig', 'ENABLE_LDCONFIG'],
+ ['efi', 'ENABLE_EFI'],
+ ['tpm', 'SD_BOOT_LOG_TPM'],
+ ['ima', 'HAVE_IMA'],
+ ['smack', 'HAVE_SMACK'],
+ ['gshadow', 'ENABLE_GSHADOW'],
+ ['idn', 'ENABLE_IDN'],
+ ['nss-systemd', 'ENABLE_NSS_SYSTEMD'],
+ ]
+
+ if get_option(pair[0])
+ conf.set(pair[1], true)
+ m4_defines += ['-D' + pair[1]]
+ endif
+endforeach
+
+want_tests = get_option('tests')
+install_tests = get_option('install-tests')
+tests = []
+
+#####################################################################
+
+if get_option('efi')
+ efi_arch = host_machine.cpu_family()
+
+ if efi_arch == 'x86'
+ EFI_MACHINE_TYPE_NAME = 'ia32'
+ gnu_efi_arch = 'ia32'
+ elif efi_arch == 'x86_64'
+ EFI_MACHINE_TYPE_NAME = 'x64'
+ gnu_efi_arch = 'x86_64'
+ elif efi_arch == 'arm'
+ EFI_MACHINE_TYPE_NAME = 'arm'
+ gnu_efi_arch = 'arm'
+ elif efi_arch == 'aarch64'
+ EFI_MACHINE_TYPE_NAME = 'aa64'
+ gnu_efi_arch = 'aarch64'
+ else
+ EFI_MACHINE_TYPE_NAME = ''
+ gnu_efi_arch = ''
+ endif
+
+ conf.set('ENABLE_EFI', true)
+ conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
+
+ conf.set('SD_TPM_PCR', get_option('tpm-pcrindex').to_int())
+endif
+
+#####################################################################
+
+config_h = configure_file(
+ output : 'config.h',
+ configuration : conf)
+
+includes = include_directories('src/basic',
+ 'src/shared',
+ 'src/systemd',
+ 'src/journal',
+ 'src/resolve',
+ 'src/timesync',
+ 'src/login',
+ 'src/udev',
+ 'src/libudev',
+ 'src/core',
+ 'src/libsystemd/sd-bus',
+ 'src/libsystemd/sd-device',
+ 'src/libsystemd/sd-hwdb',
+ 'src/libsystemd/sd-id128',
+ 'src/libsystemd/sd-netlink',
+ 'src/libsystemd/sd-network',
+ 'src/libsystemd-network',
+ )
+
+add_project_arguments('-include', 'config.h', language : 'c')
+
+gcrypt_util_sources = files('src/shared/gcrypt-util.h',
+ 'src/shared/gcrypt-util.c')
+
+subdir('po')
+subdir('catalog')
+subdir('src/systemd')
+subdir('src/basic')
+subdir('src/libsystemd')
+subdir('src/libsystemd-network')
+subdir('src/journal')
+subdir('src/login')
+
+libjournal_core = static_library(
+ 'journal-core',
+ libjournal_core_sources,
+ journald_gperf_c,
+ include_directories : includes,
+ install : false)
+
+libsystemd_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libsystemd_sym)
+libsystemd = shared_library(
+ 'systemd',
+ libsystemd_internal_sources,
+ journal_internal_sources,
+ version : '0.19.0',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + libsystemd_sym_path],
+ link_with : [libbasic],
+ dependencies : [threads,
+ libgcrypt,
+ librt,
+ libxz,
+ liblz4],
+ link_depends : libsystemd_sym,
+ install : true,
+ install_dir : rootlibdir)
+
+############################################################
+
+# binaries that have --help and are intended for use by humans,
+# usually, but not always, installed in /bin.
+public_programs = []
+
+subdir('src/libudev')
+subdir('src/shared')
+subdir('src/core')
+subdir('src/udev')
+subdir('src/network')
+
+subdir('src/analyze')
+subdir('src/journal-remote')
+subdir('src/coredump')
+subdir('src/hostname')
+subdir('src/import')
+subdir('src/kernel-install')
+subdir('src/locale')
+subdir('src/machine')
+subdir('src/nspawn')
+subdir('src/resolve')
+subdir('src/timedate')
+subdir('src/timesync')
+subdir('src/vconsole')
+subdir('src/sulogin-shell')
+subdir('src/boot/efi')
+
+subdir('src/test')
+subdir('test')
+
+############################################################
+
+# only static linking apart from libdl, to make sure that the
+# module is linked to all libraries that it uses.
+test_dlopen = executable(
+ 'test-dlopen',
+ test_dlopen_c,
+ include_directories : includes,
+ link_with : [libbasic],
+ dependencies : [libdl])
+
+foreach tuple : [['myhostname', 'HAVE_MYHOSTNAME'],
+ ['systemd', 'ENABLE_NSS_SYSTEMD'],
+ ['mymachines', 'ENABLE_MACHINED'],
+ ['resolve', 'ENABLE_RESOLVED']]
+
+ condition = tuple[1] == '' or conf.get(tuple[1], false)
+ if condition
+ module = tuple[0]
+
+ sym = 'src/nss-@0@/nss-@0@.sym'.format(module)
+ version_script_arg = join_paths(meson.current_source_dir(), sym)
+
+ nss = shared_library(
+ 'nss_' + module,
+ 'src/nss-@0@/nss-@0@.c'.format(module),
+ version : '2',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + version_script_arg,
+ '-Wl,--undefined'],
+ link_with : [libsystemd_internal,
+ libbasic],
+ dependencies : [threads,
+ librt],
+ link_depends : sym,
+ install : true,
+ install_dir : rootlibdir)
+
+ # We cannot use shared_module because it does not support version suffix.
+ # Unfortunately shared_library insists on creating the symlink…
+ meson.add_install_script('sh', '-c',
+ 'rm $DESTDIR@0@/libnss_@1@.so'
+ .format(rootlibdir, module))
+
+ test('dlopen-nss_' + module,
+ test_dlopen,
+ args : [nss.full_path()]) # path to dlopen must include a slash
+ endif
+endforeach
+
+############################################################
+
+executable('systemd',
+ systemd_sources,
+ include_directories : includes,
+ link_with : [libcore,
+ libshared],
+ dependencies : [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-analyze',
+ systemd_analyze_sources,
+ include_directories : includes,
+ link_with : [libcore,
+ libshared],
+ dependencies : [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+executable('systemd-journald',
+ systemd_journald_sources,
+ include_directories : includes,
+ link_with : [libjournal_core,
+ libshared],
+ dependencies : [threads,
+ libxz,
+ liblz4,
+ libselinux],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-cat',
+ systemd_cat_sources,
+ include_directories : includes,
+ link_with : [libjournal_core,
+ libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('journalctl',
+ journalctl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libqrencode,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-getty-generator',
+ 'src/getty-generator/getty-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+executable('systemd-debug-generator',
+ 'src/debug-generator/debug-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+executable('systemd-fstab-generator',
+ 'src/fstab-generator/fstab-generator.c',
+ 'src/core/mount-setup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+if conf.get('ENABLE_ENVIRONMENT_D', false)
+ executable('30-systemd-environment-d-generator',
+ 'src/environment-d-generator/environment-d-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : userenvgeneratordir)
+
+ meson.add_install_script(meson_make_symlink,
+ join_paths(sysconfdir, 'environment'),
+ join_paths(environmentdir, '99-environment.conf'))
+endif
+
+if conf.get('ENABLE_HIBERNATE', false)
+ executable('systemd-hibernate-resume-generator',
+ 'src/hibernate-resume/hibernate-resume-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ executable('systemd-hibernate-resume',
+ 'src/hibernate-resume/hibernate-resume.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('HAVE_BLKID', false)
+ executable('systemd-gpt-auto-generator',
+ 'src/gpt-auto-generator/gpt-auto-generator.c',
+ 'src/basic/blkid-util.h',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : libblkid,
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ exe = executable('systemd-dissect',
+ 'src/dissect/dissect.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_RESOLVED', false)
+ executable('systemd-resolved',
+ systemd_resolved_sources,
+ gcrypt_util_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libgcrypt,
+ libgpg_error,
+ libm,
+ libidn],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('systemd-resolve',
+ systemd_resolve_sources,
+ gcrypt_util_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libgcrypt,
+ libgpg_error,
+ libm,
+ libidn],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_LOGIND', false)
+ executable('systemd-logind',
+ systemd_logind_sources,
+ include_directories : includes,
+ link_with : [liblogind_core,
+ libshared],
+ dependencies : [threads,
+ libacl],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('loginctl',
+ loginctl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ liblz4,
+ libxz],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+
+ exe = executable('systemd-inhibit',
+ 'src/login/inhibit.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+
+ if conf.get('HAVE_PAM', false)
+ version_script_arg = join_paths(meson.current_source_dir(), pam_systemd_sym)
+ pam_systemd = shared_library(
+ 'pam_systemd',
+ pam_systemd_c,
+ name_prefix : '',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + version_script_arg],
+ link_with : [libsystemd_internal,
+ libshared_static],
+ dependencies : [threads,
+ libpam,
+ libpam_misc],
+ link_depends : pam_systemd_sym,
+ install : true,
+ install_dir : pamlibdir)
+
+ test('dlopen-pam_systemd',
+ test_dlopen,
+ args : [pam_systemd.full_path()]) # path to dlopen must include a slash
+ endif
+endif
+
+if conf.get('HAVE_PAM', false)
+ executable('systemd-user-sessions',
+ 'src/user-sessions/user-sessions.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_EFI', false) and conf.get('HAVE_BLKID', false)
+ exe = executable('bootctl',
+ 'src/boot/bootctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libblkid],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+exe = executable('systemd-socket-activate', 'src/activate/activate.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemctl', 'src/systemctl/systemctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libcap,
+ libselinux,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+if conf.get('ENABLE_BACKLIGHT', false)
+ executable('systemd-backlight',
+ 'src/backlight/backlight.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_RFKILL', false)
+ executable('systemd-rfkill',
+ 'src/rfkill/rfkill.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+executable('systemd-system-update-generator',
+ 'src/system-update-generator/system-update-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+if conf.get('HAVE_LIBCRYPTSETUP', false)
+ executable('systemd-cryptsetup',
+ 'src/cryptsetup/cryptsetup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ executable('systemd-cryptsetup-generator',
+ 'src/cryptsetup/cryptsetup-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ executable('systemd-veritysetup',
+ 'src/veritysetup/veritysetup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ executable('systemd-veritysetup-generator',
+ 'src/veritysetup/veritysetup-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcryptsetup],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+endif
+
+if conf.get('HAVE_SYSV_COMPAT', false)
+ executable('systemd-sysv-generator',
+ 'src/sysv-generator/sysv-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+
+ executable('systemd-rc-local-generator',
+ 'src/rc-local-generator/rc-local-generator.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : systemgeneratordir)
+endif
+
+if conf.get('ENABLE_HOSTNAMED', false)
+ executable('systemd-hostnamed',
+ 'src/hostname/hostnamed.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('hostnamectl',
+ 'src/hostname/hostnamectl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_LOCALED', false)
+ if conf.get('HAVE_XKBCOMMON', false)
+ # logind will load libxkbcommon.so dynamically on its own
+ deps = [libdl]
+ else
+ deps = []
+ endif
+
+ executable('systemd-localed',
+ systemd_localed_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : deps,
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('localectl',
+ localectl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_TIMEDATED', false)
+ executable('systemd-timedated',
+ 'src/timedate/timedated.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('timedatectl',
+ 'src/timedate/timedatectl.c',
+ include_directories : includes,
+ install_rpath : rootlibexecdir,
+ link_with : [libshared],
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_TIMESYNCD', false)
+ executable('systemd-timesyncd',
+ systemd_timesyncd_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libm],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_MACHINED', false)
+ executable('systemd-machined',
+ systemd_machined_sources,
+ include_directories : includes,
+ link_with : [libmachine_core,
+ libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('machinectl',
+ 'src/machine/machinectl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_IMPORTD', false)
+ executable('systemd-importd',
+ systemd_importd_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ systemd_pull = executable('systemd-pull',
+ systemd_pull_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcurl,
+ libz,
+ libbzip2,
+ libxz,
+ libgcrypt],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ systemd_import = executable('systemd-import',
+ systemd_import_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcurl,
+ libz,
+ libbzip2,
+ libxz],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ systemd_export = executable('systemd-export',
+ systemd_export_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcurl,
+ libz,
+ libbzip2,
+ libxz],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [systemd_pull, systemd_import, systemd_export]
+endif
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_LIBCURL', false)
+ exe = executable('systemd-journal-upload',
+ systemd_journal_upload_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libcurl,
+ libgnutls,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_MICROHTTPD', false)
+ s_j_remote = executable('systemd-journal-remote',
+ systemd_journal_remote_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libmicrohttpd,
+ libgnutls,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ s_j_gatewayd = executable('systemd-journal-gatewayd',
+ systemd_journal_gatewayd_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libmicrohttpd,
+ libgnutls,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [s_j_remote, s_j_gatewayd]
+endif
+
+if conf.get('ENABLE_COREDUMP', false)
+ executable('systemd-coredump',
+ systemd_coredump_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libacl,
+ libdw,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ exe = executable('coredumpctl',
+ coredumpctl_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads,
+ libxz,
+ liblz4],
+ install_rpath : rootlibexecdir,
+ install : true)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_BINFMT', false)
+ exe = executable('systemd-binfmt',
+ 'src/binfmt/binfmt.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+ public_programs += [exe]
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(binfmtdir))
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'binfmt.d')))
+endif
+
+if conf.get('ENABLE_VCONSOLE', false)
+ executable('systemd-vconsole-setup',
+ 'src/vconsole/vconsole-setup.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_RANDOMSEED', false)
+ executable('systemd-random-seed',
+ 'src/random-seed/random-seed.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+if conf.get('ENABLE_FIRSTBOOT', false)
+ executable('systemd-firstboot',
+ 'src/firstboot/firstboot.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libcrypt],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+endif
+
+executable('systemd-remount-fs',
+ 'src/remount-fs/remount-fs.c',
+ 'src/core/mount-setup.c',
+ 'src/core/mount-setup.h',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-machine-id-setup',
+ 'src/machine-id-setup/machine-id-setup-main.c',
+ 'src/core/machine-id-setup.c',
+ 'src/core/machine-id-setup.h',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+
+executable('systemd-fsck',
+ 'src/fsck/fsck.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-sleep',
+ 'src/sleep/sleep.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-sysctl',
+ 'src/sysctl/sysctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+public_programs += [exe]
+
+executable('systemd-ac-power',
+ 'src/ac-power/ac-power.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-detect-virt',
+ 'src/detect-virt/detect-virt.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-delta',
+ 'src/delta/delta.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-escape',
+ 'src/escape/escape.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+exe = executable('systemd-notify',
+ 'src/notify/notify.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-volatile-root',
+ 'src/volatile-root/volatile-root.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-cgroups-agent',
+ 'src/cgroups-agent/cgroups-agent.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-path',
+ 'src/path/path.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-ask-password',
+ 'src/ask-password/ask-password.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-reply-password',
+ 'src/reply-password/reply-password.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-tty-ask-password-agent',
+ 'src/tty-ask-password-agent/tty-ask-password-agent.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+exe = executable('systemd-cgls',
+ 'src/cgls/cgls.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-cgtop',
+ 'src/cgtop/cgtop.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+executable('systemd-initctl',
+ 'src/initctl/initctl.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+exe = executable('systemd-mount',
+ 'src/mount/mount-tool.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+meson.add_install_script(meson_make_symlink,
+ 'systemd-mount', join_paths(bindir, 'systemd-umount'))
+
+exe = executable('systemd-run',
+ 'src/run/run.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('systemd-stdio-bridge',
+ 'src/stdio-bridge/stdio-bridge.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+exe = executable('busctl',
+ 'src/busctl/busctl.c',
+ 'src/busctl/busctl-introspect.c',
+ 'src/busctl/busctl-introspect.h',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+if conf.get('ENABLE_SYSUSERS', false)
+ exe = executable('systemd-sysusers',
+ 'src/sysusers/sysusers.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_TMPFILES', false)
+ exe = executable('systemd-tmpfiles',
+ 'src/tmpfiles/tmpfiles.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libacl],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_HWDB', false)
+ exe = executable('systemd-hwdb',
+ 'src/hwdb/hwdb.c',
+ 'src/libsystemd/sd-hwdb/hwdb-internal.h',
+ include_directories : includes,
+ link_with : [libudev_internal],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : rootbindir)
+ public_programs += [exe]
+endif
+
+if conf.get('ENABLE_QUOTACHECK', false)
+ executable('systemd-quotacheck',
+ 'src/quotacheck/quotacheck.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+exe = executable('systemd-socket-proxyd',
+ 'src/socket-proxy/socket-proxyd.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+public_programs += [exe]
+
+exe = executable('systemd-udevd',
+ systemd_udevd_sources,
+ include_directories : includes,
+ c_args : ['-DLOG_REALM=LOG_REALM_UDEV'],
+ link_with : [libudev_core,
+ libsystemd_network,
+ libudev_internal],
+ dependencies : [threads,
+ libkmod,
+ libidn,
+ libacl,
+ libblkid],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : rootlibexecdir)
+public_programs += [exe]
+
+exe = executable('udevadm',
+ udevadm_sources,
+ include_directories : includes,
+ link_with : [libudev_core,
+ libsystemd_network,
+ libudev_internal],
+ dependencies : [threads,
+ libkmod,
+ libidn,
+ libacl,
+ libblkid],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+executable('systemd-shutdown',
+ systemd_shutdown_sources,
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-update-done',
+ 'src/update-done/update-done.c',
+ include_directories : includes,
+ link_with : [libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+executable('systemd-update-utmp',
+ 'src/update-utmp/update-utmp.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libaudit],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+if conf.get('HAVE_KMOD', false)
+ executable('systemd-modules-load',
+ 'src/modules-load/modules-load.c',
+ include_directories : includes,
+ link_with : [libshared],
+ dependencies : [libkmod],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(modulesloaddir))
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'modules-load.d')))
+endif
+
+exe = executable('systemd-nspawn',
+ systemd_nspawn_sources,
+ 'src/core/mount-setup.c', # FIXME: use a variable?
+ 'src/core/mount-setup.h',
+ 'src/core/loopback-setup.c',
+ 'src/core/loopback-setup.h',
+ include_directories : [includes, include_directories('src/nspawn')],
+ link_with : [libshared],
+ dependencies : [libacl,
+ libblkid,
+ libseccomp,
+ libselinux],
+ install_rpath : rootlibexecdir,
+ install : true)
+public_programs += [exe]
+
+if conf.get('ENABLE_NETWORKD', false)
+ executable('systemd-networkd',
+ systemd_networkd_sources,
+ include_directories : includes,
+ link_with : [libnetworkd_core,
+ libsystemd_network,
+ libudev_internal,
+ libshared],
+ dependencies : [threads],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+
+ executable('systemd-networkd-wait-online',
+ systemd_networkd_wait_online_sources,
+ include_directories : includes,
+ link_with : [libnetworkd_core,
+ libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootlibexecdir)
+endif
+
+exe = executable('networkctl',
+ networkctl_sources,
+ include_directories : includes,
+ link_with : [libsystemd_network,
+ libshared],
+ install_rpath : rootlibexecdir,
+ install : true,
+ install_dir : rootbindir)
+public_programs += [exe]
+
+############################################################
+
+foreach tuple : tests
+ sources = tuple[0]
+ link_with = tuple[1].length() > 0 ? tuple[1] : [libshared]
+ dependencies = tuple[2]
+ condition = tuple.length() >= 4 ? tuple[3] : ''
+ type = tuple.length() >= 5 ? tuple[4] : ''
+ defs = tuple.length() >= 6 ? tuple[5] : []
+ incs = tuple.length() >= 7 ? tuple[6] : includes
+ timeout = 30
+
+ name = sources[0].split('/')[-1].split('.')[0]
+ if type.startswith('timeout=')
+ timeout = type.split('=')[1].to_int()
+ type = ''
+ endif
+
+ if condition == '' or conf.get(condition, false)
+ exe = executable(
+ name,
+ sources,
+ include_directories : incs,
+ link_with : link_with,
+ dependencies : dependencies,
+ c_args : defs,
+ install_rpath : rootlibexecdir,
+ install : install_tests,
+ install_dir : join_paths(testsdir, type))
+
+ if type == 'manual'
+ message('@0@ is a manual test'.format(name))
+ elif type == 'unsafe' and want_tests != 'unsafe'
+ message('@0@ is an unsafe test'.format(name))
+ else
+ test(name, exe,
+ env : test_env,
+ timeout : timeout)
+ endif
+ else
+ message('Not compiling @0@ because @1@ is not true'.format(name, condition))
+ endif
+endforeach
+
+test_libsystemd_sym = executable(
+ 'test-libsystemd-sym',
+ test_libsystemd_sym_c,
+ include_directories : includes,
+ link_with : [libsystemd],
+ install : install_tests,
+ install_dir : testsdir)
+test('test-libsystemd-sym',
+ test_libsystemd_sym)
+
+test_libudev_sym = executable(
+ 'test-libudev-sym',
+ test_libudev_sym_c,
+ include_directories : includes,
+ c_args : ['-Wno-deprecated-declarations'],
+ link_with : [libudev],
+ install : install_tests,
+ install_dir : testsdir)
+test('test-libudev-sym',
+ test_libudev_sym)
+
+############################################################
+
+make_directive_index_py = find_program('tools/make-directive-index.py')
+make_man_index_py = find_program('tools/make-man-index.py')
+xml_helper_py = find_program('tools/xml_helper.py')
+hwdb_update_sh = find_program('tools/meson-hwdb-update.sh')
+
+subdir('units')
+subdir('sysctl.d')
+subdir('sysusers.d')
+subdir('tmpfiles.d')
+subdir('rules')
+subdir('hwdb')
+subdir('network')
+subdir('man')
+subdir('shell-completion/bash')
+subdir('shell-completion/zsh')
+subdir('docs/sysvinit')
+subdir('docs/var-log')
+
+# FIXME: figure out if the warning is true:
+# https://github.com/mesonbuild/meson/wiki/Reference-manual#install_subdir
+install_subdir('factory/etc',
+ install_dir : factorydir)
+
+
+install_data('xorg/50-systemd-user.sh',
+ install_dir : xinitrcdir)
+install_data('system-preset/90-systemd.preset',
+ install_dir : systempresetdir)
+install_data('README',
+ 'NEWS',
+ 'CODING_STYLE',
+ 'DISTRO_PORTING',
+ 'ENVIRONMENT.md',
+ 'LICENSE.GPL2',
+ 'LICENSE.LGPL2.1',
+ 'src/libsystemd/sd-bus/GVARIANT-SERIALIZATION',
+ install_dir : docdir)
+
+meson.add_install_script('sh', '-c', mkdir_p.format(systemdstatedir))
+meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir))
+
+############################################################
+
+meson_check_help = find_program('tools/meson-check-help.sh')
+
+foreach exec : public_programs
+ name = exec.full_path().split('/')[-1]
+ test('check-help-' + name,
+ meson_check_help,
+ args : [exec.full_path()])
+endforeach
+
+############################################################
+
+if git.found()
+ all_files = run_command(
+ git,
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
+ 'ls-files',
+ ':/*.[ch]'])
+ all_files = files(all_files.stdout().split())
+
+ run_target(
+ 'tags',
+ input : all_files,
+ command : ['env', 'etags', '-o', '@0@/TAGS'.format(meson.source_root())] + all_files)
+ run_target(
+ 'ctags',
+ input : all_files,
+ command : ['env', 'ctags', '-o', '@0@/tags'.format(meson.source_root())] + all_files)
+endif
+
+if git.found()
+ meson_git_contrib_sh = find_program('tools/meson-git-contrib.sh')
+ run_target(
+ 'git-contrib',
+ command : [meson_git_contrib_sh])
+endif
+
+if git.found()
+ git_head = run_command(
+ git,
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
+ 'rev-parse', 'HEAD']).stdout().strip()
+ git_head_short = run_command(
+ git,
+ ['--git-dir=@0@/.git'.format(meson.source_root()),
+ 'rev-parse', '--short=7', 'HEAD']).stdout().strip()
+
+ run_target(
+ 'git-snapshot',
+ command : ['git', 'archive',
+ '-o', '@0@/systemd-@1@.tar.gz'.format(meson.source_root(),
+ git_head_short),
+ '--prefix', 'systemd-@0@/'.format(git_head),
+ 'HEAD'])
+endif
+
+############################################################
+
+status = [
+ '@0@ @1@'.format(meson.project_name(), meson.project_version()),
+
+ 'prefix: @0@'.format(prefixdir),
+ 'rootprefix: @0@'.format(rootprefixdir),
+ 'sysconf dir: @0@'.format(sysconfdir),
+ 'includedir: @0@'.format(includedir),
+ 'lib dir: @0@'.format(libdir),
+ 'rootlib dir: @0@'.format(rootlibdir),
+ 'SysV init scripts: @0@'.format(sysvinit_path),
+ 'SysV rc?.d directories: @0@'.format(sysvrcnd_path),
+ 'PAM modules dir: @0@'.format(pamlibdir),
+ 'PAM configuration dir: @0@'.format(pamconfdir),
+ 'RPM macros dir: @0@'.format(rpmmacrosdir),
+ 'D-Bus policy dir: @0@'.format(dbuspolicydir),
+ 'D-Bus session dir: @0@'.format(dbussessionservicedir),
+ 'D-Bus system dir: @0@'.format(dbussystemservicedir),
+ 'bash completions dir: @0@'.format(bashcompletiondir),
+ 'zsh completions dir: @0@'.format(zshcompletiondir),
+ 'extra start script: @0@'.format(get_option('rc-local')),
+ 'extra stop script: @0@'.format(get_option('halt-local')),
+ 'debug shell: @0@ @ @1@'.format(get_option('debug-shell'),
+ get_option('debug-tty')),
+ 'TTY GID: @0@'.format(tty_gid),
+ 'maximum system UID: @0@'.format(system_uid_max),
+ 'maximum system GID: @0@'.format(system_gid_max),
+ '/dev/kvm access mode: @0@'.format(get_option('dev-kvm-mode')),
+ 'certificate root: @0@'.format(get_option('certificate-root')),
+ 'support URL: @0@'.format(support_url),
+ 'nobody user name: @0@'.format(get_option('nobody-user')),
+ 'nobody group name: @0@'.format(get_option('nobody-group')),
+ 'fallback hostname: @0@'.format(get_option('fallback-hostname')),
+
+ 'default DNSSEC mode: @0@'.format(default_dnssec),
+ 'default cgroup hierarchy: @0@'.format(default_hierarchy),
+ 'default KillUserProcesses setting: @0@'.format(kill_user_processes)]
+
+alt_dns_servers = '\n '.join(dns_servers.split(' '))
+alt_ntp_servers = '\n '.join(ntp_servers.split(' '))
+status += [
+ 'default DNS servers: @0@'.format(alt_dns_servers),
+ 'default NTP servers: @0@'.format(alt_ntp_servers)]
+
+alt_time_epoch = run_command('date', '-Is', '-u', '-d',
+ '@@0@'.format(time_epoch)).stdout().strip()
+status += [
+ 'time epoch: @0@ (@1@)'.format(time_epoch, alt_time_epoch)]
+
+# TODO:
+# CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
+# CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
+# LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS}
+
+if conf.get('ENABLE_EFI', false)
+ status += [
+ 'efi arch: @0@'.format(efi_arch)]
+
+ if have_gnu_efi
+ status += [
+ 'EFI machine type: @0@'.format(EFI_MACHINE_TYPE_NAME),
+ 'EFI CC @0@'.format(efi_cc),
+ 'EFI libdir: @0@'.format(efi_libdir),
+ 'EFI ldsdir: @0@'.format(efi_ldsdir),
+ 'EFI includedir: @0@'.format(efi_incdir)]
+ endif
+endif
+
+found = []
+missing = []
+
+foreach tuple : [
+ ['libcryptsetup'],
+ ['PAM'],
+ ['AUDIT'],
+ ['IMA'],
+ ['AppArmor'],
+ ['SELinux'],
+ ['SECCOMP'],
+ ['SMACK'],
+ ['zlib'],
+ ['xz'],
+ ['lz4'],
+ ['bzip2'],
+ ['ACL'],
+ ['gcrypt'],
+ ['qrencode'],
+ ['microhttpd'],
+ ['gnutls'],
+ ['libcurl'],
+ ['idn'],
+ ['libidn2'],
+ ['libidn'],
+ ['nss-systemd'],
+ ['libiptc'],
+ ['elfutils'],
+ ['binfmt'],
+ ['vconsole'],
+ ['quotacheck'],
+ ['tmpfiles'],
+ ['environment.d'],
+ ['sysusers'],
+ ['firstboot'],
+ ['randomseed'],
+ ['backlight'],
+ ['rfkill'],
+ ['logind'],
+ ['machined'],
+ ['importd'],
+ ['hostnamed'],
+ ['timedated'],
+ ['timesyncd'],
+ ['localed'],
+ ['networkd'],
+ ['resolved'],
+ ['coredump'],
+ ['polkit'],
+ ['legacy pkla', install_polkit_pkla],
+ ['efi'],
+ ['gnu-efi', have_gnu_efi],
+ ['kmod'],
+ ['xkbcommon'],
+ ['blkid'],
+ ['dbus'],
+ ['glib'],
+ ['nss-myhostname', conf.get('HAVE_MYHOSTNAME', false)],
+ ['hwdb'],
+ ['tpm'],
+ ['man pages', want_man],
+ ['html pages', want_html],
+ ['man page indices', want_man and have_lxml],
+ ['split /usr', conf.get('HAVE_SPLIT_USR', false)],
+ ['SysV compat'],
+ ['utmp'],
+ ['ldconfig'],
+ ['hibernate'],
+ ['adm group', get_option('adm-group')],
+ ['wheel group', get_option('wheel-group')],
+ ['gshadow'],
+ ['debug hashmap'],
+ ['debug mmap cache'],
+]
+
+ cond = tuple.get(1, '')
+ if cond == ''
+ ident1 = 'HAVE_' + tuple[0].underscorify().to_upper()
+ ident2 = 'ENABLE_' + tuple[0].underscorify().to_upper()
+ cond = conf.get(ident1, false) or conf.get(ident2, false)
+ endif
+ if cond
+ found += [tuple[0]]
+ else
+ missing += [tuple[0]]
+ endif
+endforeach
+
+status += [
+ 'enabled features: @0@'.format(', '.join(found)),
+ 'disabled features: @0@'.format(', '.join(missing))]
+message('\n '.join(status))
--- /dev/null
+# -*- mode: meson -*-
+
+option('split-usr', type : 'boolean', value : false,
+ description : '''assume that /bin, /sbin aren't symlinks into /usr''')
+option('rootlibdir', type : 'string',
+ description : '''[/usr]/lib/x86_64-linux-gnu or such''')
+option('rootprefix', type : 'string',
+ description : '''override the root prefix''')
+option('link-udev-shared', type : 'boolean',
+ description : 'link systemd-udev and its helpers to libsystemd-shared.so')
+
+option('sysvinit-path', type : 'string', value : '/etc/init.d',
+ description : 'the directory where the SysV init scripts are located')
+option('sysvrcnd-path', type : 'string', value : '/etc/rc.d',
+ description : 'the base directory for SysV rcN.d directories')
+option('telinit-path', type : 'string', description : 'path to telinit')
+option('rc-local', type : 'string',
+ value : '/etc/rc.local')
+option('halt-local', type : 'string',
+ value : '/usr/sbin/halt.local')
+
+option('quotaon-path', type : 'string', description : 'path to quotaon')
+option('quotacheck-path', type : 'string', description : 'path to quotacheck')
+option('kill-path', type : 'string', description : 'path to kill')
+option('kmod-path', type : 'string', description : 'path to kmod')
+option('kexec-path', type : 'string', description : 'path to kexec')
+option('sulogin-path', type : 'string', description : 'path to sulogin')
+option('mount-path', type : 'string', description : 'path to mount')
+option('umount-path', type : 'string', description : 'path to umount')
+option('loadkeys-path', type : 'string', description : 'path to loadkeys')
+option('setfont-path', type : 'string', description : 'path to setfont')
+
+option('debug-shell', type : 'string', value : '/bin/sh',
+ description : 'path to debug shell binary')
+option('debug-tty', type : 'string', value : '/dev/tty9',
+ description : 'specify the tty device for debug shell')
+option('debug', type : 'string',
+ description : 'enable extra debugging (hashmap,mmap-cache)')
+
+option('utmp', type : 'boolean',
+ description : 'support for utmp/wtmp log handling')
+option('hibernate', type : 'boolean',
+ description : 'support for hibernation')
+option('ldconfig', type : 'boolean',
+ description : 'support for dynamic linker cache creation')
+option('resolve', type : 'boolean',
+ description : 'systemd-resolved stack')
+option('efi', type : 'boolean',
+ description : 'enable systemd-boot and bootctl')
+option('tpm', type : 'boolean', value : false,
+ description : 'TPM should be used to log events and extend the registers')
+option('environment-d', type : 'boolean',
+ description : 'support for environment.d')
+option('binfmt', type : 'boolean',
+ description : 'support for custom binary formats')
+option('coredump', type : 'boolean',
+ description : 'install the coredump handler')
+option('logind', type : 'boolean',
+ description : 'install the systemd-logind stack')
+option('hostnamed', type : 'boolean',
+ description : 'install the systemd-hostnamed stack')
+option('localed', type : 'boolean',
+ description : 'install the systemd-localed stack')
+option('machined', type : 'boolean',
+ description : 'install the systemd-machined stack')
+option('networkd', type : 'boolean',
+ description : 'install the systemd-networkd stack')
+option('timedated', type : 'boolean',
+ description : 'install the systemd-timedated daemon')
+option('timesyncd', type : 'boolean',
+ description : 'install the systemd-timesyncd daemon')
+option('remote', type : 'boolean',
+ description : 'support for "journal over the network"')
+option('myhostname', type : 'boolean',
+ description : 'nss-myhostname support')
+option('firstboot', type : 'boolean',
+ description : 'support for firstboot mechanism')
+option('randomseed', type : 'boolean',
+ description : 'support for restoring random seed')
+option('backlight', type : 'boolean',
+ description : 'support for restoring backlight state')
+option('vconsole', type : 'boolean',
+ description : 'support for vconsole configuration')
+option('quotacheck', type : 'boolean',
+ description : 'support for the quotacheck tools')
+option('sysusers', type : 'boolean',
+ description : 'support for the sysusers configuration')
+option('tmpfiles', type : 'boolean',
+ description : 'support for tmpfiles.d')
+option('importd', type : 'boolean',
+ description : 'install the systemd-importd daemon')
+option('hwdb', type : 'boolean',
+ description : 'support for the hardware database')
+option('rfkill', type : 'boolean',
+ description : 'support for the rfkill tools')
+option('man', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'build and install man pages')
+option('html', type : 'combo', choices : ['auto', 'true', 'false'],
+ value : 'false',
+ description : 'build and install html pages')
+
+option('certificate-root', type : 'string', value : '/etc/ssl',
+ description : 'the prefix for TLS certificates')
+option('dbuspolicydir', type : 'string',
+ description : 'D-Bus policy directory')
+option('dbussessionservicedir', type : 'string',
+ description : 'D-Bus session service directory')
+option('dbussystemservicedir', type : 'string',
+ description : 'D-Bus system service directory')
+option('pkgconfigdatadir', type : 'string', value : 'share/pkgconfig',
+ description : 'directory for ')
+option('pkgconfiglibdir', type : 'string', value : '',
+ description : 'directory for ')
+option('rpmmacrosdir', type : 'string', value : 'lib/rpm/macros.d',
+ description : 'directory for rpm macros ["no" disables]')
+option('pamlibdir', type : 'string',
+ description : 'directory for PAM modules')
+option('pamconfdir', type : 'string',
+ description : 'directory for PAM configuration ["no" disables]')
+
+option('fallback-hostname', type : 'string', value : 'localhost',
+ description : 'the hostname used if none configured')
+option('default-hierarchy', type : 'combo',
+ choices : ['legacy', 'hybrid', 'unified'], value : 'hybrid',
+ description : 'default cgroup hierarchy')
+option('time-epoch', type : 'string',
+ description : 'time epoch for time clients')
+option('system-uid-max', type : 'string',
+ description : 'maximum system UID')
+option('system-gid-max', type : 'string',
+ description : 'maximum system GID')
+option('tty-gid', type : 'string',
+ description : 'the numeric GID of the "tty" group',
+ value : '5')
+option('adm-group', type : 'boolean',
+ description : 'the ACL for adm group should be added')
+option('wheel-group', type : 'boolean',
+ description : 'the ACL for wheel group should be added')
+option('nobody-user', type : 'string',
+ description : 'The name of the nobody user (the one with UID 65534)',
+ value : 'nobody')
+option('nobody-group', type : 'string',
+ description : 'The name of the nobody group (the one with GID 65534)',
+ value : 'nobody')
+option('dev-kvm-mode', type : 'string', value : '0660',
+ description : '/dev/kvm access mode')
+option('default-kill-user-processes', type : 'boolean',
+ description : 'the default value for KillUserProcesses= setting')
+option('gshadow', type : 'boolean',
+ description : 'support for shadow group')
+
+option('default-dnssec', type : 'combo',
+ description : 'default DNSSEC mode',
+ choices : ['yes', 'allow-downgrade', 'no'],
+ value : 'allow-downgrade')
+option('dns-servers', type : 'string',
+ description : 'space-separated list of default DNS servers',
+ value : '8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844')
+option('ntp-servers', type : 'string',
+ description : 'space-separated list of default NTP servers',
+ value : 'time1.google.com time2.google.com time3.google.com time4.google.com')
+option('support-url', type : 'string',
+ description : 'the support URL to show in catalog entries included in systemd',
+ value : 'https://lists.freedesktop.org/mailman/listinfo/systemd-devel')
+option('www-target', type : 'string',
+ description : 'the address and dir to upload docs too',
+ value : 'www.freedesktop.org:/srv/www.freedesktop.org/www/software/systemd')
+
+option('seccomp', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'SECCOMP support')
+option('selinux', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'SELinux support')
+option('apparmor', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'AppArmor support')
+option('smack', type : 'boolean',
+ description : 'SMACK support')
+option('smack-run-label', type : 'string',
+ description : 'run systemd --system itself with a specific SMACK label')
+option('polkit', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'PolicyKit support')
+option('ima', type : 'boolean',
+ description : 'IMA support')
+
+option('acl', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libacl support')
+option('audit', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libaudit support')
+option('blkid', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libblkid support')
+option('kmod', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'support for loadable modules')
+option('pam', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'PAM support')
+option('microhttpd', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libµhttpd support')
+option('libcryptsetup', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libcryptsetup support')
+option('libcurl', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libcurl support')
+option('idn', type : 'boolean',
+ description : 'use IDN when printing host names')
+option('libidn2', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libidn2 support')
+option('libidn', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libidn support')
+option('nss-systemd', type : 'boolean',
+ description : 'enable nss-systemd')
+option('libiptc', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libiptc support')
+option('qrencode', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libqrencode support')
+option('gcrypt', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'gcrypt support')
+option('gnutls', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'gnutls support')
+option('elfutils', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'elfutils support')
+option('zlib', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'zlib compression support')
+option('bzip2', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'bzip2 compression support')
+option('xz', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'xz compression support')
+option('lz4', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'lz4 compression support')
+option('xkbcommon', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'xkbcommon keymap support')
+option('glib', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libglib support (for tests only)')
+option('dbus', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'libdbus support (for tests only)')
+
+option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'gnu-efi support for sd-boot')
+option('efi-cc', type : 'string', value : 'gcc',
+ description : 'the compiler to use for EFI modules')
+option('efi-ld', type : 'string', value : 'ld',
+ description : 'the linker to use for EFI modules')
+option('efi-libdir', type : 'string',
+ description : 'path to the EFI lib directory')
+option('efi-ldsdir', type : 'string',
+ description : 'path to the EFI lds directory')
+option('efi-includedir', type : 'string', value : '/usr/include/efi',
+ description : 'path to the EFI header directory')
+option('tpm-pcrindex', type : 'string', value : '8',
+ description : 'TPM PCR register number to use')
+
+option('bashcompletiondir', type : 'string',
+ description : 'directory for bash completion scripts ["no" disables]')
+option('zshcompletiondir', type : 'string',
+ description : 'directory for zsh completion scripts ["no" disables]')
+
+option('tests', type : 'combo', choices : ['true', 'unsafe'],
+ description : 'enable extra tests with =unsafe')
+option('install-tests', type : 'boolean', value : 'false',
+ description : 'install test executables')
# This is a build script for OS image generation using mkosi (https://github.com/systemd/mkosi).
# Simply invoke "mkosi" in the project directory to build an OS image.
-./autogen.sh c
-make -j `nproc`
-
-make check
-make install
+export LC_CTYPE=C.UTF-8
+meson build
+ninja -C build all
+ninja -C build test
+ninja -C build install
mkdir -p $DESTDIR/etc
--- /dev/null
+if conf.get('ENABLE_NETWORKD', false)
+ install_data('80-container-host0.network',
+ '80-container-ve.network',
+ '80-container-vz.network',
+ install_dir : networkdir)
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'systemd/network')))
+endif
+
+install_data('99-default.link',
+ install_dir : networkdir)
# Czech translation for systemd.
-# Copyright (C) 2016 systemd's author and translators.
+# Copyright (C) 2016-2017 systemd's author and translators.
# This file is distributed under the same license as the systemd package.
-# Daniel Maixner <xskipy@gmail.com>, 2016
-# Daniel Rusek <mail@asciiwolf.com>, 2016
+# Daniel Maixner <xskipy@gmail.com>, 2016.
+# Daniel Rusek <mail@asciiwolf.com>, 2016, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
"POT-Creation-Date: 2016-04-23 14:24+0200\n"
-"PO-Revision-Date: 2017-02-07 18:38+0100\n"
+"PO-Revision-Date: 2017-04-20 23:00+0200\n"
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
msgid "Authentication is required to send the entered passphrase back to the system."
-msgstr "Autentizace je vyžadována pro odeslání zadaného hesla do systému."
+msgstr "Pro odeslání zadaného hesla do systému je vyžadováno ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
msgid "Manage system services or other units"
-msgstr "Správa systémových služeb nebo dalších jednotek"
+msgstr "Spravovat systémové služby nebo další jednotky"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
msgid "Authentication is required to manage system services or other units."
-msgstr ""
-"Autentizace je vyžadována pro správu systémových služeb nebo dalších jednotek."
+msgstr "Pro správu systémových služeb nebo dalších jednotek je vyžadováno ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
msgid "Manage system service or unit files"
-msgstr "Správa systémové služby nebo souborů jednotky"
+msgstr "Spravovat systémové služby nebo soubory jednotek"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
msgid "Authentication is required to manage system service or unit files."
-msgstr "Autentizace je vyžadována pro správu systémové služby nebo souborů jednotky."
+msgstr "Pro správu systémových služeb nebo souborů jednotek je vyžadováno ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
msgid "Set or unset system and service manager environment variables"
-msgstr "Nastavení nebo rušení proměnných správce systému a služeb"
+msgstr "Nastavit nebo rušit proměnné správce systému a služeb"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
msgid ""
"Authentication is required to set or unset system and service manager environment "
"variables."
msgstr ""
-"Autentizace je vyžadována pro nastavení nebo rušení proměnných správce systému a "
-"služeb."
+"Pro nastavení nebo rušení proměnných správce systému a služeb je vyžadováno "
+"ověření."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
msgid "Authentication is required to reload the systemd state."
-msgstr "Autentizace je vyžadována pro znovu načtení stavu systemd."
+msgstr "Pro znovu načtení stavu systemd je vyžadováno ověření."
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
msgid "Set host name"
-msgstr "Nastavení názvu stroje"
+msgstr "Nastavit název stroje"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
msgid "Authentication is required to set the local host name."
-msgstr "Autentizace je vyžadována pro nastavení lokálního názvu stroje."
+msgstr "Pro nastavení lokálního názvu stroje je vyžadováno ověření."
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
msgid "Set static host name"
-msgstr "Nastavení statického názvu stoje"
+msgstr "Nastavit statický název stoje"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
msgid ""
"Authentication is required to set the statically configured local host name, as "
"well as the pretty host name."
msgstr ""
-"Autentizace je vyžadována pro nastavení staticky konfigurovaného názvu lokálního "
-"stroje, stejně tak pro změnu uživatelsky přívětivého jména."
+"Pro nastavení staticky konfigurovaného názvu lokálního stroje, stejně tak pro "
+"změnu uživatelsky přívětivého jména je vyžadováno ověření."
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
msgid "Set machine information"
-msgstr "Nastavení informací o stroji"
+msgstr "Nastavit informace o stroji"
#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
msgid "Authentication is required to set local machine information."
-msgstr "Autentizace je vyžadována pro nastavení informací o stroji."
+msgstr "Pro nastavení informací o stroji je vyžadováno ověření."
#: ../src/import/org.freedesktop.import1.policy.in.h:1
msgid "Import a VM or container image"
-msgstr "Import obrazu virtuální stroje nebo kontejneru"
+msgstr "Importovat obraz virtuální stroje nebo kontejneru"
#: ../src/import/org.freedesktop.import1.policy.in.h:2
msgid "Authentication is required to import a VM or container image"
-msgstr ""
-"Autentizace je vyžadována pro import obrazu virtuálního stroje nebo kontejneru"
+msgstr "Pro import obrazu virtuálního stroje nebo kontejneru je vyžadováno ověření"
#: ../src/import/org.freedesktop.import1.policy.in.h:3
msgid "Export a VM or container image"
-msgstr "Export obrazu virtuálního stroje nebo kontejneru"
+msgstr "Exportovat obraz virtuálního stroje nebo kontejneru"
#: ../src/import/org.freedesktop.import1.policy.in.h:4
msgid "Authentication is required to export a VM or container image"
-msgstr ""
-"Autentizace je vyžadována pro export obrazu virtuálního stroje nebo kontejneru"
+msgstr "Pro export obrazu virtuálního stroje nebo kontejneru je vyžadováno ověření"
#: ../src/import/org.freedesktop.import1.policy.in.h:5
msgid "Download a VM or container image"
#: ../src/import/org.freedesktop.import1.policy.in.h:6
msgid "Authentication is required to download a VM or container image"
-msgstr ""
-"Autentizace je vyžadována pro stažení obrazu virtuálního stroje nebo kontejneru"
+msgstr "Pro stažení obrazu virtuálního stroje nebo kontejneru je vyžadováno ověření"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
msgid "Set system locale"
-msgstr "Nastavení lokalizace systému"
+msgstr "Nastavit lokalizaci systému"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
msgid "Authentication is required to set the system locale."
-msgstr "Autentizace je vyžadována pro nastavení lokalizace systému."
+msgstr "Pro nastavení lokalizace systému je vyžadováno ověření."
#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
msgid "Set system keyboard settings"
-msgstr "Nastavení systémové konfigurace klávesnice"
+msgstr "Nastavit systémovou konfiguraci klávesnice"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
msgid "Authentication is required to set the system keyboard settings."
-msgstr "Autentizace je vyžadována pro nastavení systémové konfigurace klávesnice."
+msgstr "Pro nastavení systémové konfigurace klávesnice je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:1
msgid "Allow applications to inhibit system shutdown"
#: ../src/login/org.freedesktop.login1.policy.in.h:2
msgid "Authentication is required for an application to inhibit system shutdown."
-msgstr "Autentizace je vyžadována pro povolení aplikacím zakázat vypnutí systému."
+msgstr "Pro povolení aplikacím zakázat vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:3
msgid "Allow applications to delay system shutdown"
#: ../src/login/org.freedesktop.login1.policy.in.h:4
msgid "Authentication is required for an application to delay system shutdown."
-msgstr "Autentizace je vyžadována pro povolení aplikacím odložit vypnutí systému."
+msgstr "Pro povolení aplikacím odložit vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:5
msgid "Allow applications to inhibit system sleep"
#: ../src/login/org.freedesktop.login1.policy.in.h:6
msgid "Authentication is required for an application to inhibit system sleep."
-msgstr "Autentizace je vyžadována pro povolení aplikacím zakázat uspání systému."
+msgstr "Pro povolení aplikacím zakázat uspání systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:7
msgid "Allow applications to delay system sleep"
#: ../src/login/org.freedesktop.login1.policy.in.h:8
msgid "Authentication is required for an application to delay system sleep."
-msgstr "Autentizace je vyžadována pro povolení aplikacím odložit uspání systému."
+msgstr "Pro povolení aplikacím odložit uspání systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:9
msgid "Allow applications to inhibit automatic system suspend"
msgid ""
"Authentication is required for an application to inhibit automatic system suspend."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat automatické vypnutí "
-"systému."
+"Pro povolení aplikacím zakázat automatické vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:11
msgid "Allow applications to inhibit system handling of the power key"
"Authentication is required for an application to inhibit system handling of the "
"power key."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"stisknutí vypínacího tlačítka."
+"Pro povolení aplikacím zakázat chovaní systému na stisknutí vypínacího tlačítka je "
+"vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:13
msgid "Allow applications to inhibit system handling of the suspend key"
"Authentication is required for an application to inhibit system handling of the "
"suspend key."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"stisknutí uspávacího tlačítka."
+"Pro povolení aplikacím zakázat chovaní systému na stisknutí uspávacího tlačítka je "
+"vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:15
msgid "Allow applications to inhibit system handling of the hibernate key"
"Authentication is required for an application to inhibit system handling of the "
"hibernate key."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"stisknutí tlačítka hibernace."
+"Pro povolení aplikacím zakázat chovaní systému na stisknutí tlačítka hibernace je "
+"vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:17
msgid "Allow applications to inhibit system handling of the lid switch"
"Authentication is required for an application to inhibit system handling of the "
"lid switch."
msgstr ""
-"Autentizace je vyžadována pro povolení aplikacím zakázat chovaní systému na "
-"zavření víka."
+"Pro povolení aplikacím zakázat chovaní systému na zavření víka je vyžadováno "
+"ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
msgid "Allow non-logged-in user to run programs"
#: ../src/login/org.freedesktop.login1.policy.in.h:20
msgid "Explicit request is required to run programs as a non-logged-in user."
msgstr ""
-"Speciální požadavek je třeba ke spuštění programů jako nepřihlášený uživatel."
+"Ke spuštění programů jako nepřihlášený uživatel je třeba speciální požadavek."
#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
-msgstr "Autentizace je vyžadována ke spuštění programů jako nepřihlášený uživatel."
+msgstr "Ke spuštění programů jako nepřihlášený uživatel je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Allow attaching devices to seats"
-msgstr "Povolit připojování zařízení ke stanovišti"
+msgstr "Povolit připojování zařízení ke stanovištím"
#: ../src/login/org.freedesktop.login1.policy.in.h:24
msgid "Authentication is required for attaching a device to a seat."
-msgstr "Autentizace je vyžadována pro připojování zařízení ke stanovišti."
+msgstr "Pro připojování zařízení ke stanovišti je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:25
msgid "Flush device to seat attachments"
-msgstr "Odstranění přiřazení zařízení ke stanovištím"
+msgstr "Odstranit přiřazení zařízení ke stanovištím"
#: ../src/login/org.freedesktop.login1.policy.in.h:26
msgid "Authentication is required for resetting how devices are attached to seats."
msgstr ""
-"Autentizace je vyžadována pro reset způsobu jak jsou zařízení přiřazována ke "
-"stanovištím."
+"Pro reset způsobu jak jsou zařízení přiřazována ke stanovištím je vyžadováno "
+"ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
-msgstr "Vypnutí systému"
+msgstr "Vypnout systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:28
msgid "Authentication is required for powering off the system."
-msgstr "Autentizace je vyžadována pro vypnutí systému."
+msgstr "Pro vypnutí systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:29
msgid "Power off the system while other users are logged in"
"Authentication is required for powering off the system while other users are "
"logged in."
msgstr ""
-"Autentizace je vyžadována pro vypnutí systému, když jsou přihlášeni další "
-"uživatelé."
+"Pro vypnutí systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:31
msgid "Power off the system while an application asked to inhibit it"
"Authentication is required for powering off the system while an application asked "
"to inhibit it."
msgstr ""
-"Autentizace je vyžadována pro vypnutí systému, když aplikace požádala o zákaz "
-"vypnutí."
+"Pro vypnutí systému, když aplikace požádala o zákaz vypnutí je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
#: ../src/login/org.freedesktop.login1.policy.in.h:34
msgid "Authentication is required for rebooting the system."
-msgstr "Autentizace je vyžadována pro restartovaní systému."
+msgstr "Pro restartování systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:35
msgid "Reboot the system while other users are logged in"
"Authentication is required for rebooting the system while other users are logged "
"in."
msgstr ""
-"Autentizace je vyžadována pro restart systému, když jsou přihlášeni další "
-"uživatelé."
+"Pro restartování systému, když jsou přihlášeni další uživatelé je vyžadováno "
+"ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:37
msgid "Reboot the system while an application asked to inhibit it"
"Authentication is required for rebooting the system while an application asked to "
"inhibit it."
msgstr ""
-"Autentizace je vyžadována pro restart systému, když aplikace požádala o zákaz "
-"restartu."
+"Pro restartování systému, když aplikace požádala o zákaz restartu je vyžadováno "
+"ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
-msgstr "Uspání systému"
+msgstr "Uspat systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
-msgstr "Autentizace je vyžadována pro uspání systému."
+msgstr "Pro uspání systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
"Authentication is required for suspending the system while other users are logged "
"in."
msgstr ""
-"Autentizace je vyžadována pro uspání systému, když jsou přihlášeni další uživatelé."
+"Pro uspání systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
"Authentication is required for suspending the system while an application asked to "
"inhibit it."
msgstr ""
-"Autentizace je vyžadována pro uspání systému, když aplikace požádala o zákaz "
-"uspání."
+"Pro uspání systému, když aplikace požádala o zákaz uspání je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
-msgstr "Hibernace systému"
+msgstr "Hibernovat systém"
#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
-msgstr "Autentizace je vyžadována k hibernaci systému."
+msgstr "Pro hibernaci systému je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
"Authentication is required for hibernating the system while other users are logged "
"in."
msgstr ""
-"Autentizace je vyžadována pro hibernaci systému, když jsou přihlášeni další "
-"uživatelé."
+"Pro hibernaci systému, když jsou přihlášeni další uživatelé je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
-msgstr "Hibernace systému, i když aplikace požádala o zákaz hibernace"
+msgstr "Hibernovat systém, i když aplikace požádala o zákaz hibernace"
#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application asked "
"to inhibit it."
msgstr ""
-"Autentizace je vyžadována pro hibernaci systému, když aplikace požádala o zákaz "
-"hibernace."
+"Pro hibernaci systému, když aplikace požádala o zákaz hibernace je vyžadováno "
+"ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
-msgstr "Správa aktivních sezení, uživatelů a stanovišť"
+msgstr "Spravovat aktivní sezení, uživatele a stanoviště"
#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid "Authentication is required for managing active sessions, users and seats."
-msgstr ""
-"Autentizace je vyžadována pro správu aktivních sezení, uživatelů a stanovišť."
+msgstr "Pro správu aktivních sezení, uživatelů a stanovišť je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
-msgstr "Zamčení nebo odemčení aktivních sezení"
+msgstr "Zamknout nebo odemknout aktivní sezení"
#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
-msgstr "Autentizace je vyžadována pro zamčení nebo odemčení aktivních sezení."
+msgstr "Pro zamčení nebo odemčení aktivních sezení je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Allow indication to the firmware to boot to setup interface"
msgid ""
"Authentication is required to indicate to the firmware to boot to setup interface."
msgstr ""
-"Autentizace je vyžadována k povolení indikace firmwaru bootovat instalační "
-"prostředí."
+"K povolení indikace firmwaru bootovat instalační prostředí je vyžadováno ověření."
#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
-msgstr "Autentizace je vyžadována k nastavení zprávy všem uživatelům"
+msgstr "K nastavení zprávy všem uživatelům je vyžadováno ověření"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
msgid "Log into a local container"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
msgid "Authentication is required to log into a local container."
-msgstr "Autentizace je vyžadována pro přihlášení do lokálního kontejneru."
+msgstr "Pro přihlášení do lokálního kontejneru je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
msgid "Log into the local host"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
msgid "Authentication is required to log into the local host."
-msgstr "Autentizace je vyžadována pro přihlášení k lokálnímu stroji."
+msgstr "Pro přihlášení k lokálnímu stroji je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
msgid "Acquire a shell in a local container"
-msgstr "Získání shellu v lokálním kontejneru"
+msgstr "Získat shell v lokálním kontejneru"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
msgid "Authentication is required to acquire a shell in a local container."
-msgstr "Autentizace je vyžadována pro získání shellu v lokálním kontejneru."
+msgstr "Pro získání shellu v lokálním kontejneru je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
msgid "Acquire a shell on the local host"
-msgstr "Získání shellu na lokálním stroji"
+msgstr "Získat shell na lokálním stroji"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
msgid "Authentication is required to acquire a shell on the local host."
-msgstr "Autentizace je vyžadována pro získání shellu na lokálním stroji."
+msgstr "Pro získání shellu na lokálním stroji je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
msgid "Acquire a pseudo TTY in a local container"
-msgstr "Získání Pseudo TTY v lokálním kontejneru"
+msgstr "Získat pseudo TTY v lokálním kontejneru"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
msgid "Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "Autentizace je vyžadována pro získání pseudo TTY v lokálním kontejneru."
+msgstr "Pro získání pseudo TTY v lokálním kontejneru je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
msgid "Acquire a pseudo TTY on the local host"
-msgstr "Získání pseudo TTY na lokálním stroji"
+msgstr "Získat pseudo TTY na lokálním stroji"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "Autentizace je vyžadována pro získání pseudo TTY na lokálním stroji."
+msgstr "Pro získání pseudo TTY na lokálním stroji je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
msgid "Manage local virtual machines and containers"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
msgid "Authentication is required to manage local virtual machines and containers."
-msgstr ""
-"Autentizace je vyžadována pro správu lokálních virtuálních strojů a kontejnerů."
+msgstr "Pro správu lokálních virtuálních strojů a kontejnerů je vyžadováno ověření."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
msgid "Manage local virtual machine and container images"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
msgid ""
"Authentication is required to manage local virtual machine and container images."
-msgstr "Autentizace je vyžadována ke správě obrazů virtuálních strojů a kontejnerů."
+msgstr ""
+"Pro správu obrazů lokálních virtuálních strojů a kontejnerů je vyžadováno ověření."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
msgid "Set system time"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
msgid "Authentication is required to set the system time."
-msgstr "Autentizace je vyžadována pro nastavení systémového času."
+msgstr "Pro nastavení systémového času je vyžadováno ověření."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
msgid "Set system timezone"
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
msgid "Authentication is required to set the system timezone."
-msgstr "Autentizace je vyžadována pro nastavení systémové časové zóny."
+msgstr "Pro nastavení systémové časové zóny je vyžadováno ověření."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
msgid "Set RTC to local timezone or UTC"
msgid ""
"Authentication is required to control whether the RTC stores the local or UTC time."
msgstr ""
-"Autentizace je vyžadována pro kontrolu jestli RTC ukládá lokální časovou zónu nebo "
-"UTC čas."
+"Pro kontrolu jestli RTC ukládá lokální časovou zónu nebo UTC čas je vyžadováno "
+"ověření."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
msgid "Turn network time synchronization on or off"
msgid ""
"Authentication is required to control whether network time synchronization shall "
"be enabled."
-msgstr "Autentizace je vyžadována pro kontrolu synchronizace času ze sítě."
+msgstr "Pro kontrolu synchronizace času ze sítě je vyžadováno ověření."
#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to start '$(unit)'."
-msgstr "Autentizace je vyžadována pro spuštění „$(unit)”."
+msgstr "Pro spuštění „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:460
msgid "Authentication is required to stop '$(unit)'."
-msgstr "Autentizace je vyžadována pro vypnutí „$(unit)”."
+msgstr "Pro vypnutí „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:461
msgid "Authentication is required to reload '$(unit)'."
-msgstr "Autentizace je vyžadována pro znovu načtení „$(unit)”."
+msgstr "Pro znovu načtení „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:462 ../src/core/dbus-unit.c:463
msgid "Authentication is required to restart '$(unit)'."
-msgstr "Autentizace je vyžadována pro restart „$(unit)”."
+msgstr "Pro restart „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:570
msgid "Authentication is required to kill '$(unit)'."
-msgstr "Autentizace je vyžadována pro ukončení „$(unit)”."
+msgstr "Pro ukončení „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:601
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "Autentizace je vyžadována pro resetování chybného stavu „$(unit)”."
+msgstr "Pro resetování chybného stavu „$(unit)” je vyžadováno ověření."
#: ../src/core/dbus-unit.c:634
msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "Autentizace je vyžadována pro nastavení vlastností na „$(unit)”."
+msgstr "Pro nastavení vlastností na „$(unit)” je vyžadováno ověření."
--- /dev/null
+i18n = import('i18n')
+i18n.gettext(meson.project_name())
+
+#####################################################################
+
+intltool_merge = find_program('intltool-merge')
+po_dir = meson.current_source_dir()
+
+intltool_cache = join_paths(meson.current_build_dir(), 'intltool-merge-cache')
+intltool_command = [intltool_merge, '-x', '-u',
+ '-c', intltool_cache,
+ po_dir, '@INPUT@', '@OUTPUT@']
# Brazilian Portuguese translation for systemd.
-# Copyright (C) 2015 systemd's COPYRIGHT HOLDER
+# Copyright (C) 2017 systemd's COPYRIGHT HOLDER
# This file is distributed under the same license as the systemd package.
-# Rafael Ferreira <rafael.f.f1@gmail.com>, 2014.
# Enrico Nicoletto <liverig@gmail.com>, 2014.
-#
+# Rafael Fontenelle <rafaelff@gnome.org>, 2015, 2017.
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2015-01-10 12:23-0300\n"
-"Last-Translator: Rafael Ferreira <rafael.f.f1@gmail.com>\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2016-11-17 03:29+0000\n"
+"PO-Revision-Date: 2017-04-03 14:25-0200\n"
+"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 1.7.1\n"
+"X-Generator: Virtaal 1.0.0-beta1\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
"sistema."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
-#, fuzzy
msgid "Manage system services or other units"
-msgstr "Gerenciar unidades e serviços do sistema"
+msgstr "Gerenciar serviços do sistema e outras unidades"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
-#, fuzzy
msgid "Authentication is required to manage system services or other units."
msgstr ""
-"É necessária autenticação para gerenciar unidades e serviços do sistema."
+"É necessária autenticação para gerenciar serviços do sistema ou outras "
+"unidades."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
msgid "Manage system service or unit files"
"sistema."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
-#, fuzzy
msgid "Set or unset system and service manager environment variables"
-msgstr "Acesso privilegiado ao gerenciador de serviço e de sistema"
+msgstr ""
+"Definir ou retirar definição de variáveis de ambiente de gerenciador de "
+"serviço e sistema"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
-#, fuzzy
msgid ""
"Authentication is required to set or unset system and service manager "
"environment variables."
msgstr ""
-"É necessária autenticação para gerenciar arquivos \"unit\" e \"service\" do "
-"sistema."
+"É necessária autenticação para definir ou retirar definição de variáveis de "
+"ambiente de gerenciador de serviço e sistema."
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
msgid "Reload the systemd state"
#: ../src/import/org.freedesktop.import1.policy.in.h:1
msgid "Import a VM or container image"
-msgstr ""
+msgstr "Importar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:2
-#, fuzzy
msgid "Authentication is required to import a VM or container image"
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para importar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:3
msgid "Export a VM or container image"
-msgstr ""
+msgstr "Exportar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:4
-#, fuzzy
msgid "Authentication is required to export a VM or container image"
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para exportar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:5
msgid "Download a VM or container image"
-msgstr ""
+msgstr "Baixar uma VM ou imagem contêiner"
#: ../src/import/org.freedesktop.import1.policy.in.h:6
-#, fuzzy
msgid "Authentication is required to download a VM or container image"
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para baixar uma VM ou imagem contêiner"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
msgid "Set system locale"
"sistema sobre o interruptor da tela."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
+#| msgid "Allow non-logged-in users to run programs"
+msgid "Allow non-logged-in user to run programs"
+msgstr ""
+"Permitir que programas sejam executados por usuário que não possui sessão"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+#| msgid "Authentication is required to run programs as a non-logged-in user."
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"É necessária requisição explícita para executar programas como usuário sem "
+"sessão aberta."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
msgstr ""
"Permitir que programas sejam executados por usuários que não possuem sessão"
-#: ../src/login/org.freedesktop.login1.policy.in.h:20
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
msgstr ""
"É necessária autenticação para executar programas como usuário sem sessão "
"aberta."
-#: ../src/login/org.freedesktop.login1.policy.in.h:21
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Allow attaching devices to seats"
msgstr "Permitir conectar dispositivos em estações"
-#: ../src/login/org.freedesktop.login1.policy.in.h:22
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
msgid "Authentication is required for attaching a device to a seat."
msgstr "É necessária autenticação para conectar um dispositivo em uma estação."
-#: ../src/login/org.freedesktop.login1.policy.in.h:23
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
msgid "Flush device to seat attachments"
msgstr "Liberar dispositivo para conexões da estação"
-#: ../src/login/org.freedesktop.login1.policy.in.h:24
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
msgid ""
"Authentication is required for resetting how devices are attached to seats."
msgstr ""
"É necessária autenticação para redefinir a quantidade de dispositivos "
"conectados na estação."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
msgstr "Desligar o sistema"
-#: ../src/login/org.freedesktop.login1.policy.in.h:26
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
msgid "Authentication is required for powering off the system."
msgstr "É necessária autenticação para desligar o sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:27
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
msgid "Power off the system while other users are logged in"
msgstr "Desligar o sistema enquanto outros usuários estão conectados"
-#: ../src/login/org.freedesktop.login1.policy.in.h:28
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
msgid ""
"Authentication is required for powering off the system while other users are "
"logged in."
"É necessária autenticação para desligar o sistema enquanto outros usuários "
"estão conectados."
-#: ../src/login/org.freedesktop.login1.policy.in.h:29
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
msgid "Power off the system while an application asked to inhibit it"
msgstr "Desligar o sistema enquanto um aplicativo solicitou inibição"
-#: ../src/login/org.freedesktop.login1.policy.in.h:30
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
msgid ""
"Authentication is required for powering off the system while an application "
"asked to inhibit it."
"É necessária autenticação para desligar o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
msgstr "Reiniciar o sistema"
-#: ../src/login/org.freedesktop.login1.policy.in.h:32
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
msgid "Authentication is required for rebooting the system."
msgstr "É necessária autenticação para reiniciar o sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:33
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
msgid "Reboot the system while other users are logged in"
msgstr "Reiniciar o sistema enquanto outros usuários estiverem conectados"
-#: ../src/login/org.freedesktop.login1.policy.in.h:34
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
msgid ""
"Authentication is required for rebooting the system while other users are "
"logged in."
"É necessária autenticação para reiniciar o sistema enquanto outros usuários "
"estiverem conectados."
-#: ../src/login/org.freedesktop.login1.policy.in.h:35
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
msgid "Reboot the system while an application asked to inhibit it"
msgstr "Reiniciar o sistema enquanto um aplicativo solicitou inibição"
-#: ../src/login/org.freedesktop.login1.policy.in.h:36
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
msgid ""
"Authentication is required for rebooting the system while an application "
"asked to inhibit it."
"É necessária autenticação para reiniciar o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
msgstr "Suspender o sistema"
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
msgstr "É necessária autenticação para suspender o sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
msgstr "Suspender o sistema enquanto outros usuários estiverem conectados"
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
msgid ""
"Authentication is required for suspending the system while other users are "
"logged in."
"É necessária autenticação para suspender o sistema enquanto outros usuários "
"estiverem conectados."
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
msgstr "Suspender o sistema enquanto um aplicativo solicitou inibição"
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid ""
"Authentication is required for suspending the system while an application "
"asked to inhibit it."
"É necessária autenticação para suspender o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
msgstr "Hibernar o sistema"
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
msgstr "É necessária autenticação para hibernar o sistema."
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
msgstr "Hibernar o sistema enquanto outros usuários estiverem conectados"
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
msgid ""
"Authentication is required for hibernating the system while other users are "
"logged in."
"É necessária autenticação para hibernar o sistema enquanto outros usuários "
"estiverem conectados."
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
msgstr "Hibernar o sistema enquanto um aplicativo solicitou inibição"
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application "
"asked to inhibit it."
"É necessária autenticação para hibernar o sistema enquanto um aplicativo "
"solicitou inibição."
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
-msgstr ""
+msgstr "Gerenciar estações, usuários e sessões ativas"
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid ""
"Authentication is required for managing active sessions, users and seats."
-msgstr "É necessária autenticação para conectar um dispositivo em uma estação."
+msgstr ""
+"É necessária autenticação para gerenciar estações, usuários e sessões ativas."
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
-msgstr ""
+msgstr "Travar ou destravar sessões ativas"
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para travar ou destravar sessões ativas."
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Allow indication to the firmware to boot to setup interface"
msgstr ""
+"Permitir indicação para o firmware inicializar para a interface de "
+"configuração"
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
msgid ""
"Authentication is required to indicate to the firmware to boot to setup "
"interface."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para indicar para o firmware inicializar para a "
+"interface de configuração."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
-msgstr ""
+msgstr "Definir uma mensagem de parede"
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
-#, fuzzy
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr "É necessária autenticação para definir uma mensagem de parede"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
msgid "Log into a local container"
msgstr "Conectar a um contêiner local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
-#, fuzzy
msgid "Authentication is required to log into a local container."
msgstr "É necessária autenticação para se conectar a um contêiner local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
-#, fuzzy
msgid "Log into the local host"
-msgstr "Conectar a um contêiner local"
+msgstr "Conectar a uma máquina local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
-#, fuzzy
msgid "Authentication is required to log into the local host."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para se conectar a uma máquina local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
-#, fuzzy
msgid "Acquire a shell in a local container"
-msgstr "Conectar a um contêiner local"
+msgstr "Adquirir uma shell em um contêiner local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
-#, fuzzy
msgid "Authentication is required to acquire a shell in a local container."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr ""
+"É necessária autenticação para adquirir uma shell em um contêiner local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
msgid "Acquire a shell on the local host"
-msgstr ""
+msgstr "Adquirir uma shell na máquina local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
-#, fuzzy
msgid "Authentication is required to acquire a shell on the local host."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para adquirir uma shell em uma máquina local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
-#, fuzzy
msgid "Acquire a pseudo TTY in a local container"
-msgstr "Conectar a um contêiner local"
+msgstr "Adquirir um pseudo TTY em um contêiner local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
-#, fuzzy
msgid ""
"Authentication is required to acquire a pseudo TTY in a local container."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr ""
+"É necessária autenticação para adquirir um pseudo TTY em um contêiner local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
msgid "Acquire a pseudo TTY on the local host"
-msgstr ""
+msgstr "Adquiri um pseudo TTY na máquina local"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
-#, fuzzy
msgid "Authentication is required to acquire a pseudo TTY on the local host."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para adquirir um pseudo TTY em um máquina local."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
msgid "Manage local virtual machines and containers"
-msgstr ""
+msgstr "Gerenciar máquinas virtuais locais e contêineres"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
-#, fuzzy
msgid ""
"Authentication is required to manage local virtual machines and containers."
-msgstr "É necessária autenticação para definir informações de máquina local."
+msgstr ""
+"É necessária autenticação para gerenciar máquinas virtuais locais e "
+"contêineres."
#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
msgid "Manage local virtual machine and container images"
-msgstr ""
+msgstr "Gerenciar máquinas virtuais locais e imagens contêineres"
#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
-#, fuzzy
msgid ""
"Authentication is required to manage local virtual machine and container "
"images."
-msgstr "É necessária autenticação para definir informações de máquina local."
+msgstr ""
+"É necessária autenticação para gerenciar máquinas virtuais locais e imagens "
+"contêineres."
#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
msgid "Set system time"
"É necessária autenticação para controlar se deve ser habilitada, ou não, a "
"sincronização de horário através de rede."
-#: ../src/core/dbus-unit.c:428
-#, fuzzy
+#: ../src/core/dbus-unit.c:457
msgid "Authentication is required to start '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para iniciar '$(unit)'."
-#: ../src/core/dbus-unit.c:429
-#, fuzzy
+#: ../src/core/dbus-unit.c:458
msgid "Authentication is required to stop '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para parar '$(unit)'."
-#: ../src/core/dbus-unit.c:430
-#, fuzzy
+#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to reload '$(unit)'."
-msgstr "É necessária autenticação para recarregar o estado do sistema."
+msgstr "É necessária autenticação para recarregar '$(unit)'."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
-#, fuzzy
+#: ../src/core/dbus-unit.c:460 ../src/core/dbus-unit.c:461
msgid "Authentication is required to restart '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para reiniciar '$(unit)'."
-#: ../src/core/dbus-unit.c:535
-#, fuzzy
+#: ../src/core/dbus-unit.c:568
msgid "Authentication is required to kill '$(unit)'."
-msgstr "É necessária autenticação para se conectar a um contêiner local."
+msgstr "É necessária autenticação para matar '$(unit)'."
-#: ../src/core/dbus-unit.c:565
-#, fuzzy
+#: ../src/core/dbus-unit.c:599
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
-msgstr "É necessária autenticação para definir nome de máquina local."
+msgstr ""
+"É necessária autenticação para reiniciar o estado \"failed\" de '$(unit)'."
-#: ../src/core/dbus-unit.c:597
-#, fuzzy
+#: ../src/core/dbus-unit.c:632
msgid "Authentication is required to set properties on '$(unit)'."
-msgstr "É necessária autenticação para definir o horário do sistema."
+msgstr "É necessária autenticação para definir propriedades em '$(unit)'."
--- /dev/null
+# Slovak translation for systemd.
+# Copyright (C) 2017 systemd's COPYRIGHT HOLDER
+# This file is distributed under the same license as the systemd package.
+# Dušan Kazik <prescott66@gmail.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: systemd master\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2017-06-24 03:26+0000\n"
+"PO-Revision-Date: 2017-06-25 11:03+0200\n"
+"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
+"Language: sk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
+"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
+"X-Generator: Poedit 2.0.2\n"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
+msgid "Send passphrase back to system"
+msgstr "Odoslanie hesla späť do systému"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:2
+msgid ""
+"Authentication is required to send the entered passphrase back to the system."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na odoslanie zadaného hesla späť do systému."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:3
+msgid "Manage system services or other units"
+msgstr "Správa systémových služieb alebo iných jednotiek"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:4
+msgid "Authentication is required to manage system services or other units."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na správu systémových služieb alebo iných "
+"jednotiek."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:5
+msgid "Manage system service or unit files"
+msgstr "Správa systémovej služby alebo súborov jednotky"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:6
+msgid "Authentication is required to manage system service or unit files."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na správu systémovej služby alebo súborov "
+"jednotky."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:7
+msgid "Set or unset system and service manager environment variables"
+msgstr ""
+"Nastavenie alebo zrušenie nastavenia premenných prostredia systému a správcu "
+"služieb"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:8
+msgid ""
+"Authentication is required to set or unset system and service manager "
+"environment variables."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie alebo zrušenie nastavenia "
+"premenných prostredia systému a správcu služieb."
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:9
+msgid "Reload the systemd state"
+msgstr "Znovu načítanie stavu systému systemd"
+
+#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:10
+msgid "Authentication is required to reload the systemd state."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na znovu načítanie stavu systému systemd."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:1
+msgid "Set host name"
+msgstr "Nastavenie názvu hostiteľa"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:2
+msgid "Authentication is required to set the local host name."
+msgstr "Vyžaduje sa overenie totožnosti na nastavenie názvu hostiteľa."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:3
+msgid "Set static host name"
+msgstr "Nastavenie nemenného názvu hostiteľa"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:4
+msgid ""
+"Authentication is required to set the statically configured local host name, "
+"as well as the pretty host name."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie pevne určeného názvu miestneho "
+"hostiteľa, známeho ako zrozumiteľný názov hostiteľa."
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:5
+msgid "Set machine information"
+msgstr "Nastavenie informácií o počítači"
+
+#: ../src/hostname/org.freedesktop.hostname1.policy.in.h:6
+msgid "Authentication is required to set local machine information."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie informácií o miestnom počítači."
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:1
+msgid "Import a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:2
+msgid "Authentication is required to import a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:3
+msgid "Export a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:4
+msgid "Authentication is required to export a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:5
+msgid "Download a VM or container image"
+msgstr ""
+
+#: ../src/import/org.freedesktop.import1.policy.in.h:6
+msgid "Authentication is required to download a VM or container image"
+msgstr ""
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:1
+msgid "Set system locale"
+msgstr "Nastavenie miestnych nastavení"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:2
+msgid "Authentication is required to set the system locale."
+msgstr "Vyžaduje sa overenie totožnosti na nastavenie miestnych nastavení."
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:3
+msgid "Set system keyboard settings"
+msgstr "Nastavenie nastavení systémovej klávesnice"
+
+#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
+msgid "Authentication is required to set the system keyboard settings."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na nastavenie nastavení systémovej "
+"klávesnice."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:1
+msgid "Allow applications to inhibit system shutdown"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:2
+msgid ""
+"Authentication is required for an application to inhibit system shutdown."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:3
+msgid "Allow applications to delay system shutdown"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:4
+msgid "Authentication is required for an application to delay system shutdown."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:5
+msgid "Allow applications to inhibit system sleep"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:6
+msgid "Authentication is required for an application to inhibit system sleep."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:7
+msgid "Allow applications to delay system sleep"
+msgstr "Umožnenie aplikáciám odložiť spánok systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:8
+msgid "Authentication is required for an application to delay system sleep."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na odloženie spánku systému aplikáciou."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:9
+msgid "Allow applications to inhibit automatic system suspend"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:10
+msgid ""
+"Authentication is required for an application to inhibit automatic system "
+"suspend."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:11
+msgid "Allow applications to inhibit system handling of the power key"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:12
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the power key."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:13
+msgid "Allow applications to inhibit system handling of the suspend key"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:14
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the suspend key."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:15
+msgid "Allow applications to inhibit system handling of the hibernate key"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:16
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the hibernate key."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:17
+msgid "Allow applications to inhibit system handling of the lid switch"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:18
+msgid ""
+"Authentication is required for an application to inhibit system handling of "
+"the lid switch."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr "Umožnenie neprihlásenému používateľovi spúšťanie programov"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Vyžaduje sa explicitná požiadavka na spúšťanie programov ako neprihlásený "
+"používateľ."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
+msgid "Allow non-logged-in users to run programs"
+msgstr "Umožnenie neprihláseným používateľom spúšťanie programov"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
+msgid "Authentication is required to run programs as a non-logged-in user."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na spúšťanie programov ako neprihlásený "
+"používateľ."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
+msgid "Allow attaching devices to seats"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
+msgid "Authentication is required for attaching a device to a seat."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
+msgid "Flush device to seat attachments"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
+msgid ""
+"Authentication is required for resetting how devices are attached to seats."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
+msgid "Power off the system"
+msgstr "Vypnutie systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
+msgid "Authentication is required for powering off the system."
+msgstr "Vyžaduje sa overenie totožnosti na vypnutie systému."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
+msgid "Power off the system while other users are logged in"
+msgstr "Vypnutie systému, pokiaľ sú prihlásení iní používatelia"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
+msgid ""
+"Authentication is required for powering off the system while other users are "
+"logged in."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na vypnutie systému, pokiaľ sú prihlásení "
+"iní používatelia."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
+msgid "Power off the system while an application asked to inhibit it"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
+msgid ""
+"Authentication is required for powering off the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
+msgid "Reboot the system"
+msgstr "Reštart systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
+msgid "Authentication is required for rebooting the system."
+msgstr "Vyžaduje sa overenie totožnosti na reštartovanie systému."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
+msgid "Reboot the system while other users are logged in"
+msgstr "Reštart systému, pokiaľ sú prihlásení iní používatelia"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
+msgid ""
+"Authentication is required for rebooting the system while other users are "
+"logged in."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na reštartovanie systému, pokiaľ sú "
+"prihlásení iní používatelia."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
+msgid "Reboot the system while an application asked to inhibit it"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
+msgid ""
+"Authentication is required for rebooting the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
+msgid "Suspend the system"
+msgstr "Uspanie systému"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
+msgid "Authentication is required for suspending the system."
+msgstr "Vyžaduje sa overenie totožnosti na uspanie systému."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
+msgid "Suspend the system while other users are logged in"
+msgstr "Uspanie systému, pokiaľ sú prihlásení iní používatelia"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
+msgid ""
+"Authentication is required for suspending the system while other users are "
+"logged in."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na uspanie systému, pokiaľ sú prihlásení iní "
+"používatelia."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
+msgid "Suspend the system while an application asked to inhibit it"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
+msgid ""
+"Authentication is required for suspending the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
+msgid "Hibernate the system"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
+msgid "Authentication is required for hibernating the system."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
+msgid "Hibernate the system while other users are logged in"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
+msgid ""
+"Authentication is required for hibernating the system while other users are "
+"logged in."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
+msgid "Hibernate the system while an application asked to inhibit it"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
+msgid ""
+"Authentication is required for hibernating the system while an application "
+"asked to inhibit it."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
+msgid "Manage active sessions, users and seats"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
+msgid ""
+"Authentication is required for managing active sessions, users and seats."
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
+msgid "Lock or unlock active sessions"
+msgstr "Zamknutie alebo odomknutie aktívnych relácií"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
+msgid "Authentication is required to lock or unlock active sessions."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na uzamknutie alebo odomknutie aktívnych "
+"relácií."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
+msgid "Allow indication to the firmware to boot to setup interface"
+msgstr "Umožnenie indikácie spustenia inštalačného rozhrania pre firmvér"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
+msgid ""
+"Authentication is required to indicate to the firmware to boot to setup "
+"interface."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na indikáciu spustenia inštalačného "
+"rozhrania pre firmvér."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
+msgid "Set a wall message"
+msgstr ""
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
+msgid "Authentication is required to set a wall message"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:1
+msgid "Log into a local container"
+msgstr "Prihlásenie do miestneho kontajneru"
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:2
+msgid "Authentication is required to log into a local container."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na prihlásenie do miestneho kontajneru."
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:3
+msgid "Log into the local host"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:4
+msgid "Authentication is required to log into the local host."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:5
+msgid "Acquire a shell in a local container"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:6
+msgid "Authentication is required to acquire a shell in a local container."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:7
+msgid "Acquire a shell on the local host"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:8
+msgid "Authentication is required to acquire a shell on the local host."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:9
+msgid "Acquire a pseudo TTY in a local container"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:10
+msgid ""
+"Authentication is required to acquire a pseudo TTY in a local container."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:11
+msgid "Acquire a pseudo TTY on the local host"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:12
+msgid "Authentication is required to acquire a pseudo TTY on the local host."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:13
+msgid "Manage local virtual machines and containers"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:14
+msgid ""
+"Authentication is required to manage local virtual machines and containers."
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:15
+msgid "Manage local virtual machine and container images"
+msgstr ""
+
+#: ../src/machine/org.freedesktop.machine1.policy.in.h:16
+msgid ""
+"Authentication is required to manage local virtual machine and container "
+"images."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:1
+msgid "Set system time"
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:2
+msgid "Authentication is required to set the system time."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:3
+msgid "Set system timezone"
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:4
+msgid "Authentication is required to set the system timezone."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:5
+msgid "Set RTC to local timezone or UTC"
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:6
+msgid ""
+"Authentication is required to control whether the RTC stores the local or "
+"UTC time."
+msgstr ""
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:7
+msgid "Turn network time synchronization on or off"
+msgstr "Zapnutie alebo vypnutie sieťovej synchronizácie času"
+
+#: ../src/timedate/org.freedesktop.timedate1.policy.in.h:8
+msgid ""
+"Authentication is required to control whether network time synchronization "
+"shall be enabled."
+msgstr ""
+"Vyžaduje sa overenie totožnosti na ovládanie, či má byť povolená "
+"synchronizácia času cez sieť."
+
+#: ../src/core/dbus-unit.c:457
+msgid "Authentication is required to start '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:458
+msgid "Authentication is required to stop '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:459
+msgid "Authentication is required to reload '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:460 ../src/core/dbus-unit.c:461
+msgid "Authentication is required to restart '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:568
+msgid "Authentication is required to kill '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:599
+msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
+msgstr ""
+
+#: ../src/core/dbus-unit.c:632
+msgid "Authentication is required to set properties on '$(unit)'."
+msgstr ""
# Swedish translation for systemd.
# Copyright © 2015 systemd's COPYRIGHT HOLDER
# This file is distributed under the same license as the systemd package.
-# Josef Andersson <josef.andersson@fripost.org>, 2015.
# Sebastian Rasmussen <sebras@gmail.com>, 2015.
# Andreas Henriksson <andreas@fatal.se>, 2016.
-#
+# Josef Andersson <l10nl18nsweja@gmail.com>, 2015, 2017.
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-11-22 16:37+0100\n"
-"PO-Revision-Date: 2016-09-29 11:58+0200\n"
-"Last-Translator: Andreas Henriksson <andreas@fatal.se>\n"
+"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
+"POT-Creation-Date: 2017-03-01 15:50+0000\n"
+"PO-Revision-Date: 2017-03-19 21:18+0100\n"
+"Last-Translator: Josef Andersson <l10nl18nsweja@gmail.com>\n"
"Language-Team: Swedish\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 2.91.7\n"
+"X-Generator: Poedit 1.8.9\n"
#: ../src/core/org.freedesktop.systemd1.policy.in.in.h:1
msgid "Send passphrase back to system"
#: ../src/locale/org.freedesktop.locale1.policy.in.h:4
msgid "Authentication is required to set the system keyboard settings."
-msgstr "Autentisering krävs för att ställa in systeminställningar för tangentbord."
+msgstr ""
+"Autentisering krävs för att ställa in systeminställningar för tangentbord."
#: ../src/login/org.freedesktop.login1.policy.in.h:1
msgid "Allow applications to inhibit system shutdown"
"av brytaren för datorhöljet."
#: ../src/login/org.freedesktop.login1.policy.in.h:19
+msgid "Allow non-logged-in user to run programs"
+msgstr "Tillåt ej inloggad användare att köra program"
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:20
+msgid "Explicit request is required to run programs as a non-logged-in user."
+msgstr ""
+"Uttrycklig begäran krävs för att köra program som en icke inloggad användare."
+
+#: ../src/login/org.freedesktop.login1.policy.in.h:21
msgid "Allow non-logged-in users to run programs"
msgstr "Tillåt ej inloggade användare att köra program"
-#: ../src/login/org.freedesktop.login1.policy.in.h:20
+#: ../src/login/org.freedesktop.login1.policy.in.h:22
msgid "Authentication is required to run programs as a non-logged-in user."
msgstr ""
"Autentisering krävs för att köra program som en icke inloggad användare."
-#: ../src/login/org.freedesktop.login1.policy.in.h:21
+#: ../src/login/org.freedesktop.login1.policy.in.h:23
msgid "Allow attaching devices to seats"
msgstr "Tillåt att binda enheter till platser"
-#: ../src/login/org.freedesktop.login1.policy.in.h:22
+#: ../src/login/org.freedesktop.login1.policy.in.h:24
msgid "Authentication is required for attaching a device to a seat."
msgstr "Autentisering krävs för att binda en enhet till en plats."
-#: ../src/login/org.freedesktop.login1.policy.in.h:23
+#: ../src/login/org.freedesktop.login1.policy.in.h:25
msgid "Flush device to seat attachments"
msgstr "Töm bindningar för enhet-till-plats"
-#: ../src/login/org.freedesktop.login1.policy.in.h:24
+#: ../src/login/org.freedesktop.login1.policy.in.h:26
msgid ""
"Authentication is required for resetting how devices are attached to seats."
msgstr ""
"Autentisering krävs för att återställa hur enheter är bundna till platser."
-#: ../src/login/org.freedesktop.login1.policy.in.h:25
+#: ../src/login/org.freedesktop.login1.policy.in.h:27
msgid "Power off the system"
msgstr "Stäng av systemet"
-#: ../src/login/org.freedesktop.login1.policy.in.h:26
+#: ../src/login/org.freedesktop.login1.policy.in.h:28
msgid "Authentication is required for powering off the system."
msgstr "Autentisering krävs för att stänga av systemet."
-#: ../src/login/org.freedesktop.login1.policy.in.h:27
+#: ../src/login/org.freedesktop.login1.policy.in.h:29
msgid "Power off the system while other users are logged in"
msgstr "Stäng av systemet medan andra användare är inloggade"
-#: ../src/login/org.freedesktop.login1.policy.in.h:28
+#: ../src/login/org.freedesktop.login1.policy.in.h:30
msgid ""
"Authentication is required for powering off the system while other users are "
"logged in."
"Autentisering krävs för att stänga av systemet medan andra användare är "
"inloggade."
-#: ../src/login/org.freedesktop.login1.policy.in.h:29
+#: ../src/login/org.freedesktop.login1.policy.in.h:31
msgid "Power off the system while an application asked to inhibit it"
msgstr "Stäng av systemet även då ett program hindrar det"
-#: ../src/login/org.freedesktop.login1.policy.in.h:30
+#: ../src/login/org.freedesktop.login1.policy.in.h:32
msgid ""
"Authentication is required for powering off the system while an application "
"asked to inhibit it."
"Autentisering krävs för att stänga av systemet även då ett program hindrar "
"det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:31
+#: ../src/login/org.freedesktop.login1.policy.in.h:33
msgid "Reboot the system"
msgstr "Starta om systemet"
-#: ../src/login/org.freedesktop.login1.policy.in.h:32
+#: ../src/login/org.freedesktop.login1.policy.in.h:34
msgid "Authentication is required for rebooting the system."
msgstr "Autentisering krävs för att starta om systemet."
-#: ../src/login/org.freedesktop.login1.policy.in.h:33
+#: ../src/login/org.freedesktop.login1.policy.in.h:35
msgid "Reboot the system while other users are logged in"
msgstr "Starta om systemet medan andra användare är inloggade"
-#: ../src/login/org.freedesktop.login1.policy.in.h:34
+#: ../src/login/org.freedesktop.login1.policy.in.h:36
msgid ""
"Authentication is required for rebooting the system while other users are "
"logged in."
"Autentisering krävs för att starta om systemet medan andra användare är "
"inloggade."
-#: ../src/login/org.freedesktop.login1.policy.in.h:35
+#: ../src/login/org.freedesktop.login1.policy.in.h:37
msgid "Reboot the system while an application asked to inhibit it"
msgstr "Starta om systemet även då ett program hindrar det"
-#: ../src/login/org.freedesktop.login1.policy.in.h:36
+#: ../src/login/org.freedesktop.login1.policy.in.h:38
msgid ""
"Authentication is required for rebooting the system while an application "
"asked to inhibit it."
"Autentisering krävs för att starta om systemet även då ett program hindrar "
"det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:37
+#: ../src/login/org.freedesktop.login1.policy.in.h:39
msgid "Suspend the system"
msgstr "Försätt system i vänteläge"
-#: ../src/login/org.freedesktop.login1.policy.in.h:38
+#: ../src/login/org.freedesktop.login1.policy.in.h:40
msgid "Authentication is required for suspending the system."
msgstr "Autentisering krävs för att försätta system i vänteläge."
-#: ../src/login/org.freedesktop.login1.policy.in.h:39
+#: ../src/login/org.freedesktop.login1.policy.in.h:41
msgid "Suspend the system while other users are logged in"
msgstr "Försätt systemet i vänteläge medan andra användare är inloggade"
-#: ../src/login/org.freedesktop.login1.policy.in.h:40
+#: ../src/login/org.freedesktop.login1.policy.in.h:42
msgid ""
"Authentication is required for suspending the system while other users are "
"logged in."
"Autentisering krävs för att försätta systemet i vänteläge medan andra "
"användare är inloggade."
-#: ../src/login/org.freedesktop.login1.policy.in.h:41
+#: ../src/login/org.freedesktop.login1.policy.in.h:43
msgid "Suspend the system while an application asked to inhibit it"
msgstr "Försätt systemet i vänteläge även då ett program hindrar det"
-#: ../src/login/org.freedesktop.login1.policy.in.h:42
+#: ../src/login/org.freedesktop.login1.policy.in.h:44
msgid ""
"Authentication is required for suspending the system while an application "
"asked to inhibit it."
"Autentisering krävs för att försätta ett program i vänteläge även då ett "
"program hindrar det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:43
+#: ../src/login/org.freedesktop.login1.policy.in.h:45
msgid "Hibernate the system"
msgstr "Försätt systemet i viloläge"
-#: ../src/login/org.freedesktop.login1.policy.in.h:44
+#: ../src/login/org.freedesktop.login1.policy.in.h:46
msgid "Authentication is required for hibernating the system."
msgstr "Autentisering krävs för att försätta systemet i viloläge."
-#: ../src/login/org.freedesktop.login1.policy.in.h:45
+#: ../src/login/org.freedesktop.login1.policy.in.h:47
msgid "Hibernate the system while other users are logged in"
msgstr "Försätt systemet i viloläge medan andra användare är inloggade"
-#: ../src/login/org.freedesktop.login1.policy.in.h:46
+#: ../src/login/org.freedesktop.login1.policy.in.h:48
msgid ""
"Authentication is required for hibernating the system while other users are "
"logged in."
"Autentisering krävs för att försätta systemet i viloläge medan andra "
"användare är inloggade."
-#: ../src/login/org.freedesktop.login1.policy.in.h:47
+#: ../src/login/org.freedesktop.login1.policy.in.h:49
msgid "Hibernate the system while an application asked to inhibit it"
msgstr "Försätt systemet i viloläge även då ett program hindrar det"
-#: ../src/login/org.freedesktop.login1.policy.in.h:48
+#: ../src/login/org.freedesktop.login1.policy.in.h:50
msgid ""
"Authentication is required for hibernating the system while an application "
"asked to inhibit it."
"Autentisering krävs för att försätta ett program i viloläge även då ett "
"program hindrar det."
-#: ../src/login/org.freedesktop.login1.policy.in.h:49
+#: ../src/login/org.freedesktop.login1.policy.in.h:51
msgid "Manage active sessions, users and seats"
msgstr "Hantera aktiva sessioner, användare och platser"
-#: ../src/login/org.freedesktop.login1.policy.in.h:50
+#: ../src/login/org.freedesktop.login1.policy.in.h:52
msgid ""
"Authentication is required for managing active sessions, users and seats."
msgstr ""
"Autentisering krävs för att hantera aktiva sessioner, användare och platser."
-#: ../src/login/org.freedesktop.login1.policy.in.h:51
+#: ../src/login/org.freedesktop.login1.policy.in.h:53
msgid "Lock or unlock active sessions"
msgstr "Lås eller lås upp aktiva sessioner"
-#: ../src/login/org.freedesktop.login1.policy.in.h:52
+#: ../src/login/org.freedesktop.login1.policy.in.h:54
msgid "Authentication is required to lock or unlock active sessions."
msgstr "Autentisering krävs för att låsa eller låsa upp aktiva sessioner."
-#: ../src/login/org.freedesktop.login1.policy.in.h:53
+#: ../src/login/org.freedesktop.login1.policy.in.h:55
msgid "Allow indication to the firmware to boot to setup interface"
msgstr ""
"Tillåt indikering till firmware att starta upp i inställningsgränssnitt"
-#: ../src/login/org.freedesktop.login1.policy.in.h:54
+#: ../src/login/org.freedesktop.login1.policy.in.h:56
msgid ""
"Authentication is required to indicate to the firmware to boot to setup "
"interface."
"Autentisering krävs för att indikera till firmware att starta upp till "
"inställningsgränssnitt."
-#: ../src/login/org.freedesktop.login1.policy.in.h:55
+#: ../src/login/org.freedesktop.login1.policy.in.h:57
msgid "Set a wall message"
msgstr "Ange ett väggmeddelande"
-#: ../src/login/org.freedesktop.login1.policy.in.h:56
+#: ../src/login/org.freedesktop.login1.policy.in.h:58
msgid "Authentication is required to set a wall message"
msgstr "Autentisering krävs för att ställa in ett väggmeddelande"
"Autentisering krävs för att kontrollera huruvida synkronisering av "
"nätverkstid ska vara aktiverat."
-#: ../src/core/dbus-unit.c:428
+#: ../src/core/dbus-unit.c:457
msgid "Authentication is required to start '$(unit)'."
msgstr "Autentisering krävs för att starta \"$(unit)\"."
-#: ../src/core/dbus-unit.c:429
+#: ../src/core/dbus-unit.c:458
msgid "Authentication is required to stop '$(unit)'."
msgstr "Autentisering krävs för att stoppa \"$(unit)\"."
-#: ../src/core/dbus-unit.c:430
+#: ../src/core/dbus-unit.c:459
msgid "Authentication is required to reload '$(unit)'."
msgstr "Autentisering krävs för att läsa om tillståndet för \"$(unit)\"."
-#: ../src/core/dbus-unit.c:431 ../src/core/dbus-unit.c:432
+#: ../src/core/dbus-unit.c:460 ../src/core/dbus-unit.c:461
msgid "Authentication is required to restart '$(unit)'."
msgstr "Autentisering krävs för att starta om \"$(unit)\"."
-#: ../src/core/dbus-unit.c:535
+#: ../src/core/dbus-unit.c:568
msgid "Authentication is required to kill '$(unit)'."
msgstr "Autentisering krävs för att döda \"$(unit)\"."
-#: ../src/core/dbus-unit.c:565
+#: ../src/core/dbus-unit.c:599
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr ""
"Autentisering krävs för att återställa det \"fallerade\" tillståndet för "
"\"$(unit)\"."
-#: ../src/core/dbus-unit.c:597
+#: ../src/core/dbus-unit.c:632
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Autentisering krävs för att ställa in egenskaper på \"$(unit)\"."
+/50-udev-default.rules
/99-systemd.rules
+++ /dev/null
-# do not edit this file, it will be overwritten on update
-
-# run a command on remove events
-ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
-ACTION=="remove", GOTO="default_end"
-
-SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}"
-
-# select "system RTC" or just use the first one
-SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
-SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
-
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
-SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
-ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
-
-ACTION!="add", GOTO="default_end"
-
-SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
-SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666"
-SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620"
-SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620"
-SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620"
-SUBSYSTEM=="tty", KERNEL=="3270/tty[0-9]*", GROUP="tty", MODE="0620"
-SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
-KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
-
-SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
-
-SUBSYSTEM=="input", GROUP="input"
-SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0664"
-
-SUBSYSTEM=="video4linux", GROUP="video"
-SUBSYSTEM=="graphics", GROUP="video"
-SUBSYSTEM=="drm", GROUP="video"
-SUBSYSTEM=="dvb", GROUP="video"
-
-SUBSYSTEM=="sound", GROUP="audio", \
- OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer"
-
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664"
-
-SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", GROUP="video"
-SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", GROUP="video"
-SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", GROUP="video"
-SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", GROUP="video"
-
-KERNEL=="parport[0-9]*", GROUP="lp"
-SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp"
-SUBSYSTEM=="ppdev", GROUP="lp"
-KERNEL=="lp[0-9]*", GROUP="lp"
-KERNEL=="irlpt[0-9]*", GROUP="lp"
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp"
-
-SUBSYSTEM=="block", GROUP="disk"
-SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom"
-SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom"
-KERNEL=="sch[0-9]*", GROUP="cdrom"
-KERNEL=="pktcdvd[0-9]*", GROUP="cdrom"
-KERNEL=="pktcdvd", GROUP="cdrom"
-
-SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape"
-SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk"
-KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk"
-KERNEL=="loop-control", GROUP="disk", OPTIONS+="static_node=loop-control"
-KERNEL=="btrfs-control", GROUP="disk"
-KERNEL=="rawctl", GROUP="disk"
-SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk"
-SUBSYSTEM=="aoe", GROUP="disk", MODE="0220"
-SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440"
-
-KERNEL=="rfkill", MODE="0664"
-KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
-
-KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse"
-
-SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm"
-
-LABEL="default_end"
--- /dev/null
+# do not edit this file, it will be overwritten on update
+
+# run a command on remove events
+ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}"
+ACTION=="remove", GOTO="default_end"
+
+SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}"
+
+# select "system RTC" or just use the first one
+SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
+SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
+
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
+ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
+
+ACTION!="add", GOTO="default_end"
+
+SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666"
+SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666"
+SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="tty", KERNEL=="3270/tty[0-9]*", GROUP="tty", MODE="0620"
+SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty"
+KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
+
+SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640"
+
+SUBSYSTEM=="input", GROUP="input"
+SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0664"
+
+SUBSYSTEM=="video4linux", GROUP="video"
+SUBSYSTEM=="graphics", GROUP="video"
+SUBSYSTEM=="drm", GROUP="video"
+SUBSYSTEM=="dvb", GROUP="video"
+SUBSYSTEM=="media", GROUP="video"
+SUBSYSTEM=="cec", GROUP="video"
+
+SUBSYSTEM=="sound", GROUP="audio", \
+ OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer"
+
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664"
+
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x00010*", GROUP="video"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00b09d:0x00010*", GROUP="video"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x010001*", GROUP="video"
+SUBSYSTEM=="firewire", ATTR{units}=="*0x00a02d:0x014001*", GROUP="video"
+
+KERNEL=="parport[0-9]*", GROUP="lp"
+SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp"
+SUBSYSTEM=="ppdev", GROUP="lp"
+KERNEL=="lp[0-9]*", GROUP="lp"
+KERNEL=="irlpt[0-9]*", GROUP="lp"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp"
+
+SUBSYSTEM=="block", GROUP="disk"
+SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom"
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom"
+KERNEL=="sch[0-9]*", GROUP="cdrom"
+KERNEL=="pktcdvd[0-9]*", GROUP="cdrom"
+KERNEL=="pktcdvd", GROUP="cdrom"
+
+SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape"
+SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk"
+KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk"
+KERNEL=="loop-control", GROUP="disk", OPTIONS+="static_node=loop-control"
+KERNEL=="btrfs-control", GROUP="disk"
+KERNEL=="rawctl", GROUP="disk"
+SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk"
+SUBSYSTEM=="aoe", GROUP="disk", MODE="0220"
+SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440"
+
+KERNEL=="rfkill", MODE="0664"
+KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun"
+
+KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse"
+
+KERNEL=="kvm", GROUP="kvm", MODE="@DEV_KVM_MODE@"
+
+SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm"
+
+LABEL="default_end"
ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change"
# watch metadata changes, caused by tools closing the device node which was opened for writing
-ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*", OPTIONS+="watch"
+ACTION!="remove", SUBSYSTEM=="block", KERNEL=="loop*|nvme*|sd*|vd*|xvd*|pmem*|mmcblk*", OPTIONS+="watch"
ACTION=="remove", GOTO="cdrom_end"
SUBSYSTEM!="block", GOTO="cdrom_end"
-KERNEL!="sr[0-9]*|xvd*", GOTO="cdrom_end"
+KERNEL!="sr[0-9]*|vdisk*|xvd*", GOTO="cdrom_end"
ENV{DEVTYPE}!="disk", GOTO="cdrom_end"
# unconditionally tag device as CDROM
RUN{builtin}+="keyboard", GOTO="evdev_end"
# AT keyboard matching by the machine's DMI data
-ENV{ID_INPUT_KEY}=="?*", DRIVERS=="atkbd", \
+DRIVERS=="atkbd", \
IMPORT{builtin}="hwdb 'evdev:atkbd:$attr{[dmi/id]modalias}'", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
--- /dev/null
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="id_input_end"
+
+SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
+
+LABEL="id_input_end"
ACTION=="remove", GOTO="persistent_input_end"
SUBSYSTEM!="input", GOTO="persistent_input_end"
SUBSYSTEMS=="bluetooth", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end"
+# Bluetooth devices don't always have the bluetooth subsystem
+ATTRS{id/bustype}=="0005", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end"
SUBSYSTEMS=="rmi4", ENV{ID_BUS}="rmi", GOTO="persistent_input_end"
SUBSYSTEMS=="serio", ENV{ID_BUS}="i8042", GOTO="persistent_input_end"
# by-path
ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id"
-ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
+KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n"
+KERNEL!="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}"
ENV{DEVTYPE}=="partition", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
# legacy virtio-pci by-path links (deprecated)
IMPORT{builtin}="hwdb 'sensor:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \
GOTO="sensor_end"
+SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1", SUBSYSTEMS=="acpi", \
+ IMPORT{builtin}="hwdb 'sensor:modalias:acpi:$attr{hid}:$attr{[dmi/id]modalias}'", \
+ GOTO="sensor_end"
+
+SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1", SUBSYSTEMS=="platform", \
+ IMPORT{builtin}="hwdb 'sensor:modalias:platform:$id:$attr{[dmi/id]modalias}'", \
+ GOTO="sensor_end"
+
LABEL="sensor_end"
--- /dev/null
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="joystick_end"
+ENV{ID_INPUT_JOYSTICK}=="", GOTO="joystick_end"
+KERNEL!="event*", GOTO="joystick_end"
+
+# joystick:<bustype>:v<vid>p<pid>:name:<name>:*
+KERNELS=="input*", ENV{ID_BUS}!="", \
+ IMPORT{builtin}="hwdb 'joystick:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \
+ GOTO="joystick_end"
+
+LABEL="joystick_end"
--- /dev/null
+rules = files('''
+ 60-block.rules
+ 60-cdrom_id.rules
+ 60-drm.rules
+ 60-evdev.rules
+ 60-input-id.rules
+ 60-persistent-alsa.rules
+ 60-persistent-input.rules
+ 60-persistent-storage.rules
+ 60-persistent-storage-tape.rules
+ 60-persistent-v4l.rules
+ 60-sensor.rules
+ 60-serial.rules
+ 64-btrfs.rules
+ 70-mouse.rules
+ 70-touchpad.rules
+ 75-net-description.rules
+ 75-probe_mtd.rules
+ 78-sound-card.rules
+ 80-drivers.rules
+ 80-net-setup-link.rules
+'''.split())
+
+install_data(rules,
+ install_dir : udevrulesdir)
+
+rules_in = '''
+ 50-udev-default.rules
+ 99-systemd.rules
+'''.split()
+
+foreach file : rules_in
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : udevrulesdir)
+endforeach
--- /dev/null
+bashcompletiondir = get_option('bashcompletiondir')
+if bashcompletiondir == ''
+ bash_completion = dependency('bash-completion', required : false)
+ if bash_completion.found()
+ bashcompletiondir = bash_completion.get_pkgconfig_variable('completionsdir')
+ else
+ bashcompletiondir = join_paths(datadir, 'bash-completion/completions')
+ endif
+
+ message('bash completions: @0@'.format(bashcompletiondir))
+endif
+
+if bashcompletiondir != 'no'
+ bash_systemctl = configure_file(
+ input : 'systemctl.in',
+ output : 'systemctl',
+ configuration : substs)
+
+ items = [['busctl', ''],
+ ['journalctl', ''],
+ ['systemd-analyze', ''],
+ ['systemd-cat', ''],
+ ['systemd-cgls', ''],
+ ['systemd-cgtop', ''],
+ ['systemd-delta', ''],
+ ['systemd-detect-virt', ''],
+ ['systemd-nspawn', ''],
+ ['systemd-path', ''],
+ ['systemd-run', ''],
+ ['udevadm', ''],
+ ['kernel-install', ''],
+ [bash_systemctl, ''],
+ ['bootctl', 'ENABLE_EFI'],
+ ['coredumpctl', 'ENABLE_COREDUMP'],
+ ['hostnamectl', 'ENABLE_HOSTNAMED'],
+ ['localectl', 'ENABLE_LOCALED'],
+ ['loginctl', 'ENABLE_LOGIND'],
+ ['machinectl', 'ENABLE_MACHINED'],
+ ['networkctl', 'ENABLE_NETWORKD'],
+ ['systemd-resolve', 'ENABLE_RESOLVED'],
+ ['timedatectl', 'ENABLE_TIMEDATED'],
+ ]
+
+ foreach item : items
+ if item[1] == '' or conf.get(item[1], false)
+ install_data(item[0],
+ install_dir : bashcompletiondir)
+ endif
+ endforeach
+endif
)
local -A VERBS=(
- [STANDALONE]='list lldp'
+ [STANDALONE]='list lldp label'
[LINKS]='status'
)
comps='full enable-only disable-only'
;;
--output|-o)
- comps='short short-full short-iso short-precise short-monotonic short-unix verbose export json
+ comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json
json-pretty json-sse cat'
;;
--machine|-M)
fi
local -A VERBS=(
- [ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies edit set-property'
+ [ALL_UNITS]='is-active is-failed is-enabled status show cat mask preset help list-dependencies edit set-property revert'
[ENABLED_UNITS]='disable'
[DISABLED_UNITS]='enable'
[REENABLABLE_UNITS]='reenable'
'list:List existing links'
'status:Show information about the specified links'
'lldp:Show Link Layer Discovery Protocol status'
+ 'label:Show address labels'
)
if (( CURRENT == 1 )); then
_describe -t commands 'networkctl command' _networkctl_cmds
#autoload
local -a _output_opts
-_output_opts=(short short-full short-iso short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
+_output_opts=(short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
_describe -t output 'output mode' _output_opts || compadd "$@"
"list-unit-files:List installed unit files"
"enable:Enable one or more unit files"
"disable:Disable one or more unit files"
+ "add-wants:Add Wants= dependencies to a unit"
+ "add-requires:Add Requires= dependencies to a unit"
"reenable:Reenable one or more unit files"
"preset:Enable/disable one or more unit files based on preset configuration"
"set-default:Set the default target"
"kexec:Shut down and reboot the system with kexec"
"exit:Ask for user instance termination"
"switch-root:Change root directory"
+ "revert:Revert unit files to their vendor versions"
)
if (( CURRENT == 1 )); then
local fun
# Completion functions for ALL_UNITS
-for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies edit ; do
+for fun in is-active is-failed is-enabled status show cat mask preset help list-dependencies edit revert add-wants add-requires ; do
(( $+functions[_systemctl_$fun] )) || _systemctl_$fun()
{
_systemctl_really_all_units
--- /dev/null
+zshcompletiondir = get_option('zshcompletiondir')
+if zshcompletiondir == ''
+ zshcompletiondir = join_paths(datadir, 'zsh/site-functions')
+
+ message('zsh completions: @0@'.format(zshcompletiondir))
+endif
+
+if zshcompletiondir != 'no'
+ zsh_systemctl = configure_file(
+ input : '_systemctl.in',
+ output : '_systemctl',
+ configuration : substs)
+
+ items = [['_busctl', ''],
+ ['_journalctl', ''],
+ ['_systemd-analyze', ''],
+ ['_systemd-delta', ''],
+ ['_systemd-nspawn', ''],
+ ['_systemd', ''],
+ ['_systemd-run', ''],
+ ['_udevadm', ''],
+ ['_kernel-install', ''],
+ ['_sd_hosts_or_user_at_host', ''],
+ ['_sd_outputmodes', ''],
+ ['_sd_unit_files', ''],
+ ['_sd_machines', ''],
+ [zsh_systemctl, ''],
+ ['_bootctl', 'ENABLE_EFI'],
+ ['_coredumpctl', 'ENABLE_COREDUMP'],
+ ['_hostnamectl', 'ENABLE_HOSTNAMED'],
+ ['_localectl', 'ENABLE_LOCALED'],
+ ['_loginctl', 'ENABLE_LOGIND'],
+ ['_machinectl', 'ENABLE_MACHINED'],
+ ['_networkctl', 'ENABLE_NETWORKD'],
+ ['_systemd-inhibit', 'ENABLE_LOGIND'],
+ ['_systemd-resolve', 'ENABLE_RESOLVED'],
+ ['_systemd-tmpfiles', 'ENABLE_TMPFILES'],
+ ['_timedatectl', 'ENABLE_TIMEDATED'],
+ ]
+
+ foreach item : items
+ if item[1] == '' or conf.get(item[1], false)
+ install_data(item[0],
+ install_dir : zshcompletiondir)
+ endif
+ endforeach
+endif
"<!-- that render these files properly but much slower are ImageMagick, -->\n"
"<!-- gimp, inkscape, etc. To display the files on your system, just -->\n"
"<!-- point your browser to this file. -->\n\n"
- "<!-- This plot was generated by systemd-analyze version %-16.16s -->\n\n", VERSION);
+ "<!-- This plot was generated by systemd-analyze version %-16.16s -->\n\n", PACKAGE_VERSION);
/* style sheet */
svg("<defs>\n <style type=\"text/css\">\n <![CDATA[\n"
--- /dev/null
+systemd_analyze_sources = files('''
+ analyze.c
+ analyze-verify.c
+ analyze-verify.h
+'''.split())
--- /dev/null
+BEGIN{
+ print "static const char* const af_names[] = { "
+}
+!/AF_FILE/ && !/AF_ROUTE/ && !/AF_LOCAL/ {
+ printf " [%s] = \"%s\",\n", $1, $1
+}
+END{
+ print "};"
+}
# elif __SIZEOF_POINTER__ == 8
{ "riscv", ARCHITECTURE_RISCV64 },
# endif
+#elif defined(__arc__)
+ { "arc", ARCHITECTURE_ARC },
+ { "arceb", ARCHITECTURE_ARC_BE },
#else
#error "Please register your architecture here!"
#endif
[ARCHITECTURE_NIOS2] = "nios2",
[ARCHITECTURE_RISCV32] = "riscv32",
[ARCHITECTURE_RISCV64] = "riscv64",
+ [ARCHITECTURE_ARC] = "arc",
+ [ARCHITECTURE_ARC_BE] = "arc-be",
};
DEFINE_STRING_TABLE_LOOKUP(architecture, int);
ARCHITECTURE_NIOS2,
ARCHITECTURE_RISCV32,
ARCHITECTURE_RISCV64,
+ ARCHITECTURE_ARC,
+ ARCHITECTURE_ARC_BE,
_ARCHITECTURE_MAX,
_ARCHITECTURE_INVALID = -1
};
#if defined(__x86_64__)
# define native_architecture() ARCHITECTURE_X86_64
-# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
+# if defined(__ILP32__)
+# define LIB_ARCH_TUPLE "x86_64-linux-gnux32"
+# else
+# define LIB_ARCH_TUPLE "x86_64-linux-gnu"
+# endif
# define SECONDARY_ARCHITECTURE ARCHITECTURE_X86
#elif defined(__i386__)
# define native_architecture() ARCHITECTURE_X86
#elif defined(__powerpc__)
# if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC
-# define LIB_ARCH_TUPLE "powerpc-linux-gnu"
+# if defined(__NO_FPRS__)
+# define LIB_ARCH_TUPLE "powerpc-linux-gnuspe"
+# else
+# define LIB_ARCH_TUPLE "powerpc-linux-gnu"
+# endif
# else
# define native_architecture() ARCHITECTURE_PPC_LE
# error "Missing LIB_ARCH_TUPLE for PPCLE"
# error "Missing LIB_ARCH_TUPLE for SH64"
#elif defined(__sh__)
# define native_architecture() ARCHITECTURE_SH
-# define LIB_ARCH_TUPLE "sh4-linux-gnu"
+# if defined(__SH1__)
+# define LIB_ARCH_TUPLE "sh1-linux-gnu"
+# elif defined(__SH2__)
+# define LIB_ARCH_TUPLE "sh2-linux-gnu"
+# elif defined(__SH2A__)
+# define LIB_ARCH_TUPLE "sh2a-linux-gnu"
+# elif defined(__SH2E__)
+# define LIB_ARCH_TUPLE "sh2e-linux-gnu"
+# elif defined(__SH3__)
+# define LIB_ARCH_TUPLE "sh3-linux-gnu"
+# elif defined(__SH3E__)
+# define LIB_ARCH_TUPLE "sh3e-linux-gnu"
+# elif defined(__SH4__) && !defined(__SH4A__)
+# define LIB_ARCH_TUPLE "sh4-linux-gnu"
+# elif defined(__SH4A__)
+# define LIB_ARCH_TUPLE "sh4a-linux-gnu"
+# endif
#elif defined(__m68k__)
# define native_architecture() ARCHITECTURE_M68K
# define LIB_ARCH_TUPLE "m68k-linux-gnu"
# else
# error "Unrecognized riscv architecture variant"
# endif
+#elif defined(__arc__)
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define native_architecture() ARCHITECTURE_ARC_BE
+# define LIB_ARCH_TUPLE "arceb-linux"
+# else
+# define native_architecture() ARCHITECTURE_ARC
+# define LIB_ARCH_TUPLE "arc-linux"
+# endif
#else
# error "Please register your architecture here!"
#endif
--- /dev/null
+BEGIN{
+ print "static const char* const arphrd_names[] = { "
+}
+!/CISCO/ {
+ printf " [ARPHRD_%s] = \"%s\",\n", $1, $1
+}
+END{
+ print "};"
+}
***/
#ifdef HAVE_BLKID
-#include <blkid/blkid.h>
+#include <blkid.h>
#endif
#include "util.h"
#define _KMOD_FEATURE_ "-KMOD"
#endif
+#ifdef HAVE_LIBIDN2
+#define _IDN2_FEATURE_ "+IDN2"
+#else
+#define _IDN2_FEATURE_ "-IDN2"
+#endif
+
#ifdef HAVE_LIBIDN
#define _IDN_FEATURE_ "+IDN"
#else
_BLKID_FEATURE_ " " \
_ELFUTILS_FEATURE_ " " \
_KMOD_FEATURE_ " " \
+ _IDN2_FEATURE_ " " \
_IDN_FEATURE_ " " \
_CGROUP_HIEARCHY_
}
}
+static int parse_one_number(const char *p, const char **e, unsigned long *ret) {
+ char *ee = NULL;
+ unsigned long value;
+
+ errno = 0;
+ value = strtoul(p, &ee, 10);
+ if (errno > 0)
+ return -errno;
+ if (ee == p)
+ return -EINVAL;
+
+ *ret = value;
+ *e = ee;
+ return 0;
+}
+
static int parse_component_decimal(const char **p, bool usec, int *res) {
unsigned long value;
const char *e = NULL;
- char *ee = NULL;
int r;
if (!isdigit(**p))
return -EINVAL;
- errno = 0;
- value = strtoul(*p, &ee, 10);
- if (errno > 0)
- return -errno;
- if (ee == *p)
- return -EINVAL;
- e = ee;
+ r = parse_one_number(*p, &e, &value);
+ if (r < 0)
+ return r;
if (usec) {
if (value * USEC_PER_SEC / USEC_PER_SEC != value)
return 0;
}
+static int calendarspec_from_time_t(CalendarSpec *c, time_t time) {
+ struct tm tm;
+ CalendarComponent *year = NULL, *month = NULL, *day = NULL, *hour = NULL, *minute = NULL, *us = NULL;
+ int r;
+
+ assert_se(gmtime_r(&time, &tm));
+
+ r = const_chain(tm.tm_year + 1900, &year);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_mon + 1, &month);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_mday, &day);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_hour, &hour);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_min, &minute);
+ if (r < 0)
+ return r;
+
+ r = const_chain(tm.tm_sec * USEC_PER_SEC, &us);
+ if (r < 0)
+ return r;
+
+ c->utc = true;
+ c->year = year;
+ c->month = month;
+ c->day = day;
+ c->hour = hour;
+ c->minute = minute;
+ c->microsecond = us;
+ return 0;
+}
+
static int prepend_component(const char **p, bool usec, CalendarComponent **c) {
int r, start, stop = -1, repeat = 0;
CalendarComponent *cc;
if (*t == 0)
return 0;
+ /* @TIMESTAMP — UNIX time in seconds since the epoch */
+ if (*t == '@') {
+ unsigned long value;
+ time_t time;
+
+ r = parse_one_number(t + 1, &t, &value);
+ if (r < 0)
+ return r;
+
+ time = value;
+ if ((unsigned long) time != value)
+ return -ERANGE;
+
+ r = calendarspec_from_time_t(c, time);
+ if (r < 0)
+ return r;
+
+ *p = t;
+ return 1; /* finito, don't parse H:M:S after that */
+ }
+
r = parse_chain(&t, false, &first);
if (r < 0)
return r;
continue;
e = endswith_no_case(p, tzname[j]);
- if(!e)
+ if (!e)
continue;
if (e == p)
continue;
if (r < 0)
goto fail;
- r = parse_calendar_time(&p, c);
- if (r < 0)
- goto fail;
+ if (r == 0) {
+ r = parse_calendar_time(&p, c);
+ if (r < 0)
+ goto fail;
+ }
if (*p != 0) {
r = -EINVAL;
--- /dev/null
+BEGIN{
+ print "static const char* const capability_names[] = { "
+}
+{
+ printf " [%s] = \"%s\",\n", $1, tolower($1)
+}
+END{
+ print "};"
+}
#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "strv.h"
#include "unit-name.h"
#include "user-util.h"
if (r > 0 && streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
r = cg_attach(SYSTEMD_CGROUP_CONTROLLER_LEGACY, path, pid);
if (r < 0)
- log_warning_errno(r, "Failed to attach %d to compat systemd cgroup %s: %m", pid, path);
+ log_warning_errno(r, "Failed to attach "PID_FMT" to compat systemd cgroup %s: %m", pid, path);
}
return 0;
return 0;
}
+int cg_mask_to_string(CGroupMask mask, char **ret) {
+ const char *controllers[_CGROUP_CONTROLLER_MAX + 1];
+ CGroupController c;
+ int i = 0;
+ char *s;
+
+ assert(ret);
+
+ if (mask == 0) {
+ *ret = NULL;
+ return 0;
+ }
+
+ for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++) {
+
+ if (!(mask & CGROUP_CONTROLLER_TO_MASK(c)))
+ continue;
+
+ controllers[i++] = cgroup_controller_to_string(c);
+ controllers[i] = NULL;
+ }
+
+ s = strv_join((char **)controllers, NULL);
+ if (!s)
+ return -ENOMEM;
+
+ *ret = s;
+ return 0;
+}
+
+int cg_mask_from_string(const char *value, CGroupMask *mask) {
+ assert(mask);
+ assert(value);
+
+ for (;;) {
+ _cleanup_free_ char *n = NULL;
+ CGroupController v;
+ int r;
+
+ r = extract_first_word(&value, &n, NULL, 0);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ v = cgroup_controller_from_string(n);
+ if (v < 0)
+ continue;
+
+ *mask |= CGROUP_CONTROLLER_TO_MASK(v);
+ }
+ return 0;
+}
+
int cg_mask_supported(CGroupMask *ret) {
CGroupMask mask = 0;
int r;
return r;
if (r > 0) {
_cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL;
- const char *c;
/* In the unified hierarchy we can read the supported
* and accessible controllers from a the top-level
if (r < 0)
return r;
- c = controllers;
- for (;;) {
- _cleanup_free_ char *n = NULL;
- CGroupController v;
-
- r = extract_first_word(&c, &n, NULL, 0);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- v = cgroup_controller_from_string(n);
- if (v < 0)
- continue;
-
- mask |= CGROUP_CONTROLLER_TO_MASK(v);
- }
+ r = cg_mask_from_string(controllers, &mask);
+ if (r < 0)
+ return r;
/* Currently, we support the cpu, memory, io and pids
* controller in the unified hierarchy, mask
int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p);
int cg_mask_supported(CGroupMask *ret);
+int cg_mask_from_string(const char *s, CGroupMask *ret);
+int cg_mask_to_string(CGroupMask mask, char **ret);
int cg_kernel_controllers(Set *controllers);
.un.sun_path = "\0/org/freedesktop/plymouthd", \
}
-#ifndef TTY_GID
-#define TTY_GID 5
-#endif
-
#define NOTIFY_FD_MAX 768
#define NOTIFY_BUFFER_MAX PIPE_BUF
return endswith(de->d_name, suffix);
}
+
+struct dirent* readdir_no_dot(DIR *dirp) {
+ struct dirent* d;
+
+ for (;;) {
+ d = readdir(dirp);
+ if (d && dot_or_dot_dot(d->d_name))
+ continue;
+ return d;
+ }
+}
bool dirent_is_file(const struct dirent *de) _pure_;
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
+struct dirent* readdir_no_dot(DIR *dirp);
+
#define FOREACH_DIRENT(de, d, on_error) \
for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \
if (!de) { \
if (!ce)
return -ENOMEM;
- fprintf(f, "env=%s\n", *e);
+ fprintf(f, "env=%s\n", ce);
}
/* caller should call ferror() */
}
int deserialize_environment(char ***environment, const char *line) {
- char *uce = NULL;
+ char *uce;
int r;
assert(line);
if (r < 0)
return r;
- if (!env_assignment_is_valid(uce))
+ if (!env_assignment_is_valid(uce)) {
+ free(uce);
return -EINVAL;
+ }
return strv_env_replace(environment, uce);
}
--- /dev/null
+BEGIN{
+ print "static const char* const errno_names[] = { "
+}
+!/EDEADLOCK/ && !/EWOULDBLOCK/ && !/ENOTSUP/ {
+ printf " [%s] = \"%s\",\n", $1, $1
+}
+END{
+ print "};"
+}
}
-static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
+static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad, bool escape_tab_nl) {
assert(bad);
for (; *s; s++) {
+ if (escape_tab_nl && IN_SET(*s, '\n', '\t')) {
+ *(t++) = '\\';
+ *(t++) = *s == '\n' ? 'n' : 't';
+ continue;
+ }
+
if (*s == '\\' || strchr(bad, *s))
*(t++) = '\\';
if (!r)
return NULL;
- t = strcpy_backslash_escaped(r, s, bad);
+ t = strcpy_backslash_escaped(r, s, bad, false);
*t = 0;
return r;
}
-char *shell_maybe_quote(const char *s) {
+char* shell_maybe_quote(const char *s, EscapeStyle style) {
const char *p;
char *r, *t;
assert(s);
- /* Encloses a string in double quotes if necessary to make it
- * OK as shell string. */
+ /* Encloses a string in quotes if necessary to make it OK as a shell
+ * string. Note that we treat benign UTF-8 characters as needing
+ * escaping too, but that should be OK. */
for (p = s; *p; p++)
if (*p <= ' ' ||
if (!*p)
return strdup(s);
- r = new(char, 1+strlen(s)*2+1+1);
+ r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1);
if (!r)
return NULL;
t = r;
- *(t++) = '"';
+ if (style == ESCAPE_BACKSLASH)
+ *(t++) = '"';
+ else if (style == ESCAPE_POSIX) {
+ *(t++) = '$';
+ *(t++) = '\'';
+ } else
+ assert_not_reached("Bad EscapeStyle");
+
t = mempcpy(t, s, p - s);
- t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
+ if (style == ESCAPE_BACKSLASH)
+ t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false);
+ else
+ t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true);
- *(t++)= '"';
+ if (style == ESCAPE_BACKSLASH)
+ *(t++) = '"';
+ else
+ *(t++) = '\'';
*t = 0;
return r;
/* What characters are special in the shell? */
/* must be escaped outside and inside double-quotes */
#define SHELL_NEED_ESCAPE "\"\\`$"
-/* can be escaped or double-quoted */
-#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;"
+
+/* Those that can be escaped or double-quoted.
+ *
+ * Stricly speaking, ! does not need to be escaped, except in interactive
+ * mode, but let's be extra nice to the user and quote ! in case this
+ * output is ever used in interactive mode. */
+#define SHELL_NEED_QUOTES SHELL_NEED_ESCAPE GLOB_CHARS "'()<>|&;!"
+
+/* Note that we assume control characters would need to be escaped too in
+ * addition to the "special" characters listed here, if they appear in the
+ * string. Current users disallow control characters. Also '"' shall not
+ * be escaped.
+ */
+#define SHELL_NEED_ESCAPE_POSIX "\\\'"
typedef enum UnescapeFlags {
UNESCAPE_RELAX = 1,
} UnescapeFlags;
+typedef enum EscapeStyle {
+ ESCAPE_BACKSLASH = 1,
+ ESCAPE_POSIX = 2,
+} EscapeStyle;
+
char *cescape(const char *s);
char *cescape_length(const char *s, size_t n);
size_t cescape_char(char c, char *buf);
char *octescape(const char *s, size_t len);
char *shell_escape(const char *s, const char *bad);
-char *shell_maybe_quote(const char *s);
+char* shell_maybe_quote(const char *s, EscapeStyle style);
return log_syntax(unit, LOG_ERR, filename, line, r, "Unable to decode word \"%s\", ignoring: %m", rvalue);
}
-int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
+/* We pass ExtractFlags as unsigned int (to avoid undefined behaviour when passing
+ * an object that undergoes default argument promotion as an argument to va_start).
+ * Let's make sure that ExtractFlags fits into an unsigned int. */
+assert_cc(sizeof(enum ExtractFlags) <= sizeof(unsigned));
+
+int extract_many_words(const char **p, const char *separators, unsigned flags, ...) {
va_list ap;
char **l;
int n = 0, i, c, r;
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags);
int extract_first_word_and_warn(const char **p, char **ret, const char *separators, ExtractFlags flags, const char *unit, const char *filename, unsigned line, const char *rvalue);
-int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) _sentinel_;
+int extract_many_words(const char **p, const char *separators, unsigned flags, ...) _sentinel_;
#include "fileio.h"
#include "selinux-util.h"
-int write_string_file_atomic_label(const char *fn, const char *line) {
+int write_string_file_atomic_label_ts(const char *fn, const char *line, struct timespec *ts) {
int r;
r = mac_selinux_create_file_prepare(fn, S_IFREG);
if (r < 0)
return r;
- r = write_string_file(fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
+ r = write_string_file_ts(fn, line, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC, ts);
mac_selinux_create_file_clear();
#include "fileio.h"
-int write_string_file_atomic_label(const char *fn, const char *line);
+int write_string_file_atomic_label_ts(const char *fn, const char *line, struct timespec *ts);
+static inline int write_string_file_atomic_label(const char *fn, const char *line) {
+ return write_string_file_atomic_label_ts(fn, line, NULL);
+}
int write_env_file_label(const char *fname, char **l);
int fopen_temporary_label(const char *target,
const char *path, FILE **f, char **temp_path);
#define READ_FULL_BYTES_MAX (4U*1024U*1024U)
-int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
+int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts) {
assert(f);
assert(line);
if (enforce_newline && !endswith(line, "\n"))
fputc('\n', f);
+ if (ts) {
+ struct timespec twice[2] = {*ts, *ts};
+
+ if (futimens(fileno(f), twice) < 0)
+ return -errno;
+ }
+
return fflush_and_check(f);
}
return r;
}
-int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
+int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts) {
_cleanup_fclose_ FILE *f = NULL;
int q, r;
goto fail;
return r;
- }
+ } else
+ assert(ts == NULL);
if (flags & WRITE_STRING_FILE_CREATE) {
f = fopen(fn, "we");
}
}
- r = write_string_stream(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
+ r = write_string_stream_ts(f, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE), ts);
if (r < 0)
goto fail;
WRITE_STRING_FILE_VERIFY_ON_FAILURE = 8,
} WriteStringFileFlags;
-int write_string_stream(FILE *f, const char *line, bool enforce_newline);
-int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags);
+int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, struct timespec *ts);
+static inline int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
+ return write_string_stream_ts(f, line, enforce_newline, NULL);
+}
+int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags flags, struct timespec *ts);
+static inline int write_string_file(const char *fn, const char *line, WriteStringFileFlags flags) {
+ return write_string_file_ts(fn, line, flags, NULL);
+}
int read_one_line_file(const char *fn, char **line);
int read_full_file(const char *fn, char **contents, size_t *size);
# error Unknown time_t size
#endif
+#if defined __x86_64__ && defined __ILP32__
+# define PRI_TIMEX PRIi64
+#else
+# define PRI_TIMEX "li"
+#endif
+
#if SIZEOF_RLIM_T == 8
# define RLIM_FMT "%" PRIu64
#elif SIZEOF_RLIM_T == 4
--- /dev/null
+#!/bin/sh -eu
+
+$1 -E -dM -include sys/socket.h - </dev/null | \
+ grep -Ev 'AF_UNSPEC|AF_MAX' | \
+ awk '/^#define[ \t]+AF_[^ \t]+[ \t]+PF_[^ \t]/ { print $2; }'
--- /dev/null
+#!/bin/sh -eu
+
+$1 -dM -include net/if_arp.h - </dev/null | \
+ awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
+ sed -e 's/ARPHRD_//'
--- /dev/null
+#!/bin/sh -eu
+
+$1 -dM -include linux/capability.h -include "$2" -include "$3" - </dev/null | \
+ awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \
+ grep -v CAP_LAST_CAP
--- /dev/null
+#!/bin/sh -eu
+
+$1 -dM -include errno.h - </dev/null | \
+ awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }'
--- /dev/null
+#!/usr/bin/env python3
+
+"""Generate %-from-name.gperf from %-list.txt
+"""
+
+import sys
+
+name, prefix, input = sys.argv[1:]
+
+print("""\
+struct {}_name {{ const char* name; int id; }};
+%null-strings
+%%""".format(name))
+
+for line in open(input):
+ print("{0}, {1}{0}".format(line.rstrip(), prefix))
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <dirent.h>
#include <errno.h>
#include <glob.h>
+#include <sys/types.h>
+#include "dirent-util.h"
#include "glob-util.h"
#include "macro.h"
+#include "path-util.h"
#include "strv.h"
-int glob_exists(const char *path) {
- _cleanup_globfree_ glob_t g = {};
+int safe_glob(const char *path, int flags, glob_t *pglob) {
int k;
- assert(path);
+ /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
+ assert(!(flags & GLOB_ALTDIRFUNC));
+
+ if (!pglob->gl_closedir)
+ pglob->gl_closedir = (void (*)(void *)) closedir;
+ if (!pglob->gl_readdir)
+ pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
+ if (!pglob->gl_opendir)
+ pglob->gl_opendir = (void *(*)(const char *)) opendir;
+ if (!pglob->gl_lstat)
+ pglob->gl_lstat = lstat;
+ if (!pglob->gl_stat)
+ pglob->gl_stat = stat;
errno = 0;
- k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+ k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
if (k == GLOB_NOMATCH)
- return 0;
+ return -ENOENT;
if (k == GLOB_NOSPACE)
return -ENOMEM;
if (k != 0)
return errno > 0 ? -errno : -EIO;
+ if (strv_isempty(pglob->gl_pathv))
+ return -ENOENT;
- return !strv_isempty(g.gl_pathv);
+ return 0;
}
-int glob_extend(char ***strv, const char *path) {
+int glob_exists(const char *path) {
_cleanup_globfree_ glob_t g = {};
int k;
- char **p;
- errno = 0;
- k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
+ assert(path);
- if (k == GLOB_NOMATCH)
- return -ENOENT;
- if (k == GLOB_NOSPACE)
- return -ENOMEM;
- if (k != 0)
- return errno > 0 ? -errno : -EIO;
- if (strv_isempty(g.gl_pathv))
- return -ENOENT;
+ k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k == -ENOENT)
+ return false;
+ if (k < 0)
+ return k;
+ return true;
+}
+
+int glob_extend(char ***strv, const char *path) {
+ _cleanup_globfree_ glob_t g = {};
+ int k;
- STRV_FOREACH(p, g.gl_pathv) {
- k = strv_extend(strv, *p);
- if (k < 0)
- return k;
- }
+ k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k < 0)
+ return k;
- return 0;
+ return strv_extend_strv(strv, g.gl_pathv, false);
}
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <glob.h>
#include <stdbool.h>
#include <string.h>
#include "macro.h"
#include "string-util.h"
+/* Note: this function modifies pglob to set various functions. */
+int safe_glob(const char *path, int flags, glob_t *pglob);
+
int glob_exists(const char *path);
int glob_extend(char ***strv, const char *path);
return -EAFNOSUPPORT;
}
+
+int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, uint8_t *ret_prefixlen) {
+ union in_addr_union buffer;
+ const char *e, *l;
+ uint8_t k;
+ int r;
+
+ assert(p);
+
+ if (!IN_SET(family, AF_INET, AF_INET6))
+ return -EAFNOSUPPORT;
+
+ e = strchr(p, '/');
+ if (e)
+ l = strndupa(p, e - p);
+ else
+ l = p;
+
+ r = in_addr_from_string(family, l, &buffer);
+ if (r < 0)
+ return r;
+
+ k = FAMILY_ADDRESS_SIZE(family) * 8;
+
+ if (e) {
+ uint8_t n;
+
+ r = safe_atou8(e + 1, &n);
+ if (r < 0)
+ return r;
+
+ if (n > k)
+ return -ERANGE;
+
+ k = n;
+ }
+
+ *ret_prefix = buffer;
+ *ret_prefixlen = k;
+
+ return 0;
+}
int in_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen);
int in_addr_default_subnet_mask(const struct in_addr *addr, struct in_addr *mask);
int in_addr_mask(int family, union in_addr_union *addr, unsigned char prefixlen);
+int in_addr_prefix_from_string(const char *p, int family, union in_addr_union *ret_prefix, uint8_t *ret_prefixlen);
static inline size_t FAMILY_ADDRESS_SIZE(int family) {
assert(family == AF_INET || family == AF_INET6);
#include "fd-util.h"
#include "parse-util.h"
#include "string-util.h"
+#include "unaligned.h"
enum {
IMPORTER_STATE_LINE = 0, /* waiting to read, or reading line */
safe_close(imp->fd);
}
+ free(imp->name);
free(imp->buf);
iovw_free_contents(&imp->iovw);
}
if (r <= 0)
return r;
- imp->data_size = le64toh( *(uint64_t *) data );
+ imp->data_size = unaligned_read_le64(data);
if (imp->data_size > DATA_SIZE_MAX) {
log_error("Stream declares field with size %zu > DATA_SIZE_MAX = %u",
imp->data_size, DATA_SIZE_MAX);
return r;
if (r == 0) {
imp->state = IMPORTER_STATE_EOF;
- return r;
+ return 0;
}
assert(n > 0);
assert(line[n-1] == '\n');
#define SNDBUF_SIZE (8*1024*1024)
static LogTarget log_target = LOG_TARGET_CONSOLE;
-static int log_max_level = LOG_INFO;
+static int log_max_level[] = {LOG_INFO, LOG_INFO};
+assert_cc(ELEMENTSOF(log_max_level) == _LOG_REALM_MAX);
static int log_facility = LOG_DAEMON;
static int console_fd = STDERR_FILENO;
int log_open(void) {
int r;
+ /* Do not call from library code. */
+
/* If we don't use the console we close it here, to not get
* killed by SAK. If we don't use syslog we close it here so
* that we are not confused by somebody deleting the socket in
}
void log_close(void) {
+ /* Do not call from library code. */
+
log_close_journal();
log_close_syslog();
log_close_kmsg();
}
void log_forget_fds(void) {
+ /* Do not call from library code. */
+
console_fd = kmsg_fd = syslog_fd = journal_fd = -1;
}
-void log_set_max_level(int level) {
+void log_set_max_level_realm(LogRealm realm, int level) {
assert((level & LOG_PRIMASK) == level);
+ assert(realm < ELEMENTSOF(log_max_level));
- log_max_level = level;
+ log_max_level[realm] = level;
}
void log_set_facility(int facility) {
return 1;
}
-static int log_dispatch(
+int log_dispatch_internal(
int level,
int error,
const char *file,
}
int log_dump_internal(
- int level,
- int error,
- const char *file,
- int line,
- const char *func,
- char *buffer) {
+ int level,
+ int error,
+ const char *file,
+ int line,
+ const char *func,
+ char *buffer) {
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
PROTECT_ERRNO;
/* This modifies the buffer... */
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
- return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
+ return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-int log_internalv(
+int log_internalv_realm(
int level,
int error,
const char *file,
const char *format,
va_list ap) {
- PROTECT_ERRNO;
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
char buffer[LINE_MAX];
+ PROTECT_ERRNO;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
/* Make sure that %m maps to the specified error */
vsnprintf(buffer, sizeof(buffer), format, ap);
- return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
+ return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-int log_internal(
+int log_internal_realm(
int level,
int error,
const char *file,
int r;
va_start(ap, format);
- r = log_internalv(level, error, file, line, func, format, ap);
+ r = log_internalv_realm(level, error, file, line, func, format, ap);
va_end(ap);
return r;
PROTECT_ERRNO;
char *buffer, *b;
- size_t l;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
return -error;
/* Make sure that %m maps to the specified error */
size_t n;
n = strlen(object);
- l = n + 2 + LINE_MAX;
-
- buffer = newa(char, l);
+ buffer = newa(char, n + 2 + LINE_MAX);
b = stpcpy(stpcpy(buffer, object), ": ");
- } else {
- l = LINE_MAX;
- b = buffer = newa(char, l);
- }
+ } else
+ b = buffer = newa(char, LINE_MAX);
- vsnprintf(b, l, format, ap);
+ vsnprintf(b, LINE_MAX, format, ap);
- return log_dispatch(level, error, file, line, func, object_field, object, extra_field, extra, buffer);
+ return log_dispatch_internal(level, error, file, line, func,
+ object_field, object, extra_field, extra, buffer);
}
int log_object_internal(
const char *format) {
static char buffer[LINE_MAX];
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return;
DISABLE_WARNING_FORMAT_NONLITERAL;
log_abort_msg = buffer;
- log_dispatch(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
+ log_dispatch_internal(level, 0, file, line, func, NULL, NULL, NULL, NULL, buffer);
}
-noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
- log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+ "Assertion '%s' failed at %s:%u, function %s(). Aborting.");
abort();
}
-noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) {
- log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
+noreturn void log_assert_failed_unreachable_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_CRIT), text, file, line, func,
+ "Code should not be reached '%s' at %s:%u, function %s(). Aborting.");
abort();
}
-void log_assert_failed_return(const char *text, const char *file, int line, const char *func) {
+void log_assert_failed_return_realm(
+ LogRealm realm,
+ const char *text,
+ const char *file,
+ int line,
+ const char *func) {
PROTECT_ERRNO;
- log_assert(LOG_DEBUG, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
+ log_assert(LOG_REALM_PLUS_LEVEL(realm, LOG_DEBUG), text, file, line, func,
+ "Assertion '%s' failed at %s:%u, function %s(). Ignoring.");
}
-int log_oom_internal(const char *file, int line, const char *func) {
- log_internal(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
+int log_oom_internal(LogRealm realm, const char *file, int line, const char *func) {
+ log_internal_realm(LOG_REALM_PLUS_LEVEL(realm, LOG_ERR),
+ ENOMEM, file, line, func, "Out of memory.");
return -ENOMEM;
}
char buf[LINE_MAX];
bool found = false;
+ LogRealm realm = LOG_REALM_REMOVE_LEVEL(level);
PROTECT_ERRNO;
va_list ap;
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[realm]))
return -error;
if (log_target == LOG_TARGET_NULL)
if (!found)
return -error;
- return log_dispatch(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
+ return log_dispatch_internal(level, error, file, line, func, NULL, NULL, NULL, NULL, buf + 8);
}
int log_set_target_from_string(const char *e) {
return 0;
}
-int log_set_max_level_from_string(const char *e) {
+int log_set_max_level_from_string_realm(LogRealm realm, const char *e) {
int t;
t = log_level_from_string(e);
if (t < 0)
return -EINVAL;
- log_set_max_level(t);
+ log_set_max_level_realm(realm, t);
return 0;
}
return 0;
}
-void log_parse_environment(void) {
+void log_parse_environment_realm(LogRealm realm) {
+ /* Do not call from library code. */
+
const char *e;
if (get_ctty_devnr(0, NULL) < 0)
user stuff. */
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
- e = secure_getenv("SYSTEMD_LOG_TARGET");
+ e = getenv("SYSTEMD_LOG_TARGET");
if (e && log_set_target_from_string(e) < 0)
log_warning("Failed to parse log target '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_LEVEL");
- if (e && log_set_max_level_from_string(e) < 0)
+ e = getenv("SYSTEMD_LOG_LEVEL");
+ if (e && log_set_max_level_from_string_realm(realm, e) < 0)
log_warning("Failed to parse log level '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_COLOR");
+ e = getenv("SYSTEMD_LOG_COLOR");
if (e && log_show_color_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
- e = secure_getenv("SYSTEMD_LOG_LOCATION");
+ e = getenv("SYSTEMD_LOG_LOCATION");
if (e && log_show_location_from_string(e) < 0)
log_warning("Failed to parse bool '%s'. Ignoring.", e);
}
return log_target;
}
-int log_get_max_level(void) {
- return log_max_level;
+int log_get_max_level_realm(LogRealm realm) {
+ return log_max_level[realm];
}
void log_show_color(bool b) {
if (error < 0)
error = -error;
- if (_likely_(LOG_PRI(level) > log_max_level))
+ if (_likely_(LOG_PRI(level) > log_max_level[LOG_REALM_SYSTEMD]))
return -error;
if (log_target == LOG_TARGET_NULL)
unit_fmt = getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s";
return log_struct_internal(
- level, error,
+ LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, level),
+ error,
file, line, func,
"MESSAGE_ID=" SD_MESSAGE_INVALID_CONFIGURATION_STR,
"CONFIG_FILE=%s", config_file,
#include "macro.h"
+typedef enum LogRealm {
+ LOG_REALM_SYSTEMD,
+ LOG_REALM_UDEV,
+ _LOG_REALM_MAX,
+} LogRealm;
+
+#ifndef LOG_REALM
+# define LOG_REALM LOG_REALM_SYSTEMD
+#endif
+
typedef enum LogTarget{
LOG_TARGET_CONSOLE,
LOG_TARGET_CONSOLE_PREFIXED,
LOG_TARGET_NULL,
_LOG_TARGET_MAX,
_LOG_TARGET_INVALID = -1
-} LogTarget;
+} LogTarget;
+
+#define LOG_REALM_PLUS_LEVEL(realm, level) \
+ ((realm) << 10 | (level))
+#define LOG_REALM_REMOVE_LEVEL(realm_level) \
+ ((realm_level >> 10))
void log_set_target(LogTarget target);
-void log_set_max_level(int level);
+void log_set_max_level_realm(LogRealm realm, int level);
+#define log_set_max_level(level) \
+ log_set_max_level_realm(LOG_REALM, (level))
+
void log_set_facility(int facility);
int log_set_target_from_string(const char *e);
-int log_set_max_level_from_string(const char *e);
+int log_set_max_level_from_string_realm(LogRealm realm, const char *e);
+#define log_set_max_level_from_string(e) \
+ log_set_max_level_from_string_realm(LOG_REALM, (e))
void log_show_color(bool b);
bool log_get_show_color(void) _pure_;
int log_show_location_from_string(const char *e);
LogTarget log_get_target(void) _pure_;
-int log_get_max_level(void) _pure_;
+int log_get_max_level_realm(LogRealm realm) _pure_;
+#define log_get_max_level() \
+ log_get_max_level_realm(LOG_REALM)
+
+/* Functions below that open and close logs or configure logging based on the
+ * environment should not be called from library code — this is always a job
+ * for the application itself.
+ */
int log_open(void);
void log_close(void);
void log_close_kmsg(void);
void log_close_console(void);
-void log_parse_environment(void);
+void log_parse_environment_realm(LogRealm realm);
+#define log_parse_environment() \
+ log_parse_environment_realm(LOG_REALM)
-int log_internal(
+int log_dispatch_internal(
+ int level,
+ int error,
+ const char *file,
+ int line,
+ const char *func,
+ const char *object_field,
+ const char *object,
+ const char *extra,
+ const char *extra_field,
+ char *buffer);
+
+int log_internal_realm(
int level,
int error,
const char *file,
int line,
const char *func,
const char *format, ...) _printf_(6,7);
+#define log_internal(level, ...) \
+ log_internal_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
-int log_internalv(
+int log_internalv_realm(
int level,
int error,
const char *file,
const char *func,
const char *format,
va_list ap) _printf_(6,0);
+#define log_internalv(level, ...) \
+ log_internalv_realm(LOG_REALM_PLUS_LEVEL(LOG_REALM, (level)), __VA_ARGS__)
+/* Realm is fixed to LOG_REALM_SYSTEMD for those */
int log_object_internal(
int level,
int error,
const char *extra_field,
const char *extra,
const char *format,
- va_list ap) _printf_(9,0);
+ va_list ap) _printf_(10,0);
int log_struct_internal(
int level,
const char *format, ...) _printf_(6,0) _sentinel_;
int log_oom_internal(
+ LogRealm realm,
const char *file,
int line,
const char *func);
bool newline_separator,
int error,
const char *format,
- va_list ap);
+ va_list ap) _printf_(6, 0);
/* This modifies the buffer passed! */
int log_dump_internal(
char *buffer);
/* Logging for various assertions */
-noreturn void log_assert_failed(
+noreturn void log_assert_failed_realm(
+ LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
+#define log_assert_failed(text, ...) \
+ log_assert_failed_realm(LOG_REALM, (text), __VA_ARGS__)
-noreturn void log_assert_failed_unreachable(
+noreturn void log_assert_failed_unreachable_realm(
+ LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
+#define log_assert_failed_unreachable(text, ...) \
+ log_assert_failed_unreachable_realm(LOG_REALM, (text), __VA_ARGS__)
-void log_assert_failed_return(
+void log_assert_failed_return_realm(
+ LogRealm realm,
const char *text,
const char *file,
int line,
const char *func);
+#define log_assert_failed_return(text, ...) \
+ log_assert_failed_return_realm(LOG_REALM, (text), __VA_ARGS__)
+
+#define log_dispatch(level, error, buffer) \
+ log_dispatch_internal(level, error, __FILE__, __LINE__, __func__, NULL, NULL, NULL, NULL, buffer)
/* Logging with level */
-#define log_full_errno(level, error, ...) \
+#define log_full_errno_realm(realm, level, error, ...) \
({ \
int _level = (level), _e = (error); \
- (log_get_max_level() >= LOG_PRI(_level)) \
- ? log_internal(_level, _e, __FILE__, __LINE__, __func__, __VA_ARGS__) \
+ (log_get_max_level_realm((realm)) >= LOG_PRI(_level)) \
+ ? log_internal_realm(LOG_REALM_PLUS_LEVEL((realm), _level), _e, \
+ __FILE__, __LINE__, __func__, __VA_ARGS__) \
: -abs(_e); \
})
-#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
+#define log_full_errno(level, error, ...) \
+ log_full_errno_realm(LOG_REALM, (level), (error), __VA_ARGS__)
+
+#define log_full(level, ...) log_full_errno((level), 0, __VA_ARGS__)
/* Normal logging */
#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__)
#endif
/* Structured logging */
-#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
-#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_struct_errno(level, error, ...) \
+ log_struct_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
+ error, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_struct(level, ...) log_struct_errno(level, 0, __VA_ARGS__)
/* This modifies the buffer passed! */
-#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer)
+#define log_dump(level, buffer) \
+ log_dump_internal(LOG_REALM_PLUS_LEVEL(LOG_REALM, level), \
+ 0, __FILE__, __LINE__, __func__, buffer)
-#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
+#define log_oom() log_oom_internal(LOG_REALM, __FILE__, __LINE__, __func__)
bool log_on_console(void) _pure_;
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <sys/param.h>
--- /dev/null
+basic_sources_plain = files('''
+ af-list.c
+ af-list.h
+ alloc-util.c
+ alloc-util.h
+ architecture.c
+ architecture.h
+ arphrd-list.c
+ arphrd-list.h
+ async.c
+ async.h
+ audit-util.c
+ audit-util.h
+ barrier.c
+ barrier.h
+ bitmap.c
+ bitmap.h
+ blkid-util.h
+ btrfs-ctree.h
+ btrfs-util.c
+ btrfs-util.h
+ build.h
+ bus-label.c
+ bus-label.h
+ calendarspec.c
+ calendarspec.h
+ capability-util.c
+ capability-util.h
+ cap-list.c
+ cap-list.h
+ cgroup-util.c
+ cgroup-util.h
+ chattr-util.c
+ chattr-util.h
+ clock-util.c
+ clock-util.h
+ conf-files.c
+ conf-files.h
+ copy.c
+ copy.h
+ cpu-set-util.c
+ cpu-set-util.h
+ def.h
+ device-nodes.c
+ device-nodes.h
+ dirent-util.c
+ dirent-util.h
+ env-util.c
+ env-util.h
+ errno-list.c
+ errno-list.h
+ escape.c
+ escape.h
+ ether-addr-util.c
+ ether-addr-util.h
+ exec-util.c
+ exec-util.h
+ exit-status.c
+ exit-status.h
+ extract-word.c
+ extract-word.h
+ fd-util.c
+ fd-util.h
+ fileio.c
+ fileio.h
+ fileio-label.c
+ fileio-label.h
+ format-util.h
+ fs-util.c
+ fs-util.h
+ glob-util.c
+ glob-util.h
+ gunicode.c
+ gunicode.h
+ hash-funcs.c
+ hash-funcs.h
+ hashmap.c
+ hashmap.h
+ hexdecoct.c
+ hexdecoct.h
+ hostname-util.c
+ hostname-util.h
+ in-addr-util.c
+ in-addr-util.h
+ ioprio.h
+ io-util.c
+ io-util.h
+ journal-importer.c
+ journal-importer.h
+ khash.c
+ khash.h
+ label.c
+ label.h
+ list.h
+ locale-util.c
+ locale-util.h
+ lockfile-util.c
+ lockfile-util.h
+ log.c
+ log.h
+ login-util.c
+ login-util.h
+ macro.h
+ memfd-util.c
+ memfd-util.h
+ mempool.c
+ mempool.h
+ missing_syscall.h
+ mkdir.c
+ mkdir.h
+ mkdir-label.c
+ mount-util.c
+ mount-util.h
+ MurmurHash2.c
+ MurmurHash2.h
+ nss-util.h
+ ordered-set.c
+ ordered-set.h
+ parse-util.c
+ parse-util.h
+ path-util.c
+ path-util.h
+ prioq.c
+ prioq.h
+ proc-cmdline.c
+ proc-cmdline.h
+ process-util.c
+ process-util.h
+ random-util.c
+ random-util.h
+ ratelimit.c
+ ratelimit.h
+ raw-clone.h
+ refcnt.h
+ replace-var.c
+ replace-var.h
+ rlimit-util.c
+ rlimit-util.h
+ rm-rf.c
+ rm-rf.h
+ securebits.h
+ selinux-util.c
+ selinux-util.h
+ set.h
+ sigbus.c
+ sigbus.h
+ signal-util.c
+ signal-util.h
+ siphash24.c
+ siphash24.h
+ smack-util.c
+ smack-util.h
+ socket-label.c
+ socket-util.c
+ socket-util.h
+ sparse-endian.h
+ special.h
+ stat-util.c
+ stat-util.h
+ stdio-util.h
+ strbuf.c
+ strbuf.h
+ string-table.c
+ string-table.h
+ string-util.c
+ string-util.h
+ strv.c
+ strv.h
+ strxcpyx.c
+ strxcpyx.h
+ syslog-util.c
+ syslog-util.h
+ terminal-util.c
+ terminal-util.h
+ time-util.c
+ time-util.h
+ umask-util.h
+ unaligned.h
+ unit-name.c
+ unit-name.h
+ user-util.c
+ user-util.h
+ utf8.c
+ utf8.h
+ util.c
+ util.h
+ verbs.c
+ verbs.h
+ virt.c
+ virt.h
+ web-util.c
+ web-util.h
+ xattr-util.c
+ xattr-util.h
+ xml.c
+ xml.h
+'''.split())
+
+missing_h = files('missing.h')
+
+generate_gperfs = find_program('generate-gperfs.py')
+
+generate_af_list = find_program('generate-af-list.sh')
+af_list_txt = custom_target(
+ 'af-list.txt',
+ output : 'af-list.txt',
+ command : [generate_af_list, cpp],
+ capture : true)
+
+generate_arphrd_list = find_program('generate-arphrd-list.sh')
+arphrd_list_txt = custom_target(
+ 'arphrd-list.txt',
+ output : 'arphrd-list.txt',
+ command : [generate_arphrd_list, cpp],
+ capture : true)
+
+generate_cap_list = find_program('generate-cap-list.sh')
+cap_list_txt = custom_target(
+ 'cap-list.txt',
+ output : 'cap-list.txt',
+ command : [generate_cap_list, cpp, config_h, missing_h],
+ capture : true)
+
+generate_errno_list = find_program('generate-errno-list.sh')
+errno_list_txt = custom_target(
+ 'errno-list.txt',
+ output : 'errno-list.txt',
+ command : [generate_errno_list, cpp],
+ capture : true)
+
+generated_gperf_headers = []
+foreach item : [['af', af_list_txt, 'af', ''],
+ ['arphrd', arphrd_list_txt, 'arphrd', 'ARPHRD_'],
+ ['cap', cap_list_txt, 'capability', ''],
+ ['errno', errno_list_txt, 'errno', '']]
+
+ fname = '@0@-from-name.gperf'.format(item[0])
+ gperf_file = custom_target(
+ fname,
+ input : item[1],
+ output : fname,
+ command : [generate_gperfs, item[2], item[3], '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-from-name.h'.format(item[0])
+ target1 = custom_target(
+ fname,
+ input : gperf_file,
+ output : fname,
+ command : [gperf,
+ '-L', 'ANSI-C', '-t', '--ignore-case',
+ '-N', 'lookup_@0@'.format(item[2]),
+ '-H', 'hash_@0@_name'.format(item[2]),
+ '-p', '-C',
+ '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-to-name.h'.format(item[0])
+ awkscript = '@0@-to-name.awk'.format(item[0])
+ target2 = custom_target(
+ fname,
+ input : [awkscript, item[1]],
+ output : fname,
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+ generated_gperf_headers += [target1, target2]
+endforeach
+
+basic_sources = basic_sources_plain + [missing_h] + generated_gperf_headers
+
+libbasic = static_library(
+ 'basic',
+ basic_sources,
+ include_directories : includes,
+ dependencies : [threads,
+ libcap,
+ libblkid,
+ libselinux,
+ ],
+ install : false)
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <linux/audit.h>
#include <linux/capability.h>
#include <linux/if_link.h>
};
#endif /* !HAVE_LINUX_VM_SOCKETS_H */
-#include "macro.h"
-
#ifndef RLIMIT_RTTIME
#define RLIMIT_RTTIME 15
#endif
# define EVIOCREVOKE _IOW('E', 0x91, int)
#endif
+#ifndef EVIOCSMASK
+
+struct input_mask {
+ uint32_t type;
+ uint32_t codes_size;
+ uint64_t codes_ptr;
+};
+
+#define EVIOCSMASK _IOW('E', 0x93, struct input_mask)
+#endif
+
#ifndef DRM_IOCTL_SET_MASTER
# define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
#endif
#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1)
#endif
-#if !HAVE_DECL_IFLA_VXLAN_REMCSUM_NOPARTIAL
+#if !HAVE_DECL_IFLA_VXLAN_GPE
#define IFLA_VXLAN_UNSPEC 0
#define IFLA_VXLAN_ID 1
#define IFLA_VXLAN_GROUP 2
#define IFLA_VXLAN_REMCSUM_RX 22
#define IFLA_VXLAN_GBP 23
#define IFLA_VXLAN_REMCSUM_NOPARTIAL 24
-#define __IFLA_VXLAN_MAX 25
+#define IFLA_VXLAN_COLLECT_METADATA 25
+#define IFLA_VXLAN_LABEL 26
+#define IFLA_VXLAN_GPE 27
+
+#define __IFLA_VXLAN_MAX 28
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
#endif
+#if !HAVE_DECL_IFLA_GENEVE_LABEL
+#define IFLA_GENEVE_UNSPEC 0
+#define IFLA_GENEVE_ID 1
+#define IFLA_GENEVE_REMOTE 2
+#define IFLA_GENEVE_TTL 3
+#define IFLA_GENEVE_TOS 4
+#define IFLA_GENEVE_PORT 5
+#define IFLA_GENEVE_COLLECT_METADATA 6
+#define IFLA_GENEVE_REMOTE6 7
+#define IFLA_GENEVE_UDP_CSUM 8
+#define IFLA_GENEVE_UDP_ZERO_CSUM6_TX 9
+#define IFLA_GENEVE_UDP_ZERO_CSUM6_RX 10
+#define IFLA_GENEVE_LABEL 11
+
+#define __IFLA_GENEVE_MAX 12
+
+#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+#endif
+
#if !HAVE_DECL_IFLA_IPTUN_ENCAP_DPORT
#define IFLA_IPTUN_UNSPEC 0
#define IFLA_IPTUN_LINK 1
#define INPUT_PROP_ACCELEROMETER 0x06
#endif
+#ifndef BTN_DPAD_UP
+#define BTN_DPAD_UP 0x220
+#define BTN_DPAD_RIGHT 0x223
+#endif
+
+#ifndef KEY_ALS_TOGGLE
+#define KEY_ALS_TOGGLE 0x230
+#endif
+
#ifndef HAVE_KEY_SERIAL_T
typedef int32_t key_serial_t;
#endif
# endif
# elif defined __i386__
# define __NR_memfd_create 356
+# elif defined __arc__
+# define __NR_memfd_create 279
# else
# warning "__NR_memfd_create unknown for your architecture"
# endif
# if _MIPS_SIM == _MIPS_SIM_ABI64
# define __NR_getrandom 5313
# endif
+# elif defined(__arc__)
+# define __NR_getrandom 278
# else
# warning "__NR_getrandom unknown for your architecture"
# endif
# define __NR_name_to_handle_at 370
# elif defined(__powerpc__)
# define __NR_name_to_handle_at 345
+# elif defined(__arc__)
+# define __NR_name_to_handle_at 264
# else
# error "__NR_name_to_handle_at is not defined"
# endif
# define __NR_setns 308
# elif defined(__i386__)
# define __NR_setns 346
+# elif defined(__arc__)
+# define __NR_setns 268
# else
# error "__NR_setns is not defined"
# endif
# endif
# elif defined __i386__
# define __NR_renameat2 353
+# elif defined __powerpc64__
+# define __NR_renameat2 357
+# elif defined __s390__ || defined __s390x__
+# define __NR_renameat2 347
+# elif defined __arc__
+# define __NR_renameat2 276
# else
# warning "__NR_renameat2 unknown for your architecture"
# endif
# define __NR_copy_file_range 285
# elif defined __powerpc__
# define __NR_copy_file_range 379
+# elif defined __arc__
+# define __NR_copy_file_range 285
# else
# warning "__NR_copy_file_range not defined for your architecture"
# endif
return 0;
}
-int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+/* Use this function only if do you have direct access to /proc/self/mountinfo
+ * and need the caller to open it for you. This is the case when /proc is
+ * masked or not mounted. Otherwise, use bind_remount_recursive. */
+int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo) {
_cleanup_set_free_free_ Set *done = NULL;
_cleanup_free_ char *cleaned = NULL;
int r;
+ assert(proc_self_mountinfo);
+
/* Recursively remount a directory (and all its submounts) read-only or read-write. If the directory is already
* mounted, we reuse the mount and simply mark it MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
* operation). If it isn't we first make it one. Afterwards we apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to
return -ENOMEM;
for (;;) {
- _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
_cleanup_set_free_free_ Set *todo = NULL;
bool top_autofs = false;
char *x;
if (!todo)
return -ENOMEM;
- proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
- if (!proc_self_mountinfo)
- return -errno;
+ rewind(proc_self_mountinfo);
for (;;) {
_cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
}
}
+int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
+ return -errno;
+
+ return bind_remount_recursive_with_mountinfo(prefix, ro, blacklist, proc_self_mountinfo);
+}
+
int mount_move_root(const char *path) {
assert(path);
int umount_recursive(const char *target, int flags);
int bind_remount_recursive(const char *prefix, bool ro, char **blacklist);
+int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **blacklist, FILE *proc_self_mountinfo);
int mount_move_root(const char *path);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <xlocale.h>
#include "alloc-util.h"
#include "extract-word.h"
return 0;
}
+
+int parse_dev(const char *s, dev_t *ret) {
+ unsigned x, y;
+ dev_t d;
+
+ if (sscanf(s, "%u:%u", &x, &y) != 2)
+ return -EINVAL;
+
+ d = makedev(x, y);
+ if ((unsigned) major(d) != x || (unsigned) minor(d) != y)
+ return -EINVAL;
+
+ *ret = d;
+ return 0;
+}
#define MODE_INVALID ((mode_t) -1)
int parse_boolean(const char *v) _pure_;
+int parse_dev(const char *s, dev_t *ret);
int parse_pid(const char *s, pid_t* ret_pid);
int parse_mode(const char *s, mode_t *ret);
int parse_ifindex(const char *s, int *ret);
return path_compare(a, b) == 0;
}
-bool path_equal_or_files_same(const char *a, const char *b) {
- return path_equal(a, b) || files_same(a, b) > 0;
+bool path_equal_or_files_same(const char *a, const char *b, int flags) {
+ return path_equal(a, b) || files_same(a, b, flags) > 0;
}
char* path_join(const char *root, const char *path, const char *rest) {
char* path_startswith(const char *path, const char *prefix) _pure_;
int path_compare(const char *a, const char *b) _pure_;
bool path_equal(const char *a, const char *b) _pure_;
-bool path_equal_or_files_same(const char *a, const char *b);
+bool path_equal_or_files_same(const char *a, const char *b, int flags);
char* path_join(const char *root, const char *path, const char *rest);
static inline bool path_equal_ptr(const char *a, const char *b) {
root = procfs_file_alloca(pid, "root");
- return files_same(root, "/proc/1/root");
+ return files_same(root, "/proc/1/root", 0);
}
bool is_main_thread(void) {
return 0;
}
+int ioprio_parse_priority(const char *s, int *ret) {
+ int i, r;
+
+ assert(s);
+ assert(ret);
+
+ r = safe_atoi(s, &i);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_priority_is_valid(i))
+ return -EINVAL;
+
+ *ret = i;
+ return 0;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
#include <stddef.h>
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/resource.h>
+#include <sys/types.h>
#include "format-util.h"
+#include "ioprio.h"
#include "macro.h"
#define procfs_file_alloca(pid, field) \
static inline bool nice_is_valid(int n) {
return n >= PRIO_MIN && n < PRIO_MAX;
}
+
+static inline bool ioprio_class_is_valid(int i) {
+ return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE);
+}
+
+static inline bool ioprio_priority_is_valid(int i) {
+ return i >= 0 && i < IOPRIO_BE_NR;
+}
+
+int ioprio_parse_priority(const char *s, int *ret);
#include <stdint.h>
#ifdef HAVE_SYS_AUXV_H
-#include <sys/auxv.h>
+# include <sys/auxv.h>
+#endif
+
+#ifdef USE_SYS_RANDOM_H
+# include <sys/random.h>
+#else
+# include <linux/random.h>
#endif
#include "fd-util.h"
#include "random-util.h"
#include "time-util.h"
-int dev_urandom(void *p, size_t n) {
+int acquire_random_bytes(void *p, size_t n, bool high_quality_required) {
static int have_syscall = -1;
_cleanup_close_ int fd = -1;
+ unsigned already_done = 0;
int r;
- /* Gathers some randomness from the kernel. This call will
- * never block, and will always return some data from the
- * kernel, regardless if the random pool is fully initialized
- * or not. It thus makes no guarantee for the quality of the
- * returned entropy, but is good enough for our usual usecases
- * of seeding the hash functions for hashtable */
+ /* Gathers some randomness from the kernel. This call will never block. If
+ * high_quality_required, it will always return some data from the kernel,
+ * regardless of whether the random pool is fully initialized or not.
+ * Otherwise, it will return success if at least some random bytes were
+ * successfully acquired, and an error if the kernel has no entropy whatsover
+ * for us. */
- /* Use the getrandom() syscall unless we know we don't have
- * it, or when the requested size is too large for it. */
- if (have_syscall != 0 || (size_t) (int) n != n) {
+ /* Use the getrandom() syscall unless we know we don't have it. */
+ if (have_syscall != 0) {
r = getrandom(p, n, GRND_NONBLOCK);
- if (r == (int) n) {
+ if (r > 0) {
+ have_syscall = true;
+ if ((size_t) r == n)
+ return 0;
+ if (!high_quality_required) {
+ /* Fill in the remaing bytes using pseudorandom values */
+ pseudorandom_bytes((uint8_t*) p + r, n - r);
+ return 0;
+ }
+
+ already_done = r;
+ } else if (errno == ENOSYS)
+ /* We lack the syscall, continue with reading from /dev/urandom. */
+ have_syscall = false;
+ else if (errno == EAGAIN) {
+ /* The kernel has no entropy whatsoever. Let's remember to
+ * use the syscall the next time again though.
+ *
+ * If high_quality_required is false, return an error so that
+ * random_bytes() can produce some pseudorandom
+ * bytes. Otherwise, fall back to /dev/urandom, which we know
+ * is empty, but the kernel will produce some bytes for us on
+ * a best-effort basis. */
have_syscall = true;
- return 0;
- }
-
- if (r < 0) {
- if (errno == ENOSYS)
- /* we lack the syscall, continue with
- * reading from /dev/urandom */
- have_syscall = false;
- else if (errno == EAGAIN)
- /* not enough entropy for now. Let's
- * remember to use the syscall the
- * next time, again, but also read
- * from /dev/urandom for now, which
- * doesn't care about the current
- * amount of entropy. */
- have_syscall = true;
- else
- return -errno;
+
+ if (!high_quality_required)
+ return -ENODATA;
} else
- /* too short read? */
- return -ENODATA;
+ return -errno;
}
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return errno == ENOENT ? -ENOSYS : -errno;
- return loop_read_exact(fd, p, n, true);
+ return loop_read_exact(fd, (uint8_t*) p + already_done, n - already_done, true);
}
void initialize_srand(void) {
return;
#ifdef HAVE_SYS_AUXV_H
- /* The kernel provides us with 16 bytes of entropy in auxv, so let's try to make use of that to seed the
- * pseudo-random generator. It's better than nothing... */
+ /* The kernel provides us with 16 bytes of entropy in auxv, so let's
+ * try to make use of that to seed the pseudo-random generator. It's
+ * better than nothing... */
auxv = (void*) getauxval(AT_RANDOM);
if (auxv) {
- assert_cc(sizeof(x) < 16);
+ assert_cc(sizeof(x) <= 16);
memcpy(&x, auxv, sizeof(x));
} else
#endif
srand_called = true;
}
-void random_bytes(void *p, size_t n) {
+/* INT_MAX gives us only 31 bits, so use 24 out of that. */
+#if RAND_MAX >= INT_MAX
+# define RAND_STEP 3
+#else
+/* SHORT_INT_MAX or lower gives at most 15 bits, we just just 8 out of that. */
+# define RAND_STEP 1
+#endif
+
+void pseudorandom_bytes(void *p, size_t n) {
uint8_t *q;
+
+ initialize_srand();
+
+ for (q = p; q < (uint8_t*) p + n; q += RAND_STEP) {
+ unsigned rr;
+
+ rr = (unsigned) rand();
+
+#if RAND_STEP >= 3
+ if ((size_t) (q - (uint8_t*) p + 2) < n)
+ q[2] = rr >> 16;
+#endif
+#if RAND_STEP >= 2
+ if ((size_t) (q - (uint8_t*) p + 1) < n)
+ q[1] = rr >> 8;
+#endif
+ q[0] = rr;
+ }
+}
+
+void random_bytes(void *p, size_t n) {
int r;
- r = dev_urandom(p, n);
+ r = acquire_random_bytes(p, n, false);
if (r >= 0)
return;
- /* If some idiot made /dev/urandom unavailable to us, he'll
- * get a PRNG instead. */
-
- initialize_srand();
-
- for (q = p; q < (uint8_t*) p + n; q ++)
- *q = rand();
+ /* If some idiot made /dev/urandom unavailable to us, or the
+ * kernel has no entropy, use a PRNG instead. */
+ return pseudorandom_bytes(p, n);
}
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
-int dev_urandom(void *p, size_t n);
+int acquire_random_bytes(void *p, size_t n, bool high_quality_required);
+void pseudorandom_bytes(void *p, size_t n);
void random_bytes(void *p, size_t n);
void initialize_srand(void);
/* We refuse to clean the root file system with this
* call. This is extra paranoia to never cause a really
* seriously broken system. */
- if (path_equal(path, "/")) {
+ if (path_equal_or_files_same(path, "/", AT_SYMLINK_NOFOLLOW)) {
log_error("Attempted to remove entire root file system, and we can't allow that.");
return -EPERM;
}
static int cached_use = -1;
static struct selabel_handle *label_hnd = NULL;
-#define log_enforcing(...) log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, __VA_ARGS__)
+#define log_enforcing(...) log_full_errno(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG, errno, __VA_ARGS__)
#endif
-bool mac_selinux_have(void) {
+bool mac_selinux_use(void) {
#ifdef HAVE_SELINUX
if (cached_use < 0)
cached_use = is_selinux_enabled() > 0;
#endif
}
-bool mac_selinux_use(void) {
- if (!mac_selinux_have())
- return false;
-
- /* Never try to configure SELinux features if we aren't
- * root */
-
- return getuid() == 0;
-}
-
void mac_selinux_retest(void) {
#ifdef HAVE_SELINUX
cached_use = -1;
assert(exe);
assert(label);
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return -EOPNOTSUPP;
r = getcon_raw(&mycon);
assert(label);
#ifdef HAVE_SELINUX
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return -EOPNOTSUPP;
r = getcon_raw(label);
assert(exe);
assert(label);
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return -EOPNOTSUPP;
r = getcon_raw(&mycon);
if (!label)
return NULL;
- if (!mac_selinux_have())
+ if (!mac_selinux_use())
return NULL;
#include "macro.h"
bool mac_selinux_use(void);
-bool mac_selinux_have(void);
void mac_selinux_retest(void);
int mac_selinux_init(void);
#include "utf8.h"
#include "util.h"
+#ifdef ENABLE_IDN
+# define IDN_FLAGS (NI_IDN|NI_IDN_USE_STD3_ASCII_RULES)
+#else
+# define IDN_FLAGS 0
+#endif
+
int socket_address_parse(SocketAddress *a, const char *s) {
char *e, *n;
unsigned u;
return false;
if (a->sockaddr.un.sun_path[0]) {
- if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
+ if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, 0))
return false;
} else {
if (a->size != b->size)
assert(_ret);
- r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
- NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
+ r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
if (r != 0) {
int saved_errno = errno;
return 1;
}
-int files_same(const char *filea, const char *fileb) {
+int files_same(const char *filea, const char *fileb, int flags) {
struct stat a, b;
assert(filea);
assert(fileb);
- if (stat(filea, &a) < 0)
+ if (fstatat(AT_FDCWD, filea, &a, flags) < 0)
return -errno;
- if (stat(fileb, &b) < 0)
+ if (fstatat(AT_FDCWD, fileb, &b, flags) < 0)
return -errno;
return a.st_dev == b.st_dev &&
int path_is_read_only_fs(const char *path);
int path_is_os_tree(const char *path);
-int files_same(const char *filea, const char *fileb);
+int files_same(const char *filea, const char *fileb, int flags);
/* The .f_type field of struct statfs is really weird defined on
* different archs. Let's give its type a name. */
}
char **strv_sort(char **l) {
-
- if (strv_isempty(l))
- return l;
-
- qsort(l, strv_length(l), sizeof(char*), str_compare);
+ qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
return l;
}
/*
* Concatenates/copies strings. In any case, terminates in all cases
- * with '\0' * and moves the @dest pointer forward to the added '\0'.
- * Returns the * remaining size, and 0 if the string was truncated.
+ * with '\0' and moves the @dest pointer forward to the added '\0'.
+ * Returns the remaining size, and 0 if the string was truncated.
+ *
+ * Due to the intended usage, these helpers silently noop invocations
+ * having zero size. This is technically an exception to the above
+ * statement "terminates in all cases". It's unexpected for such calls to
+ * occur outside of a loop where this is the preferred behavior.
*/
#include <stdarg.h>
size_t strpcpy(char **dest, size_t size, const char *src) {
size_t len;
+ assert(dest);
+ assert(src);
+
+ if (size == 0)
+ return 0;
+
len = strlen(src);
if (len >= size) {
if (size > 1)
va_list va;
int i;
+ assert(dest);
+ assert(src);
+
+ if (size == 0)
+ return 0;
+
va_start(va, src);
i = vsnprintf(*dest, size, src, va);
if (i < (int)size) {
*dest += i;
size -= i;
} else {
- *dest += size;
size = 0;
}
va_end(va);
- *dest[0] = '\0';
return size;
}
size_t strpcpyl(char **dest, size_t size, const char *src, ...) {
va_list va;
+ assert(dest);
+ assert(src);
+
va_start(va, src);
do {
size = strpcpy(dest, size, src);
size_t strscpy(char *dest, size_t size, const char *src) {
char *s;
+ assert(dest);
+ assert(src);
+
s = dest;
return strpcpy(&s, size, src);
}
va_list va;
char *s;
+ assert(dest);
+ assert(src);
+
va_start(va, src);
s = dest;
do {
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
- ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
+ ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
return ts;
}
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
- ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
- ts->boottime = clock_boottime_supported() ? usec_sub(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
+ ts->monotonic = usec_sub_signed(now(CLOCK_MONOTONIC), delta);
+ ts->boottime = clock_boottime_supported() ? usec_sub_signed(now(CLOCK_BOOTTIME), delta) : USEC_INFINITY;
return ts;
}
ts->monotonic = u;
delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
- ts->realtime = usec_sub(now(CLOCK_REALTIME), delta);
+ ts->realtime = usec_sub_signed(now(CLOCK_REALTIME), delta);
return ts;
}
dual_timestamp_get(ts);
delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
- ts->realtime = usec_sub(ts->realtime, delta);
- ts->monotonic = usec_sub(ts->monotonic, delta);
+ ts->realtime = usec_sub_signed(ts->realtime, delta);
+ ts->monotonic = usec_sub_signed(ts->monotonic, delta);
return ts;
}
struct timeval *timeval_store(struct timeval *tv, usec_t u) {
assert(tv);
- if (u == USEC_INFINITY||
+ if (u == USEC_INFINITY ||
u / USEC_PER_SEC > TIME_T_MAX) {
tv->tv_sec = (time_t) -1;
tv->tv_usec = (suseconds_t) -1;
int dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
uint64_t a, b;
+ int r, pos;
assert(value);
assert(t);
- if (sscanf(value, "%" PRIu64 "%" PRIu64, &a, &b) != 2) {
- log_debug("Failed to parse dual timestamp value \"%s\": %m", value);
+ pos = strspn(value, WHITESPACE);
+ if (value[pos] == '-')
+ return -EINVAL;
+ pos += strspn(value + pos, DIGITS);
+ pos += strspn(value + pos, WHITESPACE);
+ if (value[pos] == '-')
+ return -EINVAL;
+
+ r = sscanf(value, "%" PRIu64 "%" PRIu64 "%n", &a, &b, &pos);
+ if (r != 2) {
+ log_debug("Failed to parse dual timestamp value \"%s\".", value);
return -EINVAL;
}
+ if (value[pos] != '\0')
+ /* trailing garbage */
+ return -EINVAL;
+
t->realtime = a;
t->monotonic = b;
if (ret > USEC_TIMESTAMP_FORMATTABLE_MAX)
return -EINVAL;
- if (ret > minus)
+ if (ret >= minus)
ret -= minus;
else
- ret = 0;
+ return -EINVAL;
*usec = ret;
return parse_time(t, usec, USEC_PER_SEC);
}
+int parse_sec_fix_0(const char *t, usec_t *usec) {
+ t += strspn(t, WHITESPACE);
+ if (streq(t, "0")) {
+ *usec = USEC_INFINITY;
+ return 0;
+ }
+
+ return parse_sec(t, usec);
+}
+
int parse_nsec(const char *t, nsec_t *nsec) {
static const struct {
const char *suffix;
return DIV_ROUND_UP(u , USEC_PER_SEC / hz);
}
+
+usec_t usec_shift_clock(usec_t x, clockid_t from, clockid_t to) {
+ usec_t a, b;
+
+ if (x == USEC_INFINITY)
+ return USEC_INFINITY;
+ if (map_clock_id(from) == map_clock_id(to))
+ return x;
+
+ a = now(from);
+ b = now(to);
+
+ if (x > a)
+ /* x lies in the future */
+ return usec_add(b, usec_sub_unsigned(x, a));
+ else
+ /* x lies in the past */
+ return usec_sub_unsigned(b, usec_sub_unsigned(a, x));
+}
int parse_timestamp(const char *t, usec_t *usec);
int parse_sec(const char *t, usec_t *usec);
+int parse_sec_fix_0(const char *t, usec_t *usec);
int parse_time(const char *t, usec_t *usec, usec_t default_unit);
int parse_nsec(const char *t, nsec_t *nsec);
bool clock_supported(clockid_t clock);
clockid_t clock_boottime_or_monotonic(void);
+usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);
+
#define xstrftime(buf, fmt, tm) \
assert_message_se(strftime(buf, ELEMENTSOF(buf), fmt, tm) > 0, \
"xstrftime: " #buf "[] must be big enough")
return c;
}
-static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
- if (delta < 0)
- return usec_add(timestamp, (usec_t) (-delta));
+static inline usec_t usec_sub_unsigned(usec_t timestamp, usec_t delta) {
if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
return USEC_INFINITY;
-
- if (timestamp < (usec_t) delta)
+ if (timestamp < delta)
return 0;
return timestamp - delta;
}
+static inline usec_t usec_sub_signed(usec_t timestamp, int64_t delta) {
+ if (delta < 0)
+ return usec_add(timestamp, (usec_t) (-delta));
+ else
+ return usec_sub_unsigned(timestamp, (usec_t) delta);
+}
+
#if SIZEOF_TIME_T == 8
/* The last second we can format is 31. Dec 9999, 1s before midnight, because otherwise we'd enter 5 digit year
* territory. However, since we want to stay away from this in all timezones we take one day off. */
};
DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
+
+static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
+ [NOTIFY_NONE] = "none",
+ [NOTIFY_MAIN] = "main",
+ [NOTIFY_EXEC] = "exec",
+ [NOTIFY_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
_UNIT_DEPENDENCY_INVALID = -1
} UnitDependency;
+typedef enum NotifyAccess {
+ NOTIFY_NONE,
+ NOTIFY_ALL,
+ NOTIFY_MAIN,
+ NOTIFY_EXEC,
+ _NOTIFY_ACCESS_MAX,
+ _NOTIFY_ACCESS_INVALID = -1
+} NotifyAccess;
+
typedef enum UnitNameFlags {
UNIT_NAME_PLAIN = 1, /* Allow foo.service */
UNIT_NAME_INSTANCE = 2, /* Allow foo@bar.service */
const char *unit_dependency_to_string(UnitDependency i) _const_;
UnitDependency unit_dependency_from_string(const char *s) _pure_;
+
+const char* notify_access_to_string(NotifyAccess i) _const_;
+NotifyAccess notify_access_from_string(const char *s) _pure_;
if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
return -ENOMEM;
- r = files_same(userns_fd_path, "/proc/self/ns/user");
+ r = files_same(userns_fd_path, "/proc/self/ns/user", 0);
if (r < 0)
return r;
if (r)
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
return 0;
- ret = files_same("/proc/1/root", "/");
+ ret = files_same("/proc/1/root", "/", 0);
if (ret < 0)
return ret;
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
-#include <blkid/blkid.h>
+#include <blkid.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
struct statfs sfs;
sd_id128_t uuid = SD_ID128_NULL;
uint32_t part = 0;
+ bool quiet;
int r;
assert(p);
+ /* Non-root user can run only `bootctl status`, then if error occured in the following, it does not cause any issues.
+ * So, let's silence the error messages. */
+ quiet = (geteuid() != 0);
+
if (statfs(p, &sfs) < 0) {
/* If we are searching for the mount point, don't generate a log message if we can't find the path */
if (errno == ENOENT && searching)
return -ENOENT;
- return log_error_errno(errno, "Failed to check file system type of \"%s\": %m", p);
+ return log_full_errno(quiet && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
+ "Failed to check file system type of \"%s\": %m", p);
}
if (!F_TYPE_EQUAL(sfs.f_type, MSDOS_SUPER_MAGIC)) {
}
if (stat(p, &st) < 0)
- return log_error_errno(errno, "Failed to determine block device node of \"%s\": %m", p);
+ return log_full_errno(quiet && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
+ "Failed to determine block device node of \"%s\": %m", p);
if (major(st.st_dev) == 0) {
log_error("Block device node of %p is invalid.", p);
t2 = strjoina(p, "/..");
r = stat(t2, &st2);
if (r < 0)
- return log_error_errno(errno, "Failed to determine block device node of parent of \"%s\": %m", p);
+ return log_full_errno(quiet && errno == EACCES ? LOG_DEBUG : LOG_ERR, errno,
+ "Failed to determine block device node of parent of \"%s\": %m", p);
if (st.st_dev == st2.st_dev) {
log_error("Directory \"%s\" is not the root of the EFI System Partition (ESP) file system.", p);
}
/* In a container we don't have access to block devices, skip this part of the verification, we trust the
- * container manager set everything up correctly on its own. */
- if (detect_container() > 0)
+ * container manager set everything up correctly on its own. Also skip the following verification for non-root user. */
+ if (detect_container() > 0 || geteuid() != 0)
goto finish;
r = asprintf(&t, "/dev/block/%u:%u", major(st.st_dev), minor(st.st_dev));
printf("Boot Loader Binaries:\n");
- printf(" ESP: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(partition));
+ if (!esp_path) {
+ printf(" ESP: Cannot find or access mount point of ESP.\n\n");
+ return -ENOENT;
+ }
+
+ printf(" ESP: %s", esp_path);
+ if (!sd_id128_is_null(partition))
+ printf(" (/dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x)", SD_ID128_FORMAT_VAL(partition));
+ printf("\n");
r = enumerate_binaries(esp_path, "EFI/systemd", NULL);
if (r == 0)
_cleanup_free_ uint16_t *options = NULL, *order = NULL;
int i;
- if (!is_efi_boot()) {
- log_notice("Not booted with EFI, not showing EFI variables.");
- return 0;
- }
-
n_options = efi_get_boot_options(&options);
if (n_options == -ENOENT)
return log_error_errno(n_options,
static int verb_status(int argc, char *argv[], void *userdata) {
sd_id128_t uuid = SD_ID128_NULL;
- int r;
+ int r, r2;
- r = must_be_root();
- if (r < 0)
- return r;
-
- r = find_esp(NULL, NULL, NULL, &uuid);
- if (r < 0)
- return r;
+ r2 = find_esp(NULL, NULL, NULL, &uuid);
if (is_efi_boot()) {
_cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL;
r = efi_loader_get_device_part_uuid(&loader_part_uuid);
if (r < 0 && r != -ENOENT)
- log_warning_errno(r, "Failed to read EFI variable LoaderDevicePartUUID: %m");
+ r2 = log_warning_errno(r, "Failed to read EFI variable LoaderDevicePartUUID: %m");
printf("System:\n");
printf(" Firmware: %s (%s)\n", strna(fw_type), strna(fw_info));
r = is_efi_secure_boot();
if (r < 0)
- log_warning_errno(r, "Failed to query secure boot status: %m");
+ r2 = log_warning_errno(r, "Failed to query secure boot status: %m");
else
printf(" Secure Boot: %sd\n", enable_disable(r));
r = is_efi_secure_boot_setup_mode();
if (r < 0)
- log_warning_errno(r, "Failed to query secure boot mode: %m");
+ r2 = log_warning_errno(r, "Failed to query secure boot mode: %m");
else
printf(" Setup Mode: %s\n", r ? "setup" : "user");
printf("\n");
- printf("Loader:\n");
+ printf("Current Loader:\n");
printf(" Product: %s\n", strna(loader));
if (!sd_id128_is_null(loader_part_uuid))
- printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+ printf(" ESP: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
SD_ID128_FORMAT_VAL(loader_part_uuid));
else
- printf(" Partition: n/a\n");
+ printf(" ESP: n/a\n");
printf(" File: %s%s\n", special_glyph(TREE_RIGHT), strna(loader_path));
printf("\n");
} else
- printf("System:\n Not booted with EFI\n");
+ printf("System:\n Not booted with EFI\n\n");
r = status_binaries(arg_path, uuid);
if (r < 0)
- return r;
+ r2 = r;
- if (arg_touch_variables)
+ if (is_efi_boot()) {
r = status_variables();
+ if (r < 0)
+ r2 = r;
+ }
- return r;
+ return r2;
}
static int verb_install(int argc, char *argv[], void *userdata) {
#include "disk.h"
#include "graphics.h"
#include "linux.h"
-#include "pefile.h"
-#include "util.h"
#include "measure.h"
+#include "pe.h"
+#include "shim.h"
+#include "util.h"
#ifndef EFI_OS_INDICATIONS_BOOT_TO_FW_UI
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL
#endif
/* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " VERSION " ####";
+static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " PACKAGE_VERSION " ####";
static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK);
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- Print(L"systemd-boot version: " VERSION "\n");
+ Print(L"systemd-boot version: " PACKAGE_VERSION "\n");
Print(L"architecture: " EFI_MACHINE_TYPE_NAME "\n");
Print(L"loaded image: %s\n", loaded_image_path);
Print(L"UEFI specification: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
FreePool(b);
}
+ if (shim_loaded())
+ Print(L"Shim: present\n");
+
if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) {
Print(L"OsIndicationsSupported: %d\n", (UINT64)*b);
FreePool(b);
break;
case KEYPRESS(0, 0, 'v'):
- status = PoolPrint(L"systemd-boot " VERSION " (" EFI_MACHINE_TYPE_NAME "), UEFI Specification %d.%02d, Vendor %s %d.%02d",
+ status = PoolPrint(L"systemd-boot " PACKAGE_VERSION " (" EFI_MACHINE_TYPE_NAME "), UEFI Specification %d.%02d, Vendor %s %d.%02d",
ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff,
ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
break;
continue;
/* look for .osrel and .cmdline sections in the .efi binary */
- err = pefile_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs);
+ err = pe_file_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs);
if (EFI_ERROR(err))
continue;
InitializeLib(image, sys_table);
init_usec = time_usec();
efivar_set_time_usec(L"LoaderTimeInitUSec", init_usec);
- efivar_set(L"LoaderInfo", L"systemd-boot " VERSION, FALSE);
+ efivar_set(L"LoaderInfo", L"systemd-boot " PACKAGE_VERSION, FALSE);
s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
efivar_set(L"LoaderFirmwareInfo", s, FALSE);
FreePool(s);
return EFI_LOAD_ERROR;
}
+ if (secure_boot_enabled() && shim_loaded()) {
+ err = security_policy_install();
+ if (EFI_ERROR(err)) {
+ Print(L"Error installing security policy: %r ", err);
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
+ return err;
+ }
+ }
/* the filesystem path to this image, to prevent adding ourselves to the menu */
loaded_image_path = DevicePathToStr(loaded_image->FilePath);
event_number = 1;
status = uefi_call_wrapper(tcg->HashLogExtendEvent, 7,
- tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
+ (EFI_TCG *) tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
if (EFI_ERROR(status))
return status;
*/
static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg)
{
- return uefi_call_wrapper(tcg->GetEventLog, 5, tcg,
+ return uefi_call_wrapper(tcg->GetEventLog, 5, (EFI_TCG2 *) tcg,
EFI_TCG2_EVENT_LOG_FORMAT_TCG_2, NULL,
NULL, NULL);
}
CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len);
- status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, tcg, 0, buffer, buffer_size, tcg_event);
+ status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, buffer_size, tcg_event);
uefi_call_wrapper(BS->FreePool, 1, tcg_event);
#ifndef __SDBOOT_MEASURE_H
#define __SDBOOT_MEASURE_H
-#ifndef SD_TPM_PCR
-#define SD_TPM_PCR 8
-#endif
-
EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description);
+
#endif
--- /dev/null
+efi_headers = files('''
+ console.h
+ disk.h
+ graphics.h
+ linux.h
+ measure.h
+ pe.h
+ splash.h
+ util.h
+ shim.h
+'''.split())
+
+common_sources = '''
+ disk.c
+ graphics.c
+ measure.c
+ pe.c
+ util.c
+'''.split()
+
+systemd_boot_sources = '''
+ boot.c
+ console.c
+ shim.c
+'''.split()
+
+stub_sources = '''
+ linux.c
+ splash.c
+ stub.c
+'''.split()
+
+if conf.get('ENABLE_EFI', false) and get_option('gnu-efi') != 'false'
+ efi_cc = get_option('efi-cc')
+ efi_ld = get_option('efi-ld')
+
+ efi_incdir = get_option('efi-includedir')
+ have_header = (gnu_efi_arch != '' and
+ cc.has_header('@0@/@1@/efibind.h'.format(efi_incdir, gnu_efi_arch)))
+
+ if have_header and EFI_MACHINE_TYPE_NAME == ''
+ error('gnu-efi is available, but EFI_MACHINE_TYPE_NAME is unknown')
+ endif
+
+ efi_libdir = get_option('efi-libdir')
+ if efi_libdir == ''
+ cmd = 'cd /usr/lib/$(@0@ -print-multi-os-directory) && pwd'.format(efi_cc)
+ ret = run_command('sh', '-c', cmd)
+ if ret.returncode() == 0
+ efi_libdir = ret.stdout().strip()
+ endif
+ endif
+
+ have_gnu_efi = have_header and efi_libdir != ''
+else
+ have_gnu_efi = false
+endif
+
+if get_option('gnu-efi') == 'true' and not have_gnu_efi
+ error('gnu-efi support requested, but headers were not found')
+endif
+
+if have_gnu_efi
+ efi_conf = configuration_data()
+ efi_conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+ efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
+ efi_conf.set('SD_BOOT_LOG_TPM', get_option('tpm'))
+ efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex'))
+
+ efi_config_h = configure_file(
+ output : 'efi_config.h',
+ configuration : efi_conf)
+
+ objcopy = find_program('objcopy')
+
+ efi_ldsdir = get_option('efi-ldsdir')
+ arch_lds = 'elf_@0@_efi.lds'.format(gnu_efi_arch)
+ if efi_ldsdir == ''
+ efi_ldsdir = join_paths(efi_libdir, 'gnuefi')
+ cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
+ if cmd.returncode() != 0
+ efi_ldsdir = efi_libdir
+ cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
+ if cmd.returncode() != 0
+ error('Cannot find @0@'.format(arch_lds))
+ endif
+ endif
+ endif
+
+ message('efi-libdir: "@0@"'.format(efi_libdir))
+ message('efi-ldsdir: "@0@"'.format(efi_ldsdir))
+ message('efi-includedir: "@0@"'.format(efi_incdir))
+
+ compile_args = ['-Wall',
+ '-Wextra',
+ '-std=gnu90',
+ '-nostdinc',
+ '-ggdb', '-O0',
+ '-fpic',
+ '-fshort-wchar',
+ '-ffreestanding',
+ '-fno-strict-aliasing',
+ '-fno-stack-protector',
+ '-Wsign-compare',
+ '-Wno-missing-field-initializers',
+ '-isystem', efi_incdir,
+ '-isystem', join_paths(efi_incdir, gnu_efi_arch),
+ '-include', efi_config_h]
+ if efi_arch == 'x86_64'
+ compile_args += ['-mno-red-zone',
+ '-mno-sse',
+ '-mno-mmx',
+ '-DEFI_FUNCTION_WRAPPER',
+ '-DGNU_EFI_USE_MS_ABI']
+ elif efi_arch == 'ia32'
+ compile_args += ['-mno-sse',
+ '-mno-mmx']
+ endif
+
+ efi_ldflags = ['-T',
+ join_paths(efi_ldsdir, arch_lds),
+ '-shared',
+ '-Bsymbolic',
+ '-nostdlib',
+ '-znocombreloc',
+ '-L', efi_libdir,
+ join_paths(efi_ldsdir, 'crt0-efi-@0@.o'.format(gnu_efi_arch))]
+ if efi_arch == 'aarch64' or efi_arch == 'arm'
+ # Aarch64 and ARM32 don't have an EFI capable objcopy. Use 'binary'
+ # instead, and add required symbols manually.
+ efi_ldflags += ['--defsym=EFI_SUBSYSTEM=0xa']
+ efi_format = ['-O', 'binary']
+ else
+ efi_format = ['--target=efi-app-@0@'.format(gnu_efi_arch)]
+ endif
+
+ systemd_boot_objects = []
+ stub_objects = []
+ foreach file : common_sources + systemd_boot_sources + stub_sources
+ o_file = custom_target(file + '.o',
+ input : file,
+ output : file + '.o',
+ command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@']
+ + compile_args,
+ depend_files : efi_headers)
+ if (common_sources + systemd_boot_sources).contains(file)
+ systemd_boot_objects += [o_file]
+ endif
+ if (common_sources + stub_sources).contains(file)
+ stub_objects += [o_file]
+ endif
+ endforeach
+
+ libgcc_file_name = run_command(efi_cc, '-print-libgcc-file-name').stdout().strip()
+ systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
+ stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
+ no_undefined_symbols = find_program('no-undefined-symbols.sh')
+
+ foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects],
+ ['stub.so', stub_efi_name, stub_objects]]
+ so = custom_target(
+ tuple[0],
+ input : tuple[2],
+ output : tuple[0],
+ command : [efi_ld, '-o', '@OUTPUT@'] +
+ efi_ldflags + tuple[2] +
+ ['-lefi', '-lgnuefi', libgcc_file_name])
+
+ test('no-undefined-symbols-' + tuple[0],
+ no_undefined_symbols,
+ args : [so])
+
+ stub = custom_target(
+ tuple[1],
+ input : so,
+ output : tuple[1],
+ command : [objcopy,
+ '-j', '.text',
+ '-j', '.sdata',
+ '-j', '.data',
+ '-j', '.dynamic',
+ '-j', '.dynsym',
+ '-j', '.rel',
+ '-j', '.rela',
+ '-j', '.reloc']
+ + efi_format +
+ ['@INPUT@', '@OUTPUT@'],
+ install : true,
+ install_dir : bootlibdir)
+
+ set_variable(tuple[0].underscorify(), so)
+ set_variable(tuple[0].underscorify() + '_stub', stub)
+ endforeach
+endif
+
+############################################################
+
+if have_gnu_efi
+ test_efi_disk_img = custom_target(
+ 'test-efi-disk.img',
+ input : [systemd_boot_so, stub_so_stub],
+ output : 'test-efi-disk.img',
+ command : [test_efi_create_disk_sh, '@OUTPUT@',
+ '@INPUT0@', '@INPUT1@', splash_bmp])
+endif
--- /dev/null
+#!/bin/sh -eu
+
+if nm -D -u "$1" | grep ' U '; then
+ echo "Undefined symbols detected!"
+ exit 1
+fi
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (C) 2015 Kay Sievers <kay@vrfy.org>
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "pe.h"
+#include "util.h"
+
+struct DosFileHeader {
+ UINT8 Magic[2];
+ UINT16 LastSize;
+ UINT16 nBlocks;
+ UINT16 nReloc;
+ UINT16 HdrSize;
+ UINT16 MinAlloc;
+ UINT16 MaxAlloc;
+ UINT16 ss;
+ UINT16 sp;
+ UINT16 Checksum;
+ UINT16 ip;
+ UINT16 cs;
+ UINT16 RelocPos;
+ UINT16 nOverlay;
+ UINT16 reserved[4];
+ UINT16 OEMId;
+ UINT16 OEMInfo;
+ UINT16 reserved2[10];
+ UINT32 ExeHeader;
+} __attribute__((packed));
+
+#define PE_HEADER_MACHINE_I386 0x014c
+#define PE_HEADER_MACHINE_X64 0x8664
+struct PeFileHeader {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} __attribute__((packed));
+
+struct PeHeader {
+ UINT8 Magic[4];
+ struct PeFileHeader FileHeader;
+} __attribute__((packed));
+
+struct PeSectionHeader {
+ UINT8 Name[8];
+ UINT32 VirtualSize;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} __attribute__((packed));
+
+EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
+ struct DosFileHeader *dos;
+ struct PeHeader *pe;
+ UINTN i;
+ UINTN offset;
+
+ dos = (struct DosFileHeader *)base;
+
+ if (CompareMem(dos->Magic, "MZ", 2) != 0)
+ return EFI_LOAD_ERROR;
+
+ pe = (struct PeHeader *)&base[dos->ExeHeader];
+ if (CompareMem(pe->Magic, "PE\0\0", 4) != 0)
+ return EFI_LOAD_ERROR;
+
+ /* PE32+ Subsystem type */
+ if (pe->FileHeader.Machine != PE_HEADER_MACHINE_X64 &&
+ pe->FileHeader.Machine != PE_HEADER_MACHINE_I386)
+ return EFI_LOAD_ERROR;
+
+ if (pe->FileHeader.NumberOfSections > 96)
+ return EFI_LOAD_ERROR;
+
+ offset = dos->ExeHeader + sizeof(*pe) + pe->FileHeader.SizeOfOptionalHeader;
+
+ for (i = 0; i < pe->FileHeader.NumberOfSections; i++) {
+ struct PeSectionHeader *sect;
+ UINTN j;
+
+ sect = (struct PeSectionHeader *)&base[offset];
+ for (j = 0; sections[j]; j++) {
+ if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0)
+ continue;
+
+ if (addrs)
+ addrs[j] = (UINTN)sect->VirtualAddress;
+ if (offsets)
+ offsets[j] = (UINTN)sect->PointerToRawData;
+ if (sizes)
+ sizes[j] = (UINTN)sect->VirtualSize;
+ }
+ offset += sizeof(*sect);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS pe_file_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
+ EFI_FILE_HANDLE handle;
+ struct DosFileHeader dos;
+ struct PeHeader pe;
+ UINTN len;
+ UINTN headerlen;
+ EFI_STATUS err;
+ CHAR8 *header = NULL;
+
+ err = uefi_call_wrapper(dir->Open, 5, dir, &handle, path, EFI_FILE_MODE_READ, 0ULL);
+ if (EFI_ERROR(err))
+ return err;
+
+ /* MS-DOS stub */
+ len = sizeof(dos);
+ err = uefi_call_wrapper(handle->Read, 3, handle, &len, &dos);
+ if (EFI_ERROR(err))
+ goto out;
+ if (len != sizeof(dos)) {
+ err = EFI_LOAD_ERROR;
+ goto out;
+ }
+
+ err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader);
+ if (EFI_ERROR(err))
+ goto out;
+
+ len = sizeof(pe);
+ err = uefi_call_wrapper(handle->Read, 3, handle, &len, &pe);
+ if (EFI_ERROR(err))
+ goto out;
+ if (len != sizeof(pe)) {
+ err = EFI_LOAD_ERROR;
+ goto out;
+ }
+
+ headerlen = sizeof(dos) + sizeof(pe) + pe.FileHeader.SizeOfOptionalHeader + pe.FileHeader.NumberOfSections * sizeof(struct PeSectionHeader);
+ header = AllocatePool(headerlen);
+ if (!header) {
+ err = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+ len = headerlen;
+ err = uefi_call_wrapper(handle->SetPosition, 2, handle, 0);
+ if (EFI_ERROR(err))
+ goto out;
+
+ err = uefi_call_wrapper(handle->Read, 3, handle, &len, header);
+ if (EFI_ERROR(err)) {
+ goto out;
+ }
+ if (len != headerlen) {
+ err = EFI_LOAD_ERROR;
+ goto out;
+ }
+
+ err = pe_memory_locate_sections(header, sections, addrs, offsets, sizes);
+out:
+ if (header)
+ FreePool(header);
+ uefi_call_wrapper(handle->Close, 1, handle);
+ return err;
+}
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Copyright (C) 2015 Kay Sievers <kay@vrfy.org>
+ */
+
+#ifndef __SDBOOT_PEFILE_H
+#define __SDBOOT_PEFILE_H
+
+EFI_STATUS pe_memory_locate_sections(CHAR8 *base,
+ CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes);
+EFI_STATUS pe_file_locate_sections(EFI_FILE *dir, CHAR16 *path,
+ CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes);
+#endif
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * Copyright (C) 2015 Kay Sievers <kay@vrfy.org>
- */
-
-#include <efi.h>
-#include <efilib.h>
-
-#include "pefile.h"
-#include "util.h"
-
-struct DosFileHeader {
- UINT8 Magic[2];
- UINT16 LastSize;
- UINT16 nBlocks;
- UINT16 nReloc;
- UINT16 HdrSize;
- UINT16 MinAlloc;
- UINT16 MaxAlloc;
- UINT16 ss;
- UINT16 sp;
- UINT16 Checksum;
- UINT16 ip;
- UINT16 cs;
- UINT16 RelocPos;
- UINT16 nOverlay;
- UINT16 reserved[4];
- UINT16 OEMId;
- UINT16 OEMInfo;
- UINT16 reserved2[10];
- UINT32 ExeHeader;
-} __attribute__((packed));
-
-#define PE_HEADER_MACHINE_I386 0x014c
-#define PE_HEADER_MACHINE_X64 0x8664
-struct PeFileHeader {
- UINT16 Machine;
- UINT16 NumberOfSections;
- UINT32 TimeDateStamp;
- UINT32 PointerToSymbolTable;
- UINT32 NumberOfSymbols;
- UINT16 SizeOfOptionalHeader;
- UINT16 Characteristics;
-} __attribute__((packed));
-
-struct PeSectionHeader {
- UINT8 Name[8];
- UINT32 VirtualSize;
- UINT32 VirtualAddress;
- UINT32 SizeOfRawData;
- UINT32 PointerToRawData;
- UINT32 PointerToRelocations;
- UINT32 PointerToLinenumbers;
- UINT16 NumberOfRelocations;
- UINT16 NumberOfLinenumbers;
- UINT32 Characteristics;
-} __attribute__((packed));
-
-
-EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
- EFI_FILE_HANDLE handle;
- struct DosFileHeader dos;
- uint8_t magic[4];
- struct PeFileHeader pe;
- UINTN len;
- UINTN i;
- EFI_STATUS err;
-
- err = uefi_call_wrapper(dir->Open, 5, dir, &handle, path, EFI_FILE_MODE_READ, 0ULL);
- if (EFI_ERROR(err))
- return err;
-
- /* MS-DOS stub */
- len = sizeof(dos);
- err = uefi_call_wrapper(handle->Read, 3, handle, &len, &dos);
- if (EFI_ERROR(err))
- goto out;
- if (len != sizeof(dos)) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- if (CompareMem(dos.Magic, "MZ", 2) != 0) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader);
- if (EFI_ERROR(err))
- goto out;
-
- /* PE header */
- len = sizeof(magic);
- err = uefi_call_wrapper(handle->Read, 3, handle, &len, &magic);
- if (EFI_ERROR(err))
- goto out;
- if (len != sizeof(magic)) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- if (CompareMem(magic, "PE\0\0", 2) != 0) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- len = sizeof(pe);
- err = uefi_call_wrapper(handle->Read, 3, handle, &len, &pe);
- if (EFI_ERROR(err))
- goto out;
- if (len != sizeof(pe)) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- /* PE32+ Subsystem type */
- if (pe.Machine != PE_HEADER_MACHINE_X64 &&
- pe.Machine != PE_HEADER_MACHINE_I386) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- if (pe.NumberOfSections > 96) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
-
- /* the sections start directly after the headers */
- err = uefi_call_wrapper(handle->SetPosition, 2, handle, dos.ExeHeader + sizeof(magic) + sizeof(pe) + pe.SizeOfOptionalHeader);
- if (EFI_ERROR(err))
- goto out;
-
- for (i = 0; i < pe.NumberOfSections; i++) {
- struct PeSectionHeader sect;
- UINTN j;
-
- len = sizeof(sect);
- err = uefi_call_wrapper(handle->Read, 3, handle, &len, §);
- if (EFI_ERROR(err))
- goto out;
- if (len != sizeof(sect)) {
- err = EFI_LOAD_ERROR;
- goto out;
- }
- for (j = 0; sections[j]; j++) {
- if (CompareMem(sect.Name, sections[j], strlena(sections[j])) != 0)
- continue;
-
- if (addrs)
- addrs[j] = (UINTN)sect.VirtualAddress;
- if (offsets)
- offsets[j] = (UINTN)sect.PointerToRawData;
- if (sizes)
- sizes[j] = (UINTN)sect.VirtualSize;
- }
- }
-
-out:
- uefi_call_wrapper(handle->Close, 1, handle);
- return err;
-}
+++ /dev/null
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * Copyright (C) 2015 Kay Sievers <kay@vrfy.org>
- */
-
-#ifndef __SDBOOT_PEFILE_H
-#define __SDBOOT_PEFILE_H
-
-EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path,
- CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes);
-#endif
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Port to systemd-boot
+ * Copyright 2017 Max Resch <resch.max@gmail.com>
+ *
+ * Security Policy Handling
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ * https://github.com/mjg59/efitools
+ */
+
+#include <efi.h>
+#include <efilib.h>
+
+#include "util.h"
+#include "shim.h"
+
+/* well known shim lock guid */
+#define SHIM_LOCK_GUID
+
+struct ShimLock {
+ EFI_STATUS __attribute__((sysv_abi)) (*shim_verify) (VOID *buffer, UINT32 size);
+
+ /* context is actually a struct for the PE header, but it isn't needed so void is sufficient just do define the interface
+ * see shim.c/shim.h and PeHeader.h in the github shim repo */
+ EFI_STATUS __attribute__((sysv_abi)) (*generate_hash) (VOID *data, UINT32 datasize, VOID *context, UINT8 *sha256hash, UINT8 *sha1hash);
+
+ EFI_STATUS __attribute__((sysv_abi)) (*read_header) (VOID *data, UINT32 datasize, VOID *context);
+};
+
+static const EFI_GUID simple_fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL;
+static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
+
+static const EFI_GUID security_protocol_guid = { 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } };
+static const EFI_GUID security2_protocol_guid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
+static const EFI_GUID shim_lock_guid = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+
+BOOLEAN shim_loaded(void) {
+ struct ShimLock *shim_lock;
+
+ return uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS;
+}
+
+static BOOLEAN shim_validate(VOID *data, UINT32 size) {
+ struct ShimLock *shim_lock;
+
+ if (!data)
+ return FALSE;
+
+ if (uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) != EFI_SUCCESS)
+ return FALSE;
+
+ if (!shim_lock)
+ return FALSE;
+
+ if (shim_lock->shim_verify(data, size) == EFI_SUCCESS)
+ return TRUE;
+
+ return FALSE;
+}
+
+BOOLEAN secure_boot_enabled(void) {
+ CHAR8 *b;
+ UINTN size;
+ BOOLEAN result;
+
+ if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) {
+ result = *b > 0;
+ FreePool(b);
+ return result;
+ }
+
+ return FALSE;
+}
+
+/*
+ * See the UEFI Platform Initialization manual (Vol2: DXE) for this
+ */
+struct _EFI_SECURITY2_PROTOCOL;
+struct _EFI_SECURITY_PROTOCOL;
+struct _EFI_DEVICE_PATH_PROTOCOL;
+
+typedef struct _EFI_SECURITY2_PROTOCOL EFI_SECURITY2_PROTOCOL;
+typedef struct _EFI_SECURITY_PROTOCOL EFI_SECURITY_PROTOCOL;
+typedef struct _EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY_FILE_AUTHENTICATION_STATE) (
+ const EFI_SECURITY_PROTOCOL *This,
+ UINT32 AuthenticationStatus,
+ const EFI_DEVICE_PATH_PROTOCOL *File
+);
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
+ const EFI_SECURITY2_PROTOCOL *This,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ VOID *FileBuffer,
+ UINTN FileSize,
+ BOOLEAN BootPolicy
+);
+
+struct _EFI_SECURITY2_PROTOCOL {
+ EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
+
+struct _EFI_SECURITY_PROTOCOL {
+ EFI_SECURITY_FILE_AUTHENTICATION_STATE FileAuthenticationState;
+};
+
+/* Handle to the original authenticator for security1 protocol */
+static EFI_SECURITY_FILE_AUTHENTICATION_STATE esfas = NULL;
+
+/* Handle to the original authenticator for security2 protocol */
+static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
+
+/*
+ * Perform shim/MOK and Secure Boot authentication on a binary that's already been
+ * loaded into memory. This function does the platform SB authentication first
+ * but preserves its return value in case of its failure, so that it can be
+ * returned in case of a shim/MOK authentication failure. This is done because
+ * the SB failure code seems to vary from one implementation to another, and I
+ * don't want to interfere with that at this time.
+ */
+static EFIAPI EFI_STATUS security2_policy_authentication (const EFI_SECURITY2_PROTOCOL *this,
+ const EFI_DEVICE_PATH_PROTOCOL *device_path,
+ VOID *file_buffer, UINTN file_size, BOOLEAN boot_policy) {
+ EFI_STATUS status;
+
+ /* Chain original security policy */
+ status = uefi_call_wrapper(es2fa, 5, this, device_path, file_buffer, file_size, boot_policy);
+
+ /* if OK, don't bother with MOK check */
+ if (status == EFI_SUCCESS)
+ return status;
+
+ if (shim_validate(file_buffer, file_size))
+ return EFI_SUCCESS;
+
+ return status;
+}
+
+/*
+ * Perform both shim/MOK and platform Secure Boot authentication. This function loads
+ * the file and performs shim/MOK authentication first simply to avoid double loads
+ * of Linux kernels, which are much more likely to be shim/MOK-signed than platform-signed,
+ * since kernels are big and can take several seconds to load on some computers and
+ * filesystems. This also has the effect of returning whatever the platform code is for
+ * authentication failure, be it EFI_ACCESS_DENIED, EFI_SECURITY_VIOLATION, or something
+ * else. (This seems to vary between implementations.)
+ */
+static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROTOCOL *this, UINT32 authentication_status,
+ const EFI_DEVICE_PATH_PROTOCOL *device_path_const) {
+ EFI_STATUS status;
+ EFI_DEVICE_PATH *dev_path;
+ EFI_HANDLE h;
+ EFI_FILE *root;
+ VOID *file_buffer = NULL;
+ UINTN file_size;
+ CHAR16 *dev_path_str;
+
+ if (!device_path_const)
+ return EFI_INVALID_PARAMETER;
+
+ dev_path = DuplicateDevicePath((EFI_DEVICE_PATH*) device_path_const);
+
+ status = uefi_call_wrapper(BS->LocateDevicePath, 3, (EFI_GUID*) &simple_fs_guid, &dev_path, &h);
+ if (status != EFI_SUCCESS) {
+ FreePool(dev_path);
+ return status;
+ }
+
+ /* No need to check return value, this already happend in efi_main() */
+ root = LibOpenRoot(h);
+ dev_path_str = DevicePathToStr(dev_path);
+ FreePool(dev_path);
+
+ file_size = file_read(root, dev_path_str, 0, 0, file_buffer);
+ FreePool(dev_path_str);
+ uefi_call_wrapper(root->Close, 1, root);
+
+ if (shim_validate(file_buffer, file_size))
+ status = EFI_SUCCESS;
+
+ FreePool(file_buffer);
+
+ /* Try using the platform's native policy.... */
+ if (status != EFI_SUCCESS)
+ status = uefi_call_wrapper(esfas, 3, this, authentication_status, device_path_const);
+
+ return status;
+}
+
+EFI_STATUS security_policy_install(void) {
+ EFI_SECURITY_PROTOCOL *security_protocol;
+ EFI_SECURITY2_PROTOCOL *security2_protocol = NULL;
+ EFI_STATUS status;
+
+ /* Already Installed */
+ if (esfas)
+ return EFI_ALREADY_STARTED;
+
+ /*
+ * Don't bother with status here. The call is allowed
+ * to fail, since SECURITY2 was introduced in PI 1.2.1
+ * If it fails, use security2_protocol == NULL as indicator
+ */
+ uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol);
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol);
+ /* This one is mandatory, so there's a serious problem */
+ if (status != EFI_SUCCESS)
+ return status;
+
+ if (!security2_protocol) {
+ es2fa = security2_protocol->FileAuthentication;
+ security2_protocol->FileAuthentication = security2_policy_authentication;
+ }
+
+ esfas = security_protocol->FileAuthenticationState;
+ security_protocol->FileAuthenticationState = security_policy_authentication;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS security_policy_uninstall(void) {
+ EFI_STATUS status;
+
+ if (esfas) {
+ EFI_SECURITY_PROTOCOL *security_protocol;
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ security_protocol->FileAuthenticationState = esfas;
+ esfas = NULL;
+ } else
+ /* nothing installed */
+ return EFI_NOT_STARTED;
+
+ if (es2fa) {
+ EFI_SECURITY2_PROTOCOL *security2_protocol;
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol);
+
+ if (status != EFI_SUCCESS)
+ return status;
+
+ security2_protocol->FileAuthentication = es2fa;
+ es2fa = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Port to systemd-boot
+ * Copyright 2017 Max Resch <resch.max@gmail.com>
+ *
+ * Security Policy Handling
+ * Copyright 2012 <James.Bottomley@HansenPartnership.com>
+ * https://github.com/mjg59/efitools
+ */
+
+#ifndef __SDBOOT_SHIM_H
+#define __SDBOOT_SHIM_H
+
+BOOLEAN shim_loaded(void);
+
+BOOLEAN secure_boot_enabled(void);
+
+EFI_STATUS security_policy_install(void);
+
+EFI_STATUS security_policy_uninstall(void);
+
+#endif
#include "disk.h"
#include "graphics.h"
#include "linux.h"
-#include "pefile.h"
+#include "measure.h"
+#include "pe.h"
#include "splash.h"
#include "util.h"
-#include "measure.h"
/* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " VERSION " ####";
+static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " PACKAGE_VERSION " ####";
static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
EFI_LOADED_IMAGE *loaded_image;
- EFI_FILE *root_dir;
- CHAR16 *loaded_image_path;
CHAR8 *b;
UINTN size;
BOOLEAN secure = FALSE;
return err;
}
- root_dir = LibOpenRoot(loaded_image->DeviceHandle);
- if (!root_dir) {
- Print(L"Unable to open root directory: %r ", err);
- uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
- return EFI_LOAD_ERROR;
- }
-
- loaded_image_path = DevicePathToStr(loaded_image->FilePath);
-
if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) {
if (*b > 0)
secure = TRUE;
FreePool(b);
}
-
- err = pefile_locate_sections(root_dir, loaded_image_path, sections, addrs, offs, szs);
+ err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
if (EFI_ERROR(err)) {
Print(L"Unable to locate embedded .linux section: %r ", err);
uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-bus.h"
+
+#include "alloc-util.h"
+#include "busctl-introspect.h"
+#include "string-util.h"
+#include "util.h"
+#include "xml.h"
+
+#define NODE_DEPTH_MAX 16
+
+typedef struct Context {
+ const XMLIntrospectOps *ops;
+ void *userdata;
+
+ char *interface_name;
+ uint64_t interface_flags;
+
+ char *member_name;
+ char *member_signature;
+ char *member_result;
+ uint64_t member_flags;
+ bool member_writable;
+
+ const char *current;
+ void *xml_state;
+} Context;
+
+static void context_reset_member(Context *c) {
+ free(c->member_name);
+ free(c->member_signature);
+ free(c->member_result);
+
+ c->member_name = c->member_signature = c->member_result = NULL;
+ c->member_flags = 0;
+ c->member_writable = false;
+}
+
+static void context_reset_interface(Context *c) {
+ c->interface_name = mfree(c->interface_name);
+ c->interface_flags = 0;
+
+ context_reset_member(c);
+}
+
+static int parse_xml_annotation(Context *context, uint64_t *flags) {
+
+ enum {
+ STATE_ANNOTATION,
+ STATE_NAME,
+ STATE_VALUE
+ } state = STATE_ANNOTATION;
+
+ _cleanup_free_ char *field = NULL, *value = NULL;
+
+ assert(context);
+
+ for (;;) {
+ _cleanup_free_ char *name = NULL;
+
+ int t;
+
+ t = xml_tokenize(&context->current, &name, &context->xml_state, NULL);
+ if (t < 0) {
+ log_error("XML parse error.");
+ return t;
+ }
+
+ if (t == XML_END) {
+ log_error("Premature end of XML data.");
+ return -EBADMSG;
+ }
+
+ switch (state) {
+
+ case STATE_ANNOTATION:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+
+ if (streq_ptr(name, "name"))
+ state = STATE_NAME;
+
+ else if (streq_ptr(name, "value"))
+ state = STATE_VALUE;
+
+ else {
+ log_error("Unexpected <annotation> attribute %s.", name);
+ return -EBADMSG;
+ }
+
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "annotation"))) {
+
+ if (flags) {
+ if (streq_ptr(field, "org.freedesktop.DBus.Deprecated")) {
+
+ if (streq_ptr(value, "true"))
+ *flags |= SD_BUS_VTABLE_DEPRECATED;
+
+ } else if (streq_ptr(field, "org.freedesktop.DBus.Method.NoReply")) {
+
+ if (streq_ptr(value, "true"))
+ *flags |= SD_BUS_VTABLE_METHOD_NO_REPLY;
+
+ } else if (streq_ptr(field, "org.freedesktop.DBus.Property.EmitsChangedSignal")) {
+
+ if (streq_ptr(value, "const"))
+ *flags = (*flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE)) | SD_BUS_VTABLE_PROPERTY_CONST;
+ else if (streq_ptr(value, "invalidates"))
+ *flags = (*flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_CONST)) | SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION;
+ else if (streq_ptr(value, "false"))
+ *flags = *flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION);
+ }
+ }
+
+ return 0;
+
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in <annotation>. (1)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(field, name);
+
+ state = STATE_ANNOTATION;
+ } else {
+ log_error("Unexpected token in <annotation>. (2)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_VALUE:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(value, name);
+
+ state = STATE_ANNOTATION;
+ } else {
+ log_error("Unexpected token in <annotation>. (3)");
+ return -EINVAL;
+ }
+
+ break;
+
+ default:
+ assert_not_reached("Bad state");
+ }
+ }
+}
+
+static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth) {
+
+ enum {
+ STATE_NODE,
+ STATE_NODE_NAME,
+ STATE_INTERFACE,
+ STATE_INTERFACE_NAME,
+ STATE_METHOD,
+ STATE_METHOD_NAME,
+ STATE_METHOD_ARG,
+ STATE_METHOD_ARG_NAME,
+ STATE_METHOD_ARG_TYPE,
+ STATE_METHOD_ARG_DIRECTION,
+ STATE_SIGNAL,
+ STATE_SIGNAL_NAME,
+ STATE_SIGNAL_ARG,
+ STATE_SIGNAL_ARG_NAME,
+ STATE_SIGNAL_ARG_TYPE,
+ STATE_SIGNAL_ARG_DIRECTION,
+ STATE_PROPERTY,
+ STATE_PROPERTY_NAME,
+ STATE_PROPERTY_TYPE,
+ STATE_PROPERTY_ACCESS,
+ } state = STATE_NODE;
+
+ _cleanup_free_ char *node_path = NULL, *argument_type = NULL, *argument_direction = NULL;
+ const char *np = prefix;
+ int r;
+
+ assert(context);
+ assert(prefix);
+
+ if (n_depth > NODE_DEPTH_MAX) {
+ log_error("<node> depth too high.");
+ return -EINVAL;
+ }
+
+ for (;;) {
+ _cleanup_free_ char *name = NULL;
+ int t;
+
+ t = xml_tokenize(&context->current, &name, &context->xml_state, NULL);
+ if (t < 0) {
+ log_error("XML parse error.");
+ return t;
+ }
+
+ if (t == XML_END) {
+ log_error("Premature end of XML data.");
+ return -EBADMSG;
+ }
+
+ switch (state) {
+
+ case STATE_NODE:
+ if (t == XML_ATTRIBUTE_NAME) {
+
+ if (streq_ptr(name, "name"))
+ state = STATE_NODE_NAME;
+ else {
+ log_error("Unexpected <node> attribute %s.", name);
+ return -EBADMSG;
+ }
+
+ } else if (t == XML_TAG_OPEN) {
+
+ if (streq_ptr(name, "interface"))
+ state = STATE_INTERFACE;
+ else if (streq_ptr(name, "node")) {
+
+ r = parse_xml_node(context, np, n_depth+1);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected <node> tag %s.", name);
+ return -EBADMSG;
+ }
+
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "node"))) {
+
+ if (context->ops->on_path) {
+ r = context->ops->on_path(node_path ? node_path : np, context->userdata);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in <node>. (1)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_NODE_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+
+ free(node_path);
+
+ if (name[0] == '/') {
+ node_path = name;
+ name = NULL;
+ } else {
+
+ if (endswith(prefix, "/"))
+ node_path = strappend(prefix, name);
+ else
+ node_path = strjoin(prefix, "/", name);
+ if (!node_path)
+ return log_oom();
+ }
+
+ np = node_path;
+ state = STATE_NODE;
+ } else {
+ log_error("Unexpected token in <node>. (2)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_INTERFACE:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+ if (streq_ptr(name, "name"))
+ state = STATE_INTERFACE_NAME;
+ else {
+ log_error("Unexpected <interface> attribute %s.", name);
+ return -EBADMSG;
+ }
+
+ } else if (t == XML_TAG_OPEN) {
+ if (streq_ptr(name, "method"))
+ state = STATE_METHOD;
+ else if (streq_ptr(name, "signal"))
+ state = STATE_SIGNAL;
+ else if (streq_ptr(name, "property")) {
+ context->member_flags |= SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE;
+ state = STATE_PROPERTY;
+ } else if (streq_ptr(name, "annotation")) {
+ r = parse_xml_annotation(context, &context->interface_flags);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected <interface> tag %s.", name);
+ return -EINVAL;
+ }
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "interface"))) {
+
+ if (n_depth == 0) {
+ if (context->ops->on_interface) {
+ r = context->ops->on_interface(context->interface_name, context->interface_flags, context->userdata);
+ if (r < 0)
+ return r;
+ }
+
+ context_reset_interface(context);
+ }
+
+ state = STATE_NODE;
+
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in <interface>. (1)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_INTERFACE_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ if (n_depth == 0)
+ free_and_replace(context->interface_name, name);
+
+ state = STATE_INTERFACE;
+ } else {
+ log_error("Unexpected token in <interface>. (2)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_METHOD:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+ if (streq_ptr(name, "name"))
+ state = STATE_METHOD_NAME;
+ else {
+ log_error("Unexpected <method> attribute %s", name);
+ return -EBADMSG;
+ }
+ } else if (t == XML_TAG_OPEN) {
+ if (streq_ptr(name, "arg"))
+ state = STATE_METHOD_ARG;
+ else if (streq_ptr(name, "annotation")) {
+ r = parse_xml_annotation(context, &context->member_flags);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected <method> tag %s.", name);
+ return -EINVAL;
+ }
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "method"))) {
+
+ if (n_depth == 0) {
+ if (context->ops->on_method) {
+ r = context->ops->on_method(context->interface_name, context->member_name, context->member_signature, context->member_result, context->member_flags, context->userdata);
+ if (r < 0)
+ return r;
+ }
+
+ context_reset_member(context);
+ }
+
+ state = STATE_INTERFACE;
+
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in <method> (1).");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_METHOD_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ if (n_depth == 0)
+ free_and_replace(context->member_name, name);
+
+ state = STATE_METHOD;
+ } else {
+ log_error("Unexpected token in <method> (2).");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_METHOD_ARG:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+ if (streq_ptr(name, "name"))
+ state = STATE_METHOD_ARG_NAME;
+ else if (streq_ptr(name, "type"))
+ state = STATE_METHOD_ARG_TYPE;
+ else if (streq_ptr(name, "direction"))
+ state = STATE_METHOD_ARG_DIRECTION;
+ else {
+ log_error("Unexpected method <arg> attribute %s.", name);
+ return -EBADMSG;
+ }
+ } else if (t == XML_TAG_OPEN) {
+ if (streq_ptr(name, "annotation")) {
+ r = parse_xml_annotation(context, NULL);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected method <arg> tag %s.", name);
+ return -EINVAL;
+ }
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
+
+ if (n_depth == 0) {
+
+ if (argument_type) {
+ if (!argument_direction || streq(argument_direction, "in")) {
+ if (!strextend(&context->member_signature, argument_type, NULL))
+ return log_oom();
+ } else if (streq(argument_direction, "out")) {
+ if (!strextend(&context->member_result, argument_type, NULL))
+ return log_oom();
+ } else
+ log_error("Unexpected method <arg> direction value '%s'.", argument_direction);
+ }
+
+ argument_type = mfree(argument_type);
+ argument_direction = mfree(argument_direction);
+ }
+
+ state = STATE_METHOD;
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in method <arg>. (1)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_METHOD_ARG_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE)
+ state = STATE_METHOD_ARG;
+ else {
+ log_error("Unexpected token in method <arg>. (2)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_METHOD_ARG_TYPE:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(argument_type, name);
+
+ state = STATE_METHOD_ARG;
+ } else {
+ log_error("Unexpected token in method <arg>. (3)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_METHOD_ARG_DIRECTION:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(argument_direction, name);
+
+ state = STATE_METHOD_ARG;
+ } else {
+ log_error("Unexpected token in method <arg>. (4)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_SIGNAL:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+ if (streq_ptr(name, "name"))
+ state = STATE_SIGNAL_NAME;
+ else {
+ log_error("Unexpected <signal> attribute %s.", name);
+ return -EBADMSG;
+ }
+ } else if (t == XML_TAG_OPEN) {
+ if (streq_ptr(name, "arg"))
+ state = STATE_SIGNAL_ARG;
+ else if (streq_ptr(name, "annotation")) {
+ r = parse_xml_annotation(context, &context->member_flags);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected <signal> tag %s.", name);
+ return -EINVAL;
+ }
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "signal"))) {
+
+ if (n_depth == 0) {
+ if (context->ops->on_signal) {
+ r = context->ops->on_signal(context->interface_name, context->member_name, context->member_signature, context->member_flags, context->userdata);
+ if (r < 0)
+ return r;
+ }
+
+ context_reset_member(context);
+ }
+
+ state = STATE_INTERFACE;
+
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in <signal>. (1)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_SIGNAL_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ if (n_depth == 0)
+ free_and_replace(context->member_name, name);
+
+ state = STATE_SIGNAL;
+ } else {
+ log_error("Unexpected token in <signal>. (2)");
+ return -EINVAL;
+ }
+
+ break;
+
+
+ case STATE_SIGNAL_ARG:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+ if (streq_ptr(name, "name"))
+ state = STATE_SIGNAL_ARG_NAME;
+ else if (streq_ptr(name, "type"))
+ state = STATE_SIGNAL_ARG_TYPE;
+ else if (streq_ptr(name, "direction"))
+ state = STATE_SIGNAL_ARG_DIRECTION;
+ else {
+ log_error("Unexpected signal <arg> attribute %s.", name);
+ return -EBADMSG;
+ }
+ } else if (t == XML_TAG_OPEN) {
+ if (streq_ptr(name, "annotation")) {
+ r = parse_xml_annotation(context, NULL);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected signal <arg> tag %s.", name);
+ return -EINVAL;
+ }
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
+
+ if (argument_type) {
+ if (!argument_direction || streq(argument_direction, "out")) {
+ if (!strextend(&context->member_signature, argument_type, NULL))
+ return log_oom();
+ } else
+ log_error("Unexpected signal <arg> direction value '%s'.", argument_direction);
+
+ argument_type = mfree(argument_type);
+ }
+
+ state = STATE_SIGNAL;
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in signal <arg> (1).");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_SIGNAL_ARG_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE)
+ state = STATE_SIGNAL_ARG;
+ else {
+ log_error("Unexpected token in signal <arg> (2).");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_SIGNAL_ARG_TYPE:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(argument_type, name);
+
+ state = STATE_SIGNAL_ARG;
+ } else {
+ log_error("Unexpected token in signal <arg> (3).");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_SIGNAL_ARG_DIRECTION:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ free_and_replace(argument_direction, name);
+
+ state = STATE_SIGNAL_ARG;
+ } else {
+ log_error("Unexpected token in signal <arg>. (4)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_PROPERTY:
+
+ if (t == XML_ATTRIBUTE_NAME) {
+ if (streq_ptr(name, "name"))
+ state = STATE_PROPERTY_NAME;
+ else if (streq_ptr(name, "type"))
+ state = STATE_PROPERTY_TYPE;
+ else if (streq_ptr(name, "access"))
+ state = STATE_PROPERTY_ACCESS;
+ else {
+ log_error("Unexpected <property> attribute %s.", name);
+ return -EBADMSG;
+ }
+ } else if (t == XML_TAG_OPEN) {
+
+ if (streq_ptr(name, "annotation")) {
+ r = parse_xml_annotation(context, &context->member_flags);
+ if (r < 0)
+ return r;
+ } else {
+ log_error("Unexpected <property> tag %s.", name);
+ return -EINVAL;
+ }
+
+ } else if (t == XML_TAG_CLOSE_EMPTY ||
+ (t == XML_TAG_CLOSE && streq_ptr(name, "property"))) {
+
+ if (n_depth == 0) {
+ if (context->ops->on_property) {
+ r = context->ops->on_property(context->interface_name, context->member_name, context->member_signature, context->member_writable, context->member_flags, context->userdata);
+ if (r < 0)
+ return r;
+ }
+
+ context_reset_member(context);
+ }
+
+ state = STATE_INTERFACE;
+
+ } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token in <property>. (1)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_PROPERTY_NAME:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ if (n_depth == 0)
+ free_and_replace(context->member_name, name);
+
+ state = STATE_PROPERTY;
+ } else {
+ log_error("Unexpected token in <property>. (2)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_PROPERTY_TYPE:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+ if (n_depth == 0)
+ free_and_replace(context->member_signature, name);
+
+ state = STATE_PROPERTY;
+ } else {
+ log_error("Unexpected token in <property>. (3)");
+ return -EINVAL;
+ }
+
+ break;
+
+ case STATE_PROPERTY_ACCESS:
+
+ if (t == XML_ATTRIBUTE_VALUE) {
+
+ if (streq(name, "readwrite") || streq(name, "write"))
+ context->member_writable = true;
+
+ state = STATE_PROPERTY;
+ } else {
+ log_error("Unexpected token in <property>. (4)");
+ return -EINVAL;
+ }
+
+ break;
+ }
+ }
+}
+
+int parse_xml_introspect(const char *prefix, const char *xml, const XMLIntrospectOps *ops, void *userdata) {
+ Context context = {
+ .ops = ops,
+ .userdata = userdata,
+ .current = xml,
+ };
+
+ int r;
+
+ assert(prefix);
+ assert(xml);
+ assert(ops);
+
+ for (;;) {
+ _cleanup_free_ char *name = NULL;
+
+ r = xml_tokenize(&context.current, &name, &context.xml_state, NULL);
+ if (r < 0) {
+ log_error("XML parse error");
+ goto finish;
+ }
+
+ if (r == XML_END) {
+ r = 0;
+ break;
+ }
+
+ if (r == XML_TAG_OPEN) {
+
+ if (streq(name, "node")) {
+ r = parse_xml_node(&context, prefix, 0);
+ if (r < 0)
+ goto finish;
+ } else {
+ log_error("Unexpected tag '%s' in introspection data.", name);
+ r = -EBADMSG;
+ goto finish;
+ }
+ } else if (r != XML_TEXT || !in_charset(name, WHITESPACE)) {
+ log_error("Unexpected token.");
+ r = -EBADMSG;
+ goto finish;
+ }
+ }
+
+finish:
+ context_reset_interface(&context);
+
+ return r;
+}
--- /dev/null
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+typedef struct XMLIntrospectOps {
+ int (*on_path)(const char *path, void *userdata);
+ int (*on_interface)(const char *name, uint64_t flags, void *userdata);
+ int (*on_method)(const char *interface, const char *name, const char *signature, const char *result, uint64_t flags, void *userdata);
+ int (*on_signal)(const char *interface, const char *name, const char *signature, uint64_t flags, void *userdata);
+ int (*on_property)(const char *interface, const char *name, const char *signature, bool writable, uint64_t flags, void *userdata);
+} XMLIntrospectOps;
+
+int parse_xml_introspect(const char *prefix, const char *xml, const XMLIntrospectOps *ops, void *userdata);
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2013 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <getopt.h>
+
+#include "sd-bus.h"
+
+#include "alloc-util.h"
+#include "bus-dump.h"
+#include "bus-internal.h"
+#include "bus-signature.h"
+#include "bus-type.h"
+#include "bus-util.h"
+#include "busctl-introspect.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "locale-util.h"
+#include "log.h"
+#include "pager.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "set.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "user-util.h"
+#include "util.h"
+
+static bool arg_no_pager = false;
+static bool arg_legend = true;
+static char *arg_address = NULL;
+static bool arg_unique = false;
+static bool arg_acquired = false;
+static bool arg_activatable = false;
+static bool arg_show_machine = false;
+static char **arg_matches = NULL;
+static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
+static char *arg_host = NULL;
+static bool arg_user = false;
+static size_t arg_snaplen = 4096;
+static bool arg_list = false;
+static bool arg_quiet = false;
+static bool arg_verbose = false;
+static bool arg_expect_reply = true;
+static bool arg_auto_start = true;
+static bool arg_allow_interactive_authorization = true;
+static bool arg_augment_creds = true;
+static usec_t arg_timeout = 0;
+
+#define NAME_IS_ACQUIRED INT_TO_PTR(1)
+#define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
+
+static int list_bus_names(sd_bus *bus, char **argv) {
+ _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
+ _cleanup_free_ char **merged = NULL;
+ _cleanup_hashmap_free_ Hashmap *names = NULL;
+ char **i;
+ int r;
+ size_t max_i = 0;
+ unsigned n = 0;
+ void *v;
+ char *k;
+ Iterator iterator;
+
+ assert(bus);
+
+ if (!arg_unique && !arg_acquired && !arg_activatable)
+ arg_unique = arg_acquired = arg_activatable = true;
+
+ r = sd_bus_list_names(bus, (arg_acquired || arg_unique) ? &acquired : NULL, arg_activatable ? &activatable : NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to list names: %m");
+
+ pager_open(arg_no_pager, false);
+
+ names = hashmap_new(&string_hash_ops);
+ if (!names)
+ return log_oom();
+
+ STRV_FOREACH(i, acquired) {
+ max_i = MAX(max_i, strlen(*i));
+
+ r = hashmap_put(names, *i, NAME_IS_ACQUIRED);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add to hashmap: %m");
+ }
+
+ STRV_FOREACH(i, activatable) {
+ max_i = MAX(max_i, strlen(*i));
+
+ r = hashmap_put(names, *i, NAME_IS_ACTIVATABLE);
+ if (r < 0 && r != -EEXIST)
+ return log_error_errno(r, "Failed to add to hashmap: %m");
+ }
+
+ merged = new(char*, hashmap_size(names) + 1);
+ HASHMAP_FOREACH_KEY(v, k, names, iterator)
+ merged[n++] = k;
+
+ merged[n] = NULL;
+ strv_sort(merged);
+
+ if (arg_legend) {
+ printf("%-*s %*s %-*s %-*s %-*s %-*s %-*s %-*s",
+ (int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 13, "CONNECTION", 25, "UNIT", 10, "SESSION", 19, "DESCRIPTION");
+
+ if (arg_show_machine)
+ puts(" MACHINE");
+ else
+ putchar('\n');
+ }
+
+ STRV_FOREACH(i, merged) {
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ sd_id128_t mid;
+
+ if (hashmap_get(names, *i) == NAME_IS_ACTIVATABLE) {
+ /* Activatable */
+
+ printf("%-*s", (int) max_i, *i);
+ printf(" - - - (activatable) - - ");
+ if (arg_show_machine)
+ puts(" -");
+ else
+ putchar('\n');
+ continue;
+
+ }
+
+ if (!arg_unique && (*i)[0] == ':')
+ continue;
+
+ if (!arg_acquired && (*i)[0] != ':')
+ continue;
+
+ printf("%-*s", (int) max_i, *i);
+
+ r = sd_bus_get_name_creds(
+ bus, *i,
+ (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) |
+ SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
+ SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
+ SD_BUS_CREDS_DESCRIPTION, &creds);
+ if (r >= 0) {
+ const char *unique, *session, *unit, *cn;
+ pid_t pid;
+ uid_t uid;
+
+ r = sd_bus_creds_get_pid(creds, &pid);
+ if (r >= 0) {
+ const char *comm = NULL;
+
+ sd_bus_creds_get_comm(creds, &comm);
+
+ printf(" %10lu %-15s", (unsigned long) pid, strna(comm));
+ } else
+ fputs(" - - ", stdout);
+
+ r = sd_bus_creds_get_euid(creds, &uid);
+ if (r >= 0) {
+ _cleanup_free_ char *u = NULL;
+
+ u = uid_to_name(uid);
+ if (!u)
+ return log_oom();
+
+ if (strlen(u) > 16)
+ u[16] = 0;
+
+ printf(" %-16s", u);
+ } else
+ fputs(" - ", stdout);
+
+ r = sd_bus_creds_get_unique_name(creds, &unique);
+ if (r >= 0)
+ printf(" %-13s", unique);
+ else
+ fputs(" - ", stdout);
+
+ r = sd_bus_creds_get_unit(creds, &unit);
+ if (r >= 0) {
+ _cleanup_free_ char *e;
+
+ e = ellipsize(unit, 25, 100);
+ if (!e)
+ return log_oom();
+
+ printf(" %-25s", e);
+ } else
+ fputs(" - ", stdout);
+
+ r = sd_bus_creds_get_session(creds, &session);
+ if (r >= 0)
+ printf(" %-10s", session);
+ else
+ fputs(" - ", stdout);
+
+ r = sd_bus_creds_get_description(creds, &cn);
+ if (r >= 0)
+ printf(" %-19s", cn);
+ else
+ fputs(" - ", stdout);
+
+ } else
+ printf(" - - - - - - - ");
+
+ if (arg_show_machine) {
+ r = sd_bus_get_name_machine_id(bus, *i, &mid);
+ if (r >= 0) {
+ char m[SD_ID128_STRING_MAX];
+ printf(" %s\n", sd_id128_to_string(mid, m));
+ } else
+ puts(" -");
+ } else
+ putchar('\n');
+ }
+
+ return 0;
+}
+
+static void print_subtree(const char *prefix, const char *path, char **l) {
+ const char *vertical, *space;
+ char **n;
+
+ /* We assume the list is sorted. Let's first skip over the
+ * entry we are looking at. */
+ for (;;) {
+ if (!*l)
+ return;
+
+ if (!streq(*l, path))
+ break;
+
+ l++;
+ }
+
+ vertical = strjoina(prefix, special_glyph(TREE_VERTICAL));
+ space = strjoina(prefix, special_glyph(TREE_SPACE));
+
+ for (;;) {
+ bool has_more = false;
+
+ if (!*l || !path_startswith(*l, path))
+ break;
+
+ n = l + 1;
+ for (;;) {
+ if (!*n || !path_startswith(*n, path))
+ break;
+
+ if (!path_startswith(*n, *l)) {
+ has_more = true;
+ break;
+ }
+
+ n++;
+ }
+
+ printf("%s%s%s\n", prefix, special_glyph(has_more ? TREE_BRANCH : TREE_RIGHT), *l);
+
+ print_subtree(has_more ? vertical : space, *l, l);
+ l = n;
+ }
+}
+
+static void print_tree(const char *prefix, char **l) {
+
+ pager_open(arg_no_pager, false);
+
+ prefix = strempty(prefix);
+
+ if (arg_list) {
+ char **i;
+
+ STRV_FOREACH(i, l)
+ printf("%s%s\n", prefix, *i);
+ return;
+ }
+
+ if (strv_isempty(l)) {
+ printf("No objects discovered.\n");
+ return;
+ }
+
+ if (streq(l[0], "/") && !l[1]) {
+ printf("Only root object discovered.\n");
+ return;
+ }
+
+ print_subtree(prefix, "/", l);
+}
+
+static int on_path(const char *path, void *userdata) {
+ Set *paths = userdata;
+ int r;
+
+ assert(paths);
+
+ r = set_put_strdup(paths, path);
+ if (r < 0)
+ return log_oom();
+
+ return 0;
+}
+
+static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *paths, bool many) {
+ static const XMLIntrospectOps ops = {
+ .on_path = on_path,
+ };
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ const char *xml;
+ int r;
+
+ r = sd_bus_call_method(bus, service, path, "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
+ if (r < 0) {
+ if (many)
+ printf("Failed to introspect object %s of service %s: %s\n", path, service, bus_error_message(&error, r));
+ else
+ log_error("Failed to introspect object %s of service %s: %s", path, service, bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply, "s", &xml);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ return parse_xml_introspect(path, xml, &ops, paths);
+}
+
+static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool many) {
+ _cleanup_set_free_free_ Set *paths = NULL, *done = NULL, *failed = NULL;
+ _cleanup_free_ char **l = NULL;
+ char *m;
+ int r;
+
+ paths = set_new(&string_hash_ops);
+ if (!paths)
+ return log_oom();
+
+ done = set_new(&string_hash_ops);
+ if (!done)
+ return log_oom();
+
+ failed = set_new(&string_hash_ops);
+ if (!failed)
+ return log_oom();
+
+ m = strdup("/");
+ if (!m)
+ return log_oom();
+
+ r = set_put(paths, m);
+ if (r < 0) {
+ free(m);
+ return log_oom();
+ }
+
+ for (;;) {
+ _cleanup_free_ char *p = NULL;
+ int q;
+
+ p = set_steal_first(paths);
+ if (!p)
+ break;
+
+ if (set_contains(done, p) ||
+ set_contains(failed, p))
+ continue;
+
+ q = find_nodes(bus, service, p, paths, many);
+ if (q < 0) {
+ if (r >= 0)
+ r = q;
+
+ q = set_put(failed, p);
+ } else
+ q = set_put(done, p);
+
+ if (q < 0)
+ return log_oom();
+
+ assert(q != 0);
+ p = NULL;
+ }
+
+ pager_open(arg_no_pager, false);
+
+ l = set_get_strv(done);
+ if (!l)
+ return log_oom();
+
+ strv_sort(l);
+ print_tree(prefix, l);
+
+ fflush(stdout);
+
+ return r;
+}
+
+static int tree(sd_bus *bus, char **argv) {
+ char **i;
+ int r = 0;
+
+ if (!arg_unique && !arg_acquired)
+ arg_acquired = true;
+
+ if (strv_length(argv) <= 1) {
+ _cleanup_strv_free_ char **names = NULL;
+ bool not_first = false;
+
+ r = sd_bus_list_names(bus, &names, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get name list: %m");
+
+ pager_open(arg_no_pager, false);
+
+ STRV_FOREACH(i, names) {
+ int q;
+
+ if (!arg_unique && (*i)[0] == ':')
+ continue;
+
+ if (!arg_acquired && (*i)[0] == ':')
+ continue;
+
+ if (not_first)
+ printf("\n");
+
+ printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
+
+ q = tree_one(bus, *i, NULL, true);
+ if (q < 0 && r >= 0)
+ r = q;
+
+ not_first = true;
+ }
+ } else {
+ STRV_FOREACH(i, argv+1) {
+ int q;
+
+ if (i > argv+1)
+ printf("\n");
+
+ if (argv[2]) {
+ pager_open(arg_no_pager, false);
+ printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
+ }
+
+ q = tree_one(bus, *i, NULL, !!argv[2]);
+ if (q < 0 && r >= 0)
+ r = q;
+ }
+ }
+
+ return r;
+}
+
+static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) {
+ int r;
+
+ for (;;) {
+ const char *contents = NULL;
+ char type;
+ union {
+ uint8_t u8;
+ uint16_t u16;
+ int16_t s16;
+ uint32_t u32;
+ int32_t s32;
+ uint64_t u64;
+ int64_t s64;
+ double d64;
+ const char *string;
+ int i;
+ } basic;
+
+ r = sd_bus_message_peek_type(m, &type, &contents);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return needs_space;
+
+ if (bus_type_is_container(type) > 0) {
+
+ r = sd_bus_message_enter_container(m, type, contents);
+ if (r < 0)
+ return r;
+
+ if (type == SD_BUS_TYPE_ARRAY) {
+ unsigned n = 0;
+
+ /* count array entries */
+ for (;;) {
+
+ r = sd_bus_message_skip(m, contents);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ n++;
+ }
+
+ r = sd_bus_message_rewind(m, false);
+ if (r < 0)
+ return r;
+
+ if (needs_space)
+ fputc(' ', f);
+
+ fprintf(f, "%u", n);
+ needs_space = true;
+
+ } else if (type == SD_BUS_TYPE_VARIANT) {
+
+ if (needs_space)
+ fputc(' ', f);
+
+ fprintf(f, "%s", contents);
+ needs_space = true;
+ }
+
+ r = format_cmdline(m, f, needs_space);
+ if (r < 0)
+ return r;
+
+ needs_space = r > 0;
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return r;
+
+ continue;
+ }
+
+ r = sd_bus_message_read_basic(m, type, &basic);
+ if (r < 0)
+ return r;
+
+ if (needs_space)
+ fputc(' ', f);
+
+ switch (type) {
+ case SD_BUS_TYPE_BYTE:
+ fprintf(f, "%u", basic.u8);
+ break;
+
+ case SD_BUS_TYPE_BOOLEAN:
+ fputs(true_false(basic.i), f);
+ break;
+
+ case SD_BUS_TYPE_INT16:
+ fprintf(f, "%i", basic.s16);
+ break;
+
+ case SD_BUS_TYPE_UINT16:
+ fprintf(f, "%u", basic.u16);
+ break;
+
+ case SD_BUS_TYPE_INT32:
+ fprintf(f, "%i", basic.s32);
+ break;
+
+ case SD_BUS_TYPE_UINT32:
+ fprintf(f, "%u", basic.u32);
+ break;
+
+ case SD_BUS_TYPE_INT64:
+ fprintf(f, "%" PRIi64, basic.s64);
+ break;
+
+ case SD_BUS_TYPE_UINT64:
+ fprintf(f, "%" PRIu64, basic.u64);
+ break;
+
+ case SD_BUS_TYPE_DOUBLE:
+ fprintf(f, "%g", basic.d64);
+ break;
+
+ case SD_BUS_TYPE_STRING:
+ case SD_BUS_TYPE_OBJECT_PATH:
+ case SD_BUS_TYPE_SIGNATURE: {
+ _cleanup_free_ char *b = NULL;
+
+ b = cescape(basic.string);
+ if (!b)
+ return -ENOMEM;
+
+ fprintf(f, "\"%s\"", b);
+ break;
+ }
+
+ case SD_BUS_TYPE_UNIX_FD:
+ fprintf(f, "%i", basic.i);
+ break;
+
+ default:
+ assert_not_reached("Unknown basic type.");
+ }
+
+ needs_space = true;
+ }
+}
+
+typedef struct Member {
+ const char *type;
+ char *interface;
+ char *name;
+ char *signature;
+ char *result;
+ char *value;
+ bool writable;
+ uint64_t flags;
+} Member;
+
+static void member_hash_func(const void *p, struct siphash *state) {
+ const Member *m = p;
+ uint64_t arity = 1;
+
+ assert(m);
+ assert(m->type);
+
+ string_hash_func(m->type, state);
+
+ arity += !!m->name + !!m->interface;
+
+ uint64_hash_func(&arity, state);
+
+ if (m->name)
+ string_hash_func(m->name, state);
+
+ if (m->interface)
+ string_hash_func(m->interface, state);
+}
+
+static int member_compare_func(const void *a, const void *b) {
+ const Member *x = a, *y = b;
+ int d;
+
+ assert(x);
+ assert(y);
+ assert(x->type);
+ assert(y->type);
+
+ d = strcmp_ptr(x->interface, y->interface);
+ if (d != 0)
+ return d;
+
+ d = strcmp(x->type, y->type);
+ if (d != 0)
+ return d;
+
+ return strcmp_ptr(x->name, y->name);
+}
+
+static int member_compare_funcp(const void *a, const void *b) {
+ const Member *const * x = (const Member *const *) a, * const *y = (const Member *const *) b;
+
+ return member_compare_func(*x, *y);
+}
+
+static void member_free(Member *m) {
+ if (!m)
+ return;
+
+ free(m->interface);
+ free(m->name);
+ free(m->signature);
+ free(m->result);
+ free(m->value);
+ free(m);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Member*, member_free);
+
+static void member_set_free(Set *s) {
+ Member *m;
+
+ while ((m = set_steal_first(s)))
+ member_free(m);
+
+ set_free(s);
+}
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, member_set_free);
+
+static int on_interface(const char *interface, uint64_t flags, void *userdata) {
+ _cleanup_(member_freep) Member *m;
+ Set *members = userdata;
+ int r;
+
+ assert(interface);
+ assert(members);
+
+ m = new0(Member, 1);
+ if (!m)
+ return log_oom();
+
+ m->type = "interface";
+ m->flags = flags;
+
+ r = free_and_strdup(&m->interface, interface);
+ if (r < 0)
+ return log_oom();
+
+ r = set_put(members, m);
+ if (r <= 0) {
+ log_error("Duplicate interface");
+ return -EINVAL;
+ }
+
+ m = NULL;
+ return 0;
+}
+
+static int on_method(const char *interface, const char *name, const char *signature, const char *result, uint64_t flags, void *userdata) {
+ _cleanup_(member_freep) Member *m;
+ Set *members = userdata;
+ int r;
+
+ assert(interface);
+ assert(name);
+
+ m = new0(Member, 1);
+ if (!m)
+ return log_oom();
+
+ m->type = "method";
+ m->flags = flags;
+
+ r = free_and_strdup(&m->interface, interface);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->name, name);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->signature, signature);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->result, result);
+ if (r < 0)
+ return log_oom();
+
+ r = set_put(members, m);
+ if (r <= 0) {
+ log_error("Duplicate method");
+ return -EINVAL;
+ }
+
+ m = NULL;
+ return 0;
+}
+
+static int on_signal(const char *interface, const char *name, const char *signature, uint64_t flags, void *userdata) {
+ _cleanup_(member_freep) Member *m;
+ Set *members = userdata;
+ int r;
+
+ assert(interface);
+ assert(name);
+
+ m = new0(Member, 1);
+ if (!m)
+ return log_oom();
+
+ m->type = "signal";
+ m->flags = flags;
+
+ r = free_and_strdup(&m->interface, interface);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->name, name);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->signature, signature);
+ if (r < 0)
+ return log_oom();
+
+ r = set_put(members, m);
+ if (r <= 0) {
+ log_error("Duplicate signal");
+ return -EINVAL;
+ }
+
+ m = NULL;
+ return 0;
+}
+
+static int on_property(const char *interface, const char *name, const char *signature, bool writable, uint64_t flags, void *userdata) {
+ _cleanup_(member_freep) Member *m;
+ Set *members = userdata;
+ int r;
+
+ assert(interface);
+ assert(name);
+
+ m = new0(Member, 1);
+ if (!m)
+ return log_oom();
+
+ m->type = "property";
+ m->flags = flags;
+ m->writable = writable;
+
+ r = free_and_strdup(&m->interface, interface);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->name, name);
+ if (r < 0)
+ return log_oom();
+
+ r = free_and_strdup(&m->signature, signature);
+ if (r < 0)
+ return log_oom();
+
+ r = set_put(members, m);
+ if (r <= 0) {
+ log_error("Duplicate property");
+ return -EINVAL;
+ }
+
+ m = NULL;
+ return 0;
+}
+
+static const char *strdash(const char *x) {
+ return isempty(x) ? "-" : x;
+}
+
+static int introspect(sd_bus *bus, char **argv) {
+ static const struct hash_ops member_hash_ops = {
+ .hash = member_hash_func,
+ .compare = member_compare_func,
+ };
+
+ static const XMLIntrospectOps ops = {
+ .on_interface = on_interface,
+ .on_method = on_method,
+ .on_signal = on_signal,
+ .on_property = on_property,
+ };
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(member_set_freep) Set *members = NULL;
+ Iterator i;
+ Member *m;
+ const char *xml;
+ int r;
+ unsigned name_width, type_width, signature_width, result_width;
+ Member **sorted = NULL;
+ unsigned k = 0, j, n_args;
+
+ n_args = strv_length(argv);
+ if (n_args < 3) {
+ log_error("Requires service and object path argument.");
+ return -EINVAL;
+ }
+
+ if (n_args > 4) {
+ log_error("Too many arguments.");
+ return -EINVAL;
+ }
+
+ members = set_new(&member_hash_ops);
+ if (!members)
+ return log_oom();
+
+ r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
+ if (r < 0) {
+ log_error("Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply, "s", &xml);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ /* First, get list of all properties */
+ r = parse_xml_introspect(argv[2], xml, &ops, members);
+ if (r < 0)
+ return r;
+
+ /* Second, find the current values for them */
+ SET_FOREACH(m, members, i) {
+
+ if (!streq(m->type, "property"))
+ continue;
+
+ if (m->value)
+ continue;
+
+ if (argv[3] && !streq(argv[3], m->interface))
+ continue;
+
+ r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface);
+ if (r < 0) {
+ log_error("%s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_enter_container(reply, 'a', "{sv}");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ for (;;) {
+ Member *z;
+ _cleanup_free_ char *buf = NULL;
+ _cleanup_fclose_ FILE *mf = NULL;
+ size_t sz = 0;
+ const char *name;
+
+ r = sd_bus_message_enter_container(reply, 'e', "sv");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (r == 0)
+ break;
+
+ r = sd_bus_message_read(reply, "s", &name);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_enter_container(reply, 'v', NULL);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ mf = open_memstream(&buf, &sz);
+ if (!mf)
+ return log_oom();
+
+ r = format_cmdline(reply, mf, false);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ fclose(mf);
+ mf = NULL;
+
+ z = set_get(members, &((Member) {
+ .type = "property",
+ .interface = m->interface,
+ .name = (char*) name }));
+ if (z) {
+ free(z->value);
+ z->value = buf;
+ buf = NULL;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+ }
+
+ pager_open(arg_no_pager, false);
+
+ name_width = strlen("NAME");
+ type_width = strlen("TYPE");
+ signature_width = strlen("SIGNATURE");
+ result_width = strlen("RESULT/VALUE");
+
+ sorted = newa(Member*, set_size(members));
+
+ SET_FOREACH(m, members, i) {
+
+ if (argv[3] && !streq(argv[3], m->interface))
+ continue;
+
+ if (m->interface)
+ name_width = MAX(name_width, strlen(m->interface));
+ if (m->name)
+ name_width = MAX(name_width, strlen(m->name) + 1);
+ if (m->type)
+ type_width = MAX(type_width, strlen(m->type));
+ if (m->signature)
+ signature_width = MAX(signature_width, strlen(m->signature));
+ if (m->result)
+ result_width = MAX(result_width, strlen(m->result));
+ if (m->value)
+ result_width = MAX(result_width, strlen(m->value));
+
+ sorted[k++] = m;
+ }
+
+ if (result_width > 40)
+ result_width = 40;
+
+ qsort(sorted, k, sizeof(Member*), member_compare_funcp);
+
+ if (arg_legend) {
+ printf("%-*s %-*s %-*s %-*s %s\n",
+ (int) name_width, "NAME",
+ (int) type_width, "TYPE",
+ (int) signature_width, "SIGNATURE",
+ (int) result_width, "RESULT/VALUE",
+ "FLAGS");
+ }
+
+ for (j = 0; j < k; j++) {
+ _cleanup_free_ char *ellipsized = NULL;
+ const char *rv;
+ bool is_interface;
+
+ m = sorted[j];
+
+ if (argv[3] && !streq(argv[3], m->interface))
+ continue;
+
+ is_interface = streq(m->type, "interface");
+
+ if (argv[3] && is_interface)
+ continue;
+
+ if (m->value) {
+ ellipsized = ellipsize(m->value, result_width, 100);
+ if (!ellipsized)
+ return log_oom();
+
+ rv = ellipsized;
+ } else
+ rv = strdash(m->result);
+
+ printf("%s%s%-*s%s %-*s %-*s %-*s%s%s%s%s%s%s\n",
+ is_interface ? ansi_highlight() : "",
+ is_interface ? "" : ".",
+ - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name),
+ is_interface ? ansi_normal() : "",
+ (int) type_width, strdash(m->type),
+ (int) signature_width, strdash(m->signature),
+ (int) result_width, rv,
+ (m->flags & SD_BUS_VTABLE_DEPRECATED) ? " deprecated" : (m->flags || m->writable ? "" : " -"),
+ (m->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ? " no-reply" : "",
+ (m->flags & SD_BUS_VTABLE_PROPERTY_CONST) ? " const" : "",
+ (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) ? " emits-change" : "",
+ (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) ? " emits-invalidation" : "",
+ m->writable ? " writable" : "");
+ }
+
+ return 0;
+}
+
+static int message_dump(sd_bus_message *m, FILE *f) {
+ return bus_message_dump(m, f, BUS_MESSAGE_DUMP_WITH_HEADER);
+}
+
+static int message_pcap(sd_bus_message *m, FILE *f) {
+ return bus_message_pcap_frame(m, arg_snaplen, f);
+}
+
+static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ char **i;
+ uint32_t flags = 0;
+ const char *unique_name;
+ bool is_monitor = false;
+ int r;
+
+ /* upgrade connection; it's not used for anything else after this call */
+ r = sd_bus_message_new_method_call(bus, &message, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus.Monitoring", "BecomeMonitor");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(message, 'a', "s");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ STRV_FOREACH(i, argv+1) {
+ _cleanup_free_ char *m = NULL;
+
+ if (!service_name_is_valid(*i)) {
+ log_error("Invalid service name '%s'", *i);
+ return -EINVAL;
+ }
+
+ m = strjoin("sender='", *i, "'");
+ if (!m)
+ return log_oom();
+
+ r = sd_bus_message_append_basic(message, 's', m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ free(m);
+ m = strjoin("destination='", *i, "'");
+ if (!m)
+ return log_oom();
+
+ r = sd_bus_message_append_basic(message, 's', m);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ STRV_FOREACH(i, arg_matches) {
+ r = sd_bus_message_append_basic(message, 's', *i);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ r = sd_bus_message_close_container(message);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_basic(message, 'u', &flags);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, message, arg_timeout, &error, NULL);
+ if (r < 0) {
+ log_error("%s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_get_unique_name(bus, &unique_name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get unique name: %m");
+
+ log_info("Monitoring bus message stream.");
+
+ for (;;) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+
+ r = sd_bus_process(bus, &m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to process bus: %m");
+
+ if (!is_monitor) {
+ const char *name;
+
+ /* wait until we lose our unique name */
+ if (sd_bus_message_is_signal(m, "org.freedesktop.DBus", "NameLost") <= 0)
+ continue;
+
+ r = sd_bus_message_read(m, "s", &name);
+ if (r < 0)
+ return log_error_errno(r, "Failed to read lost name: %m");
+
+ if (streq(name, unique_name))
+ is_monitor = true;
+
+ continue;
+ }
+
+ if (m) {
+ dump(m, stdout);
+ fflush(stdout);
+
+ if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) {
+ log_info("Connection terminated, exiting.");
+ return 0;
+ }
+
+ continue;
+ }
+
+ if (r > 0)
+ continue;
+
+ r = sd_bus_wait(bus, (uint64_t) -1);
+ if (r < 0)
+ return log_error_errno(r, "Failed to wait for bus: %m");
+ }
+}
+
+static int capture(sd_bus *bus, char *argv[]) {
+ int r;
+
+ if (isatty(fileno(stdout)) > 0) {
+ log_error("Refusing to write message data to console, please redirect output to a file.");
+ return -EINVAL;
+ }
+
+ bus_pcap_header(arg_snaplen, stdout);
+
+ r = monitor(bus, argv, message_pcap);
+ if (r < 0)
+ return r;
+
+ if (ferror(stdout)) {
+ log_error("Couldn't write capture file.");
+ return -EIO;
+ }
+
+ return r;
+}
+
+static int status(sd_bus *bus, char *argv[]) {
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ pid_t pid;
+ int r;
+
+ assert(bus);
+
+ if (strv_length(argv) > 2) {
+ log_error("Expects no or one argument.");
+ return -EINVAL;
+ }
+
+ if (argv[1]) {
+ r = parse_pid(argv[1], &pid);
+ if (r < 0)
+ r = sd_bus_get_name_creds(
+ bus,
+ argv[1],
+ (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
+ &creds);
+ else
+ r = sd_bus_creds_new_from_pid(
+ &creds,
+ pid,
+ _SD_BUS_CREDS_ALL);
+ } else {
+ const char *scope, *address;
+ sd_id128_t bus_id;
+
+ r = sd_bus_get_address(bus, &address);
+ if (r >= 0)
+ printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_normal());
+
+ r = sd_bus_get_scope(bus, &scope);
+ if (r >= 0)
+ printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_normal());
+
+ r = sd_bus_get_bus_id(bus, &bus_id);
+ if (r >= 0)
+ printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_normal());
+
+ r = sd_bus_get_owner_creds(
+ bus,
+ (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
+ &creds);
+ }
+
+ if (r < 0)
+ return log_error_errno(r, "Failed to get credentials: %m");
+
+ bus_creds_dump(creds, NULL, false);
+ return 0;
+}
+
+static int message_append_cmdline(sd_bus_message *m, const char *signature, char ***x) {
+ char **p;
+ int r;
+
+ assert(m);
+ assert(signature);
+ assert(x);
+
+ p = *x;
+
+ for (;;) {
+ const char *v;
+ char t;
+
+ t = *signature;
+ v = *p;
+
+ if (t == 0)
+ break;
+ if (!v) {
+ log_error("Too few parameters for signature.");
+ return -EINVAL;
+ }
+
+ signature++;
+ p++;
+
+ switch (t) {
+
+ case SD_BUS_TYPE_BOOLEAN:
+
+ r = parse_boolean(v);
+ if (r < 0) {
+ log_error("Failed to parse as boolean: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &r);
+ break;
+
+ case SD_BUS_TYPE_BYTE: {
+ uint8_t z;
+
+ r = safe_atou8(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as byte (unsigned 8bit integer): %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_INT16: {
+ int16_t z;
+
+ r = safe_atoi16(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as signed 16bit integer: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_UINT16: {
+ uint16_t z;
+
+ r = safe_atou16(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as unsigned 16bit integer: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_INT32: {
+ int32_t z;
+
+ r = safe_atoi32(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as signed 32bit integer: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_UINT32: {
+ uint32_t z;
+
+ r = safe_atou32(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as unsigned 32bit integer: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_INT64: {
+ int64_t z;
+
+ r = safe_atoi64(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as signed 64bit integer: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_UINT64: {
+ uint64_t z;
+
+ r = safe_atou64(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as unsigned 64bit integer: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+
+ case SD_BUS_TYPE_DOUBLE: {
+ double z;
+
+ r = safe_atod(v, &z);
+ if (r < 0) {
+ log_error("Failed to parse as double precision floating point: %s", v);
+ return r;
+ }
+
+ r = sd_bus_message_append_basic(m, t, &z);
+ break;
+ }
+
+ case SD_BUS_TYPE_STRING:
+ case SD_BUS_TYPE_OBJECT_PATH:
+ case SD_BUS_TYPE_SIGNATURE:
+
+ r = sd_bus_message_append_basic(m, t, v);
+ break;
+
+ case SD_BUS_TYPE_ARRAY: {
+ uint32_t n;
+ size_t k;
+
+ r = safe_atou32(v, &n);
+ if (r < 0) {
+ log_error("Failed to parse number of array entries: %s", v);
+ return r;
+ }
+
+ r = signature_element_length(signature, &k);
+ if (r < 0) {
+ log_error("Invalid array signature.");
+ return r;
+ }
+
+ {
+ unsigned i;
+ char s[k + 1];
+ memcpy(s, signature, k);
+ s[k] = 0;
+
+ r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ for (i = 0; i < n; i++) {
+ r = message_append_cmdline(m, s, &p);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ signature += k;
+
+ r = sd_bus_message_close_container(m);
+ break;
+ }
+
+ case SD_BUS_TYPE_VARIANT:
+ r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, v);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = message_append_cmdline(m, v, &p);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(m);
+ break;
+
+ case SD_BUS_TYPE_STRUCT_BEGIN:
+ case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
+ size_t k;
+
+ signature--;
+ p--;
+
+ r = signature_element_length(signature, &k);
+ if (r < 0) {
+ log_error("Invalid struct/dict entry signature.");
+ return r;
+ }
+
+ {
+ char s[k-1];
+ memcpy(s, signature + 1, k - 2);
+ s[k - 2] = 0;
+
+ r = sd_bus_message_open_container(m, t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = message_append_cmdline(m, s, &p);
+ if (r < 0)
+ return r;
+ }
+
+ signature += k;
+
+ r = sd_bus_message_close_container(m);
+ break;
+ }
+
+ case SD_BUS_TYPE_UNIX_FD:
+ log_error("UNIX file descriptor not supported as type.");
+ return -EINVAL;
+
+ default:
+ log_error("Unknown signature type %c.", t);
+ return -EINVAL;
+ }
+
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ *x = p;
+ return 0;
+}
+
+static int call(sd_bus *bus, char *argv[]) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
+ int r;
+
+ assert(bus);
+
+ if (strv_length(argv) < 5) {
+ log_error("Expects at least four arguments.");
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], argv[3], argv[4]);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_expect_reply(m, arg_expect_reply);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_auto_start(m, arg_auto_start);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_allow_interactive_authorization);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ if (!isempty(argv[5])) {
+ char **p;
+
+ p = argv+6;
+
+ r = message_append_cmdline(m, argv[5], &p);
+ if (r < 0)
+ return r;
+
+ if (*p) {
+ log_error("Too many parameters for signature.");
+ return -EINVAL;
+ }
+ }
+
+ if (!arg_expect_reply) {
+ r = sd_bus_send(bus, m, NULL);
+ if (r < 0) {
+ log_error("Failed to send message.");
+ return r;
+ }
+
+ return 0;
+ }
+
+ r = sd_bus_call(bus, m, arg_timeout, &error, &reply);
+ if (r < 0) {
+ log_error("%s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_is_empty(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (r == 0 && !arg_quiet) {
+
+ if (arg_verbose) {
+ pager_open(arg_no_pager, false);
+
+ r = bus_message_dump(reply, stdout, 0);
+ if (r < 0)
+ return r;
+ } else {
+
+ fputs(sd_bus_message_get_signature(reply, true), stdout);
+ fputc(' ', stdout);
+
+ r = format_cmdline(reply, stdout, false);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ fputc('\n', stdout);
+ }
+ }
+
+ return 0;
+}
+
+static int get_property(sd_bus *bus, char *argv[]) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ unsigned n;
+ char **i;
+ int r;
+
+ assert(bus);
+
+ n = strv_length(argv);
+ if (n < 5) {
+ log_error("Expects at least four arguments.");
+ return -EINVAL;
+ }
+
+ STRV_FOREACH(i, argv + 4) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ const char *contents = NULL;
+ char type;
+
+ r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Get", &error, &reply, "ss", argv[3], *i);
+ if (r < 0) {
+ log_error("%s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_peek_type(reply, &type, &contents);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_enter_container(reply, 'v', contents);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (arg_verbose) {
+ pager_open(arg_no_pager, false);
+
+ r = bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_SUBTREE_ONLY);
+ if (r < 0)
+ return r;
+ } else {
+ fputs(contents, stdout);
+ fputc(' ', stdout);
+
+ r = format_cmdline(reply, stdout, false);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ fputc('\n', stdout);
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+ }
+
+ return 0;
+}
+
+static int set_property(sd_bus *bus, char *argv[]) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ unsigned n;
+ char **p;
+ int r;
+
+ assert(bus);
+
+ n = strv_length(argv);
+ if (n < 6) {
+ log_error("Expects at least five arguments.");
+ return -EINVAL;
+ }
+
+ r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Set");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ss", argv[3], argv[4]);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_open_container(m, 'v', argv[5]);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ p = argv+6;
+ r = message_append_cmdline(m, argv[5], &p);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ if (*p) {
+ log_error("Too many parameters for signature.");
+ return -EINVAL;
+ }
+
+ r = sd_bus_call(bus, m, arg_timeout, &error, NULL);
+ if (r < 0) {
+ log_error("%s", bus_error_message(&error, r));
+ return r;
+ }
+
+ return 0;
+}
+
+static int help(void) {
+ printf("%s [OPTIONS...] {COMMAND} ...\n\n"
+ "Introspect the bus.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " --no-pager Do not pipe output into a pager\n"
+ " --no-legend Do not show the headers and footers\n"
+ " --system Connect to system bus\n"
+ " --user Connect to user bus\n"
+ " -H --host=[USER@]HOST Operate on remote host\n"
+ " -M --machine=CONTAINER Operate on local container\n"
+ " --address=ADDRESS Connect to bus specified by address\n"
+ " --show-machine Show machine ID column in list\n"
+ " --unique Only show unique names\n"
+ " --acquired Only show acquired names\n"
+ " --activatable Only show activatable names\n"
+ " --match=MATCH Only show matching messages\n"
+ " --size=SIZE Maximum length of captured packet\n"
+ " --list Don't show tree, but simple object path list\n"
+ " --quiet Don't show method call reply\n"
+ " --verbose Show result values in long format\n"
+ " --expect-reply=BOOL Expect a method call reply\n"
+ " --auto-start=BOOL Auto-start destination service\n"
+ " --allow-interactive-authorization=BOOL\n"
+ " Allow interactive authorization for operation\n"
+ " --timeout=SECS Maximum time to wait for method call completion\n"
+ " --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n"
+ "Commands:\n"
+ " list List bus names\n"
+ " status [SERVICE] Show bus service, process or bus owner credentials\n"
+ " monitor [SERVICE...] Show bus traffic\n"
+ " capture [SERVICE...] Capture bus traffic as pcap\n"
+ " tree [SERVICE...] Show object tree of service\n"
+ " introspect SERVICE OBJECT [INTERFACE]\n"
+ " call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]\n"
+ " Call a method\n"
+ " get-property SERVICE OBJECT INTERFACE PROPERTY...\n"
+ " Get property value\n"
+ " set-property SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT...\n"
+ " Set property value\n"
+ " help Show this help\n"
+ , program_invocation_short_name);
+
+ return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+ enum {
+ ARG_VERSION = 0x100,
+ ARG_NO_PAGER,
+ ARG_NO_LEGEND,
+ ARG_SYSTEM,
+ ARG_USER,
+ ARG_ADDRESS,
+ ARG_MATCH,
+ ARG_SHOW_MACHINE,
+ ARG_UNIQUE,
+ ARG_ACQUIRED,
+ ARG_ACTIVATABLE,
+ ARG_SIZE,
+ ARG_LIST,
+ ARG_VERBOSE,
+ ARG_EXPECT_REPLY,
+ ARG_AUTO_START,
+ ARG_ALLOW_INTERACTIVE_AUTHORIZATION,
+ ARG_TIMEOUT,
+ ARG_AUGMENT_CREDS,
+ };
+
+ static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
+ { "system", no_argument, NULL, ARG_SYSTEM },
+ { "user", no_argument, NULL, ARG_USER },
+ { "address", required_argument, NULL, ARG_ADDRESS },
+ { "show-machine", no_argument, NULL, ARG_SHOW_MACHINE },
+ { "unique", no_argument, NULL, ARG_UNIQUE },
+ { "acquired", no_argument, NULL, ARG_ACQUIRED },
+ { "activatable", no_argument, NULL, ARG_ACTIVATABLE },
+ { "match", required_argument, NULL, ARG_MATCH },
+ { "host", required_argument, NULL, 'H' },
+ { "machine", required_argument, NULL, 'M' },
+ { "size", required_argument, NULL, ARG_SIZE },
+ { "list", no_argument, NULL, ARG_LIST },
+ { "quiet", no_argument, NULL, 'q' },
+ { "verbose", no_argument, NULL, ARG_VERBOSE },
+ { "expect-reply", required_argument, NULL, ARG_EXPECT_REPLY },
+ { "auto-start", required_argument, NULL, ARG_AUTO_START },
+ { "allow-interactive-authorization", required_argument, NULL, ARG_ALLOW_INTERACTIVE_AUTHORIZATION },
+ { "timeout", required_argument, NULL, ARG_TIMEOUT },
+ { "augment-creds",required_argument, NULL, ARG_AUGMENT_CREDS},
+ {},
+ };
+
+ int c, r;
+
+ assert(argc >= 0);
+ assert(argv);
+
+ while ((c = getopt_long(argc, argv, "hH:M:q", options, NULL)) >= 0)
+
+ switch (c) {
+
+ case 'h':
+ return help();
+
+ case ARG_VERSION:
+ return version();
+
+ case ARG_NO_PAGER:
+ arg_no_pager = true;
+ break;
+
+ case ARG_NO_LEGEND:
+ arg_legend = false;
+ break;
+
+ case ARG_USER:
+ arg_user = true;
+ break;
+
+ case ARG_SYSTEM:
+ arg_user = false;
+ break;
+
+ case ARG_ADDRESS:
+ arg_address = optarg;
+ break;
+
+ case ARG_SHOW_MACHINE:
+ arg_show_machine = true;
+ break;
+
+ case ARG_UNIQUE:
+ arg_unique = true;
+ break;
+
+ case ARG_ACQUIRED:
+ arg_acquired = true;
+ break;
+
+ case ARG_ACTIVATABLE:
+ arg_activatable = true;
+ break;
+
+ case ARG_MATCH:
+ if (strv_extend(&arg_matches, optarg) < 0)
+ return log_oom();
+ break;
+
+ case ARG_SIZE: {
+ uint64_t sz;
+
+ r = parse_size(optarg, 1024, &sz);
+ if (r < 0) {
+ log_error("Failed to parse size: %s", optarg);
+ return r;
+ }
+
+ if ((uint64_t) (size_t) sz != sz) {
+ log_error("Size out of range.");
+ return -E2BIG;
+ }
+
+ arg_snaplen = (size_t) sz;
+ break;
+ }
+
+ case ARG_LIST:
+ arg_list = true;
+ break;
+
+ case 'H':
+ arg_transport = BUS_TRANSPORT_REMOTE;
+ arg_host = optarg;
+ break;
+
+ case 'M':
+ arg_transport = BUS_TRANSPORT_MACHINE;
+ arg_host = optarg;
+ break;
+
+ case 'q':
+ arg_quiet = true;
+ break;
+
+ case ARG_VERBOSE:
+ arg_verbose = true;
+ break;
+
+ case ARG_EXPECT_REPLY:
+ r = parse_boolean(optarg);
+ if (r < 0) {
+ log_error("Failed to parse --expect-reply= parameter.");
+ return r;
+ }
+
+ arg_expect_reply = !!r;
+ break;
+
+
+ case ARG_AUTO_START:
+ r = parse_boolean(optarg);
+ if (r < 0) {
+ log_error("Failed to parse --auto-start= parameter.");
+ return r;
+ }
+
+ arg_auto_start = !!r;
+ break;
+
+
+ case ARG_ALLOW_INTERACTIVE_AUTHORIZATION:
+ r = parse_boolean(optarg);
+ if (r < 0) {
+ log_error("Failed to parse --allow-interactive-authorization= parameter.");
+ return r;
+ }
+
+ arg_allow_interactive_authorization = !!r;
+ break;
+
+ case ARG_TIMEOUT:
+ r = parse_sec(optarg, &arg_timeout);
+ if (r < 0) {
+ log_error("Failed to parse --timeout= parameter.");
+ return r;
+ }
+
+ break;
+
+ case ARG_AUGMENT_CREDS:
+ r = parse_boolean(optarg);
+ if (r < 0) {
+ log_error("Failed to parse --augment-creds= parameter.");
+ return r;
+ }
+
+ arg_augment_creds = !!r;
+ break;
+
+ case '?':
+ return -EINVAL;
+
+ default:
+ assert_not_reached("Unhandled option");
+ }
+
+ return 1;
+}
+
+static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
+ assert(bus);
+
+ if (optind >= argc ||
+ streq(argv[optind], "list"))
+ return list_bus_names(bus, argv + optind);
+
+ if (streq(argv[optind], "monitor"))
+ return monitor(bus, argv + optind, message_dump);
+
+ if (streq(argv[optind], "capture"))
+ return capture(bus, argv + optind);
+
+ if (streq(argv[optind], "status"))
+ return status(bus, argv + optind);
+
+ if (streq(argv[optind], "tree"))
+ return tree(bus, argv + optind);
+
+ if (streq(argv[optind], "introspect"))
+ return introspect(bus, argv + optind);
+
+ if (streq(argv[optind], "call"))
+ return call(bus, argv + optind);
+
+ if (streq(argv[optind], "get-property"))
+ return get_property(bus, argv + optind);
+
+ if (streq(argv[optind], "set-property"))
+ return set_property(bus, argv + optind);
+
+ if (streq(argv[optind], "help"))
+ return help();
+
+ log_error("Unknown command '%s'", argv[optind]);
+ return -EINVAL;
+}
+
+int main(int argc, char *argv[]) {
+ sd_bus *bus = NULL;
+ int r;
+
+ log_parse_environment();
+ log_open();
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto finish;
+
+ r = sd_bus_new(&bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to allocate bus: %m");
+ goto finish;
+ }
+
+ if (STRPTR_IN_SET(argv[optind], "monitor", "capture")) {
+
+ r = sd_bus_set_monitor(bus, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set monitor mode: %m");
+ goto finish;
+ }
+
+ r = sd_bus_negotiate_creds(bus, true, _SD_BUS_CREDS_ALL);
+ if (r < 0) {
+ log_error_errno(r, "Failed to enable credentials: %m");
+ goto finish;
+ }
+
+ r = sd_bus_negotiate_timestamp(bus, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to enable timestamps: %m");
+ goto finish;
+ }
+
+ r = sd_bus_negotiate_fds(bus, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to enable fds: %m");
+ goto finish;
+ }
+ }
+
+ r = sd_bus_set_bus_client(bus, true);
+ if (r < 0) {
+ log_error_errno(r, "Failed to set bus client: %m");
+ goto finish;
+ }
+
+ if (arg_address)
+ r = sd_bus_set_address(bus, arg_address);
+ else {
+ switch (arg_transport) {
+
+ case BUS_TRANSPORT_LOCAL:
+ if (arg_user) {
+ bus->is_user = true;
+ r = bus_set_address_user(bus);
+ } else {
+ bus->is_system = true;
+ r = bus_set_address_system(bus);
+ }
+ break;
+
+ case BUS_TRANSPORT_REMOTE:
+ r = bus_set_address_system_remote(bus, arg_host);
+ break;
+
+ case BUS_TRANSPORT_MACHINE:
+ r = bus_set_address_system_machine(bus, arg_host);
+ break;
+
+ default:
+ assert_not_reached("Hmm, unknown transport type.");
+ }
+ }
+ if (r < 0) {
+ log_error_errno(r, "Failed to set address: %m");
+ goto finish;
+ }
+
+ r = sd_bus_start(bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to connect to bus: %m");
+ goto finish;
+ }
+
+ r = busctl_main(bus, argc, argv);
+
+finish:
+ sd_bus_flush_close_unref(bus);
+ pager_close();
+
+ strv_free(arg_matches);
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
static char* arg_machine = NULL;
static char* arg_root = NULL;
static bool arg_recursive = true;
+static bool arg_recursive_unset = false;
static enum {
COUNT_PIDS,
if (!is_valid)
return "-";
if (arg_raw) {
- snprintf(buf, l, "%jd", t);
+ snprintf(buf, l, "%" PRIu64, t);
return buf;
}
return format_bytes(buf, l, t);
{}
};
- bool recursive_unset = false;
int c, r;
assert(argc >= 1);
}
arg_recursive = r;
- recursive_unset = r == 0;
+ arg_recursive_unset = r == 0;
break;
case 'M':
return -EINVAL;
}
- if (recursive_unset && arg_count == COUNT_PIDS) {
- log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
- return -EINVAL;
- }
-
return 1;
}
log_parse_environment();
log_open();
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ goto finish;
+
r = cg_mask_supported(&mask);
if (r < 0) {
log_error_errno(r, "Failed to determine supported controllers: %m");
arg_count = (mask & CGROUP_MASK_PIDS) ? COUNT_PIDS : COUNT_USERSPACE_PROCESSES;
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
+ if (arg_recursive_unset && arg_count == COUNT_PIDS) {
+ log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
+ return -EINVAL;
+ }
r = show_cgroup_get_path_and_warn(arg_machine, arg_root, &root);
if (r < 0) {
#include <libaudit.h>
#include <stdbool.h>
+#include "capability-util.h"
#include "fd-util.h"
#include "log.h"
#include "util.h"
int get_audit_fd(void) {
if (!initialized) {
+ if (have_effective_cap(CAP_AUDIT_WRITE) == 0) {
+ audit_fd = -EPERM;
+ initialized = true;
+
+ return audit_fd;
+ }
+
audit_fd = audit_open();
if (audit_fd < 0) {
init_autofs_dev_ioctl(¶m);
param.ioctlfd = ioctl_fd;
- /* Convert to seconds, rounding up. */
- param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
+ if (usec == USEC_INFINITY)
+ param.timeout.timeout = 0;
+ else
+ /* Convert to seconds, rounding up. */
+ param.timeout.timeout = (usec + USEC_PER_SEC - 1) / USEC_PER_SEC;
if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
return -errno;
while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
int k;
- /* Autofs fun fact II:
+ /* Autofs fun fact:
*
- * if you pass a positive status code here, the kernel will
- * freeze! Yay! */
+ * if you pass a positive status code here, kernels
+ * prior to 4.12 will freeze! Yay! */
k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
ioctl_fd,
if (r < 0)
goto fail;
- /* Autofs fun fact:
- *
- * Unless we close the ioctl fd here, for some weird reason
- * the direct mount will not receive events from the
- * kernel. */
-
r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
if (r < 0)
goto fail;
(void) sd_event_source_set_enabled(a->expire_event_source, SD_EVENT_OFF);
}
-static void automount_enter_runnning(Automount *a) {
+static void automount_enter_running(Automount *a) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ Unit *trigger;
struct stat st;
int r;
goto fail;
}
- if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
+ /* The mount unit may have been explicitly started before we got the
+ * autofs request. Ack it to unblock anything waiting on the mount point. */
+ if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) {
log_unit_info(UNIT(a), "Automount point already active?");
- else {
- Unit *trigger;
+ automount_send_ready(a, a->tokens, 0);
+ return;
+ }
- trigger = UNIT_TRIGGER(UNIT(a));
- if (!trigger) {
- log_unit_error(UNIT(a), "Unit to trigger vanished.");
- goto fail;
- }
+ trigger = UNIT_TRIGGER(UNIT(a));
+ if (!trigger) {
+ log_unit_error(UNIT(a), "Unit to trigger vanished.");
+ goto fail;
+ }
- r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL);
- if (r < 0) {
- log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r));
- goto fail;
- }
+ r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL);
+ if (r < 0) {
+ log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r));
+ goto fail;
}
automount_set_state(a, AUTOMOUNT_RUNNING);
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
union autofs_v5_packet_union packet;
Automount *a = AUTOMOUNT(userdata);
- struct stat st;
Unit *trigger;
int r;
goto fail;
}
- automount_enter_runnning(a);
+ automount_enter_running(a);
break;
case autofs_ptype_expire_direct:
goto fail;
}
- /* Before we do anything, let's see if somebody is playing games with us? */
- if (lstat(a->where, &st) < 0) {
- log_unit_warning_errno(UNIT(a), errno, "Failed to stat automount point: %m");
- goto fail;
- }
-
- if (!S_ISDIR(st.st_mode) || st.st_dev == a->dev_id) {
- log_unit_info(UNIT(a), "Automount point already unmounted?");
- automount_send_ready(a, a->expire_tokens, 0);
- break;
- }
-
trigger = UNIT_TRIGGER(UNIT(a));
if (!trigger) {
log_unit_error(UNIT(a), "Unit to trigger vanished.");
struct kdbus_item *d;
struct kdbus_msg *k;
size_t start, ps, sz, delta;
- void *p = NULL;
+ void *p = MAP_FAILED;
pid_t pid = 0;
int r;
r = 0;
finish:
- if (p)
+ if (p != MAP_FAILED)
(void) munmap(p, sz);
cmd_free.offset = cmd_recv.msg.offset;
return 0;
fail:
- log_warning_errno(errno, "Failed to read /proc/devices: %m");
- return -errno;
+ return log_warning_errno(errno, "Failed to read /proc/devices: %m");
}
static bool cgroup_context_has_cpu_weight(CGroupContext *c) {
if (mode != UNIT_CHECK) {
c->cpu_quota_per_sec_usec = u64;
unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
- unit_write_drop_in_private_format(u, mode, "CPUQuota", "CPUQuota=%0.f%%", (double) (c->cpu_quota_per_sec_usec / 10000));
+ if (c->cpu_quota_per_sec_usec == USEC_INFINITY)
+ unit_write_drop_in_private_format(u, mode, "CPUQuota",
+ "CPUQuota=");
+ else
+ /* config_parse_cpu_quota() requires an integer, so
+ * truncating division is used on purpose here. */
+ unit_write_drop_in_private_format(u, mode, "CPUQuota",
+ "CPUQuota=%0.f%%",
+ (double) (c->cpu_quota_per_sec_usec / 10000));
}
return 1;
#endif
#include "strv.h"
#include "syslog-util.h"
+#include "unit-printf.h"
#include "user-util.h"
#include "utf8.h"
ExecContext *c = userdata;
- int32_t n;
assert(bus);
assert(reply);
assert(c);
- if (c->ioprio_set)
- n = c->ioprio;
- else {
- n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
- if (n < 0)
- n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
- }
+ return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
+}
- return sd_bus_message_append(reply, "i", n);
+static int property_get_ioprio_class(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+
+ ExecContext *c = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
+}
+
+static int property_get_ioprio_priority(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+
+ ExecContext *c = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
}
static int property_get_cpu_sched_policy(
c->bind_mounts[i].source,
c->bind_mounts[i].destination,
c->bind_mounts[i].ignore_enoent,
- c->bind_mounts[i].recursive ? MS_REC : 0);
+ c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0);
if (r < 0)
return r;
}
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
+
+ /* Obsolete/redundant properties: */
+ SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+
SD_BUS_VTABLE_END
};
return 1;
} else if (streq(name, "SyslogLevel")) {
- int level;
+ int32_t level;
r = sd_bus_message_read(message, "i", &level);
if (r < 0)
return 1;
} else if (streq(name, "SyslogFacility")) {
- int facility;
+ int32_t facility;
r = sd_bus_message_read(message, "i", &facility);
if (r < 0)
return 1;
} else if (streq(name, "Nice")) {
- int n;
+ int32_t n;
r = sd_bus_message_read(message, "i", &n);
if (r < 0)
return 1;
+ } else if (streq(name, "IOSchedulingClass")) {
+ int32_t q;
+
+ r = sd_bus_message_read(message, "i", &q);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_class_is_valid(q))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
+
+ if (mode != UNIT_CHECK) {
+ _cleanup_free_ char *s = NULL;
+
+ r = ioprio_class_to_string_alloc(q, &s);
+ if (r < 0)
+ return r;
+
+ c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
+ c->ioprio_set = true;
+
+ unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
+ }
+
+ return 1;
+
+ } else if (streq(name, "IOSchedulingPriority")) {
+ int32_t p;
+
+ r = sd_bus_message_read(message, "i", &p);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_priority_is_valid(p))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
+
+ if (mode != UNIT_CHECK) {
+ c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
+ c->ioprio_set = true;
+
+ unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
+ }
+
+ return 1;
+
} else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
const char *s;
} else if (streq(name, "Environment")) {
- _cleanup_strv_free_ char **l = NULL;
+ _cleanup_strv_free_ char **l = NULL, **q = NULL;
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
if (!strv_env_is_valid(l))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *joined = NULL;
- char **e;
+ r = unit_full_printf_strv(u, l, &q);
+ if (r < 0)
+ return r;
- if (strv_length(l) == 0) {
+ if (mode != UNIT_CHECK) {
+ if (strv_length(q) == 0) {
c->environment = strv_free(c->environment);
unit_write_drop_in_private_format(u, mode, name, "Environment=");
} else {
- e = strv_env_merge(2, c->environment, l);
+ _cleanup_free_ char *joined = NULL;
+ char **e;
+
+ e = strv_env_merge(2, c->environment, q);
if (!e)
return -ENOMEM;
strv_free(c->environment);
c->environment = e;
- joined = strv_join_quoted(c->environment);
+ /* We write just the new settings out to file, with unresolved specifiers */
+ joined = strv_join_quoted(q);
if (!joined)
return -ENOMEM;
return 1;
+ } else if (streq(name, "FileDescriptorStoreMax")) {
+ uint32_t u;
+
+ r = sd_bus_message_read(message, "u", &u);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ s->n_fd_store_max = (unsigned) u;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "FileDescriptorStoreMax=%" PRIu32, u);
+ }
+
+ return 1;
+
+ } else if (streq(name, "NotifyAccess")) {
+ const char *t;
+ NotifyAccess k;
+
+ r = sd_bus_message_read(message, "s", &t);
+ if (r < 0)
+ return r;
+
+ k = notify_access_from_string(t);
+ if (k < 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t);
+
+ if (mode != UNIT_CHECK) {
+ s->notify_access = k;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access));
+ }
+
+ return 1;
+
} else if (streq(name, "ExecStart")) {
unsigned n = 0;
sd_bus_error *error) {
Timer *t = userdata;
- usec_t x;
assert(bus);
assert(reply);
assert(t);
- if (t->next_elapse_monotonic_or_boottime <= 0)
- x = 0;
- else if (t->wake_system) {
- usec_t a, b;
-
- a = now(CLOCK_MONOTONIC);
- b = now(clock_boottime_or_monotonic());
-
- if (t->next_elapse_monotonic_or_boottime + a > b)
- x = t->next_elapse_monotonic_or_boottime + a - b;
- else
- x = 0;
- } else
- x = t->next_elapse_monotonic_or_boottime;
-
- return sd_bus_message_append(reply, "t", x);
+ return sd_bus_message_append(reply, "t",
+ (uint64_t) usec_shift_clock(t->next_elapse_monotonic_or_boottime,
+ TIMER_MONOTONIC_CLOCK(t), CLOCK_MONOTONIC));
}
const sd_bus_vtable bus_timer_vtable[] = {
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
/* If it is, determine its current owner */
r = sd_bus_get_name_creds(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
if (r < 0) {
- log_error_errno(r, "Failed to get bus name owner %s: %m", name);
+ log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get bus name owner %s: %m", name);
continue;
}
r = sd_bus_creds_get_unique_name(creds, &unique);
if (r < 0) {
- log_error_errno(r, "Failed to get unique name for %s: %m", name);
+ log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get unique name for %s: %m", name);
continue;
}
* indefinitely for plugged in devices, something which cannot
* happen for the other units since their operations time out
* anyway. */
- u->job_timeout = u->manager->default_timeout_start_usec;
+ u->job_running_timeout = u->manager->default_timeout_start_usec;
u->ignore_on_isolate = true;
}
* now referenced by the kernel, then we assume the
* kernel knows it now, and udev might soon too. */
device_set_state(d, DEVICE_TENTATIVE);
- else
+ else {
/* If nobody sees the device, or if the device was
* previously seen by udev and now is only referenced
* from the kernel, then we consider the device is
* gone, the kernel just hasn't noticed it yet. */
+
device_set_state(d, DEVICE_DEAD);
+ device_unset_sysfs(d);
+ }
+
}
static int device_update_found_by_sysfs(Manager *m, const char *sysfs, bool add, DeviceFound found, bool now) {
return 0;
}
-static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
- unsigned i;
+static int flags_fds(const int fds[], unsigned n_storage_fds, unsigned n_socket_fds, bool nonblock) {
+ unsigned i, n_fds;
int r;
+ n_fds = n_storage_fds + n_socket_fds;
if (n_fds <= 0)
return 0;
assert(fds);
- /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
+ /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags.
+ * O_NONBLOCK only applies to socket activation though. */
for (i = 0; i < n_fds; i++) {
- r = fd_nonblock(fds[i], nonblock);
- if (r < 0)
- return r;
+ if (i < n_socket_fds) {
+ r = fd_nonblock(fds[i], nonblock);
+ if (r < 0)
+ return r;
+ }
/* We unconditionally drop FD_CLOEXEC from the fds,
* since after all we want to pass these fds to our
context->protect_control_groups)
return true;
- if (context->mount_apivfs)
+ if (context->mount_apivfs && (context->root_image || context->root_directory))
return true;
return false;
char **argv,
int socket_fd,
int named_iofds[3],
- int *fds, unsigned n_fds,
+ int *fds,
+ unsigned n_storage_fds,
+ unsigned n_socket_fds,
char **files_env,
int user_lookup_fd,
int *exit_status,
uid_t uid = UID_INVALID;
gid_t gid = GID_INVALID;
int i, r, ngids = 0;
+ unsigned n_fds;
assert(unit);
assert(command);
log_forget_fds();
+ n_fds = n_storage_fds + n_socket_fds;
r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, fds, n_fds);
if (r < 0) {
*exit_status = EXIT_FDS;
if (r >= 0)
r = shift_fds(fds, n_fds);
if (r >= 0)
- r = flags_fds(fds, n_fds, context->non_blocking);
+ r = flags_fds(fds, n_storage_fds, n_socket_fds, context->non_blocking);
if (r < 0) {
*exit_status = EXIT_FDS;
return r;
if (line) {
log_open();
log_struct(LOG_DEBUG,
- LOG_UNIT_ID(unit),
"EXECUTABLE=%s", command->path,
LOG_UNIT_MESSAGE(unit, "Executing: %s", line),
+ LOG_UNIT_ID(unit),
NULL);
log_close();
}
pid_t *ret) {
_cleanup_strv_free_ char **files_env = NULL;
- int *fds = NULL; unsigned n_fds = 0;
+ int *fds = NULL;
+ unsigned n_storage_fds = 0, n_socket_fds = 0;
_cleanup_free_ char *line = NULL;
int socket_fd, r;
int named_iofds[3] = { -1, -1, -1 };
assert(context);
assert(ret);
assert(params);
- assert(params->fds || params->n_fds <= 0);
+ assert(params->fds || (params->n_storage_fds + params->n_socket_fds <= 0));
if (context->std_input == EXEC_INPUT_SOCKET ||
context->std_output == EXEC_OUTPUT_SOCKET ||
context->std_error == EXEC_OUTPUT_SOCKET) {
- if (params->n_fds != 1) {
+ if (params->n_socket_fds > 1) {
log_unit_error(unit, "Got more than one socket.");
return -EINVAL;
}
+ if (params->n_socket_fds == 0) {
+ log_unit_error(unit, "Got no socket.");
+ return -EINVAL;
+ }
+
socket_fd = params->fds[0];
} else {
socket_fd = -1;
fds = params->fds;
- n_fds = params->n_fds;
+ n_storage_fds = params->n_storage_fds;
+ n_socket_fds = params->n_socket_fds;
}
r = exec_context_named_iofds(unit, context, params, named_iofds);
return log_oom();
log_struct(LOG_DEBUG,
- LOG_UNIT_ID(unit),
LOG_UNIT_MESSAGE(unit, "About to execute: %s", line),
"EXECUTABLE=%s", command->path,
+ LOG_UNIT_ID(unit),
NULL);
pid = fork();
if (pid < 0)
argv,
socket_fd,
named_iofds,
- fds, n_fds,
+ fds,
+ n_storage_fds,
+ n_socket_fds,
files_env,
unit->manager->user_lookup_fds[1],
&exit_status,
error_message),
"EXECUTABLE=%s", command->path,
NULL);
+ else if (r == -ENOENT && command->ignore)
+ log_struct_errno(LOG_INFO, r,
+ "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
+ LOG_UNIT_ID(unit),
+ LOG_UNIT_MESSAGE(unit, "Skipped spawning %s: %m",
+ command->path),
+ "EXECUTABLE=%s", command->path,
+ NULL);
else
log_struct_errno(LOG_ERR, r,
"MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
int exec_context_named_iofds(Unit *unit, const ExecContext *c, const ExecParameters *p, int named_iofds[3]) {
unsigned i, targets;
const char* stdio_fdname[3];
+ unsigned n_fds;
assert(c);
assert(p);
for (i = 0; i < 3; i++)
stdio_fdname[i] = exec_context_fdname(c, i);
- for (i = 0; i < p->n_fds && targets > 0; i++)
+ n_fds = p->n_storage_fds + p->n_socket_fds;
+
+ for (i = 0; i < n_fds && targets > 0; i++)
if (named_iofds[STDIN_FILENO] < 0 &&
c->std_input == EXEC_INPUT_NAMED_FD &&
stdio_fdname[STDIN_FILENO] &&
STRV_FOREACH(i, c->environment_files) {
char *fn;
int k;
+ unsigned n;
bool ignore = false;
char **p;
_cleanup_globfree_ glob_t pglob = {};
- int count, n;
fn = *i;
}
/* Filename supports globbing, take all matching files */
- errno = 0;
- if (glob(fn, 0, NULL, &pglob) != 0) {
+ k = safe_glob(fn, 0, &pglob);
+ if (k < 0) {
if (ignore)
continue;
strv_free(r);
- return errno > 0 ? -errno : -EINVAL;
+ return k;
}
- count = pglob.gl_pathc;
- if (count == 0) {
- if (ignore)
- continue;
- strv_free(r);
- return -EINVAL;
- }
- for (n = 0; n < count; n++) {
+ /* When we don't match anything, -ENOENT should be returned */
+ assert(pglob.gl_pathc > 0);
+
+ for (n = 0; n < pglob.gl_pathc; n++) {
k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
if (k < 0) {
if (ignore)
return false;
}
+int exec_context_get_effective_ioprio(ExecContext *c) {
+ int p;
+
+ assert(c);
+
+ if (c->ioprio_set)
+ return c->ioprio;
+
+ p = ioprio_get(IOPRIO_WHO_PROCESS, 0);
+ if (p < 0)
+ return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
+
+ return p;
+}
+
void exec_status_start(ExecStatus *s, pid_t pid) {
assert(s);
int *fds;
char **fd_names;
- unsigned n_fds;
+ unsigned n_storage_fds;
+ unsigned n_socket_fds;
ExecFlags flags;
bool selinux_context_net:1;
bool exec_context_may_touch_console(ExecContext *c);
bool exec_context_maintains_privileges(ExecContext *c);
+int exec_context_get_effective_ioprio(ExecContext *c);
+
void exec_status_start(ExecStatus *s, pid_t pid);
void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status);
void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
return 0;
}
+ if (access(IMA_POLICY_PATH, F_OK) < 0) {
+ log_debug("No IMA custom policy file "IMA_POLICY_PATH", ignoring.");
+ return 0;
+ }
+
imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC);
if (imafd < 0) {
log_error_errno(errno, "Failed to open the IMA kernel interface "IMA_SECFS_POLICY", ignoring: %m");
/* fall back to copying the policy line-by-line */
input = fopen(IMA_POLICY_PATH, "re");
if (!input) {
- log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
- "Failed to open the IMA custom policy file "IMA_POLICY_PATH", ignoring: %m");
+ log_warning_errno(errno, "Failed to open the IMA custom policy file "IMA_POLICY_PATH", ignoring: %m");
return 0;
}
if (!job_is_runnable(j))
return -EAGAIN;
+ job_start_timer(j, true);
job_set_state(j, JOB_RUNNING);
job_add_to_dbus_queue(j);
return NULL;
}
-static void job_print_status_message(Unit *u, JobType t, JobResult result) {
- static const struct {
- const char *color, *word;
- } statuses[_JOB_RESULT_MAX] = {
- [JOB_DONE] = { ANSI_GREEN, " OK " },
- [JOB_TIMEOUT] = { ANSI_HIGHLIGHT_RED, " TIME " },
- [JOB_FAILED] = { ANSI_HIGHLIGHT_RED, "FAILED" },
- [JOB_DEPENDENCY] = { ANSI_HIGHLIGHT_YELLOW, "DEPEND" },
- [JOB_SKIPPED] = { ANSI_HIGHLIGHT, " INFO " },
- [JOB_ASSERT] = { ANSI_HIGHLIGHT_YELLOW, "ASSERT" },
- [JOB_UNSUPPORTED] = { ANSI_HIGHLIGHT_YELLOW, "UNSUPP" },
- [JOB_COLLECTED] = { ANSI_HIGHLIGHT, " INFO " },
- };
+static const struct {
+ const char *color, *word;
+} job_print_status_messages [_JOB_RESULT_MAX] = {
+ [JOB_DONE] = { ANSI_GREEN, " OK " },
+ [JOB_TIMEOUT] = { ANSI_HIGHLIGHT_RED, " TIME " },
+ [JOB_FAILED] = { ANSI_HIGHLIGHT_RED, "FAILED" },
+ [JOB_DEPENDENCY] = { ANSI_HIGHLIGHT_YELLOW, "DEPEND" },
+ [JOB_SKIPPED] = { ANSI_HIGHLIGHT, " INFO " },
+ [JOB_ASSERT] = { ANSI_HIGHLIGHT_YELLOW, "ASSERT" },
+ [JOB_UNSUPPORTED] = { ANSI_HIGHLIGHT_YELLOW, "UNSUPP" },
+ /* JOB_COLLECTED */
+};
+static void job_print_status_message(Unit *u, JobType t, JobResult result) {
const char *format;
const char *status;
if (t == JOB_RELOAD)
return;
+ if (!job_print_status_messages[result].word)
+ return;
+
format = job_get_status_message_format(u, t, result);
if (!format)
return;
if (log_get_show_color())
- status = strjoina(statuses[result].color, statuses[result].word, ANSI_NORMAL);
+ status = strjoina(job_print_status_messages[result].color,
+ job_print_status_messages[result].word,
+ ANSI_NORMAL);
else
- status = statuses[result].word;
+ status = job_print_status_messages[result].word;
if (result != JOB_DONE)
manager_flip_auto_status(u->manager, true);
if (t == JOB_START && result == JOB_FAILED) {
_cleanup_free_ char *quoted;
- quoted = shell_maybe_quote(u->id);
+ quoted = shell_maybe_quote(u->id, ESCAPE_BACKSLASH);
manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, "See 'systemctl status %s' for details.", strna(quoted));
}
}
assert(t >= 0);
assert(t < _JOB_TYPE_MAX);
- /* Skip this if it goes to the console. since we already print
- * to the console anyway... */
-
- if (log_on_console())
+ /* Skip printing if output goes to the console, and job_print_status_message()
+ will actually print something to the console. */
+ if (log_on_console() && job_print_status_messages[result].word)
return;
format = job_get_status_message_format(u, t, result);
default:
log_struct(job_result_log_level[result],
- LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
+ LOG_UNIT_ID(u),
NULL);
return;
}
log_struct(job_result_log_level[result],
- mid,
- LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
"RESULT=%s", job_result_to_string(result),
+ LOG_UNIT_ID(u),
+ mid,
NULL);
}
return 0;
}
-int job_start_timer(Job *j) {
+int job_start_timer(Job *j, bool job_running) {
int r;
+ usec_t timeout_time, old_timeout_time;
- if (j->timer_event_source)
- return 0;
+ if (job_running) {
+ j->begin_running_usec = now(CLOCK_MONOTONIC);
+
+ if (j->unit->job_running_timeout == USEC_INFINITY)
+ return 0;
- j->begin_usec = now(CLOCK_MONOTONIC);
+ timeout_time = usec_add(j->begin_running_usec, j->unit->job_running_timeout);
- if (j->unit->job_timeout == USEC_INFINITY)
- return 0;
+ if (j->timer_event_source) {
+ /* Update only if JobRunningTimeoutSec= results in earlier timeout */
+ r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time);
+ if (r < 0)
+ return r;
+
+ if (old_timeout_time <= timeout_time)
+ return 0;
+
+ return sd_event_source_set_time(j->timer_event_source, timeout_time);
+ }
+ } else {
+ if (j->timer_event_source)
+ return 0;
+
+ j->begin_usec = now(CLOCK_MONOTONIC);
+
+ if (j->unit->job_timeout == USEC_INFINITY)
+ return 0;
+
+ timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
+ }
r = sd_event_add_time(
j->manager->event,
&j->timer_event_source,
CLOCK_MONOTONIC,
- usec_add(j->begin_usec, j->unit->job_timeout), 0,
+ timeout_time, 0,
job_dispatch_timer, j);
if (r < 0)
return r;
if (j->begin_usec > 0)
fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
+ if (j->begin_running_usec > 0)
+ fprintf(f, "job-begin-running="USEC_FMT"\n", j->begin_running_usec);
bus_track_serialize(j->bus_track, f, "subscribed");
else
j->begin_usec = ull;
+ } else if (streq(l, "job-begin-running")) {
+ unsigned long long ull;
+
+ if (sscanf(v, "%llu", &ull) != 1)
+ log_debug("Failed to parse job-begin-running value %s", v);
+ else
+ j->begin_running_usec = ull;
+
} else if (streq(l, "subscribed")) {
if (strv_extend(&j->deserialized_clients, v) < 0)
int job_coldplug(Job *j) {
int r;
+ usec_t timeout_time = USEC_INFINITY;
assert(j);
/* Maybe due to new dependencies we don't actually need this job anymore? */
job_add_to_gc_queue(j);
- if (j->begin_usec == 0 || j->unit->job_timeout == USEC_INFINITY)
+ /* Create timer only when job began or began running and the respective timeout is finite.
+ * Follow logic of job_start_timer() if both timeouts are finite */
+ if (j->begin_usec == 0)
+ return 0;
+
+ if (j->unit->job_timeout != USEC_INFINITY)
+ timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
+
+ if (j->begin_running_usec > 0 && j->unit->job_running_timeout != USEC_INFINITY)
+ timeout_time = MIN(timeout_time, usec_add(j->begin_running_usec, j->unit->job_running_timeout));
+
+ if (timeout_time == USEC_INFINITY)
return 0;
j->timer_event_source = sd_event_source_unref(j->timer_event_source);
j->manager->event,
&j->timer_event_source,
CLOCK_MONOTONIC,
- usec_add(j->begin_usec, j->unit->job_timeout), 0,
+ timeout_time, 0,
job_dispatch_timer, j);
if (r < 0)
log_debug_errno(r, "Failed to restart timeout for job: %m");
return true;
}
- /* If we are going down, but something else is orederd After= us, then it needs to wait for us */
- if (IN_SET(j->type, JOB_STOP, JOB_RESTART)) {
-
+ /* If we are going down, but something else is ordered After= us, then it needs to wait for us */
+ if (IN_SET(j->type, JOB_STOP, JOB_RESTART))
SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i) {
if (!other->job)
continue;
return true;
}
- }
/* The logic above is kinda the inverse of the job_is_runnable() logic. Specifically, if the job "we" is
* ordered before the job "other":
sd_event_source *timer_event_source;
usec_t begin_usec;
+ usec_t begin_running_usec;
/*
* This tracks where to send signals, and also which clients
void job_add_to_run_queue(Job *j);
void job_add_to_dbus_queue(Job *j);
-int job_start_timer(Job *j);
+int job_start_timer(Job *j, bool job_running);
int job_run_and_invalidate(Job *j);
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already);
#include "unit-name.h"
#include "unit.h"
-static bool unit_name_compatible(const char *a, const char *b) {
+static int unit_name_compatible(const char *a, const char *b) {
_cleanup_free_ char *prefix = NULL;
int r;
/* the straightforward case: the symlink name matches the target */
if (streq(a, b))
- return true;
+ return 1;
r = unit_name_template(a, &prefix);
- if (r < 0) {
- log_oom();
- return true;
- }
+ if (r == -EINVAL)
+ /* not a template */
+ return 0;
+ if (r < 0)
+ /* oom, or some other failure. Just skip the warning. */
+ return r;
/* an instance name points to a target that is just the template name */
if (streq(prefix, b))
- return true;
+ return 1;
- return false;
+ return 0;
}
static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suffix) {
/* We don't treat this as an error, especially because we didn't check this for a
* long time. Nevertheless, we warn, because such mismatch can be mighty confusing. */
- if (!unit_name_compatible(entry, basename(target)))
+ r = unit_name_compatible(entry, basename(target));
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "Can't check if names %s and %s are compatible, ignoring: %m", entry, basename(target));
+ continue;
+ }
+ if (r == 0)
log_unit_warning(u, "%s dependency dropin %s target %s has different name",
unit_dependency_to_string(dependency), *p, target);
--- /dev/null
+BEGIN{
+ keywords=0 ; FS="," ;
+ print "extern const char load_fragment_gperf_nulstr[];" ;
+ print "const char load_fragment_gperf_nulstr[] ="
+}
+keyword==1 {
+ print "\"" $$1 "\\0\""
+}
+/%%/ {
+ keyword=1
+}
+END {
+ print ";"
+}
m4_dnl Define the context options only once
m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
`$1.WorkingDirectory, config_parse_working_directory, 0, offsetof($1, exec_context)
-$1.RootDirectory, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_directory)
-$1.RootImage, config_parse_unit_path_printf, 0, offsetof($1, exec_context.root_image)
+$1.RootDirectory, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_directory)
+$1.RootImage, config_parse_unit_path_printf, true, offsetof($1, exec_context.root_image)
$1.User, config_parse_user_group, 0, offsetof($1, exec_context.user)
$1.Group, config_parse_user_group, 0, offsetof($1, exec_context.group)
$1.SupplementaryGroups, config_parse_user_group_strv, 0, offsetof($1, exec_context.supplementary_groups)
$1.Environment, config_parse_environ, 0, offsetof($1, exec_context.environment)
$1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files)
$1.PassEnvironment, config_parse_pass_environ, 0, offsetof($1, exec_context.pass_environment)
-$1.DynamicUser, config_parse_bool, 0, offsetof($1, exec_context.dynamic_user)
+$1.DynamicUser, config_parse_bool, true, offsetof($1, exec_context.dynamic_user)
$1.StandardInput, config_parse_exec_input, 0, offsetof($1, exec_context)
$1.StandardOutput, config_parse_exec_output, 0, offsetof($1, exec_context)
$1.StandardError, config_parse_exec_output, 0, offsetof($1, exec_context)
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
+Unit.JobRunningTimeoutSec, config_parse_sec, 0, offsetof(Unit, job_running_timeout)
Unit.JobTimeoutAction, config_parse_emergency_action, 0, offsetof(Unit, job_timeout_action)
Unit.JobTimeoutRebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, job_timeout_reboot_arg)
Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
Unit.ConditionCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, offsetof(Unit, conditions)
Unit.ConditionHost, config_parse_unit_condition_string, CONDITION_HOST, offsetof(Unit, conditions)
Unit.ConditionACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, conditions)
+Unit.ConditionUser, config_parse_unit_condition_string, CONDITION_USER, offsetof(Unit, conditions)
+Unit.ConditionGroup, config_parse_unit_condition_string, CONDITION_GROUP, offsetof(Unit, conditions)
Unit.ConditionNull, config_parse_unit_condition_null, 0, offsetof(Unit, conditions)
Unit.AssertPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, asserts)
Unit.AssertPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, asserts)
Unit.AssertCapability, config_parse_unit_condition_string, CONDITION_CAPABILITY, offsetof(Unit, asserts)
Unit.AssertHost, config_parse_unit_condition_string, CONDITION_HOST, offsetof(Unit, asserts)
Unit.AssertACPower, config_parse_unit_condition_string, CONDITION_AC_POWER, offsetof(Unit, asserts)
+Unit.AssertUser, config_parse_unit_condition_string, CONDITION_USER, offsetof(Unit, asserts)
+Unit.AssertGroup, config_parse_unit_condition_string, CONDITION_GROUP, offsetof(Unit, asserts)
Unit.AssertNull, config_parse_unit_condition_null, 0, offsetof(Unit, asserts)
m4_dnl
Service.PIDFile, config_parse_unit_path_printf, 0, offsetof(Service, pid_file)
Socket.ExecStartPost, config_parse_exec, SOCKET_EXEC_START_POST, offsetof(Socket, exec_command)
Socket.ExecStopPre, config_parse_exec, SOCKET_EXEC_STOP_PRE, offsetof(Socket, exec_command)
Socket.ExecStopPost, config_parse_exec, SOCKET_EXEC_STOP_POST, offsetof(Socket, exec_command)
-Socket.TimeoutSec, config_parse_sec, 0, offsetof(Socket, timeout_usec)
+Socket.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Socket, timeout_usec)
Socket.SocketUser, config_parse_user_group, 0, offsetof(Socket, user)
Socket.SocketGroup, config_parse_user_group, 0, offsetof(Socket, group)
Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode)
Mount.Where, config_parse_path, 0, offsetof(Mount, where)
Mount.Options, config_parse_unit_string_printf, 0, offsetof(Mount, parameters_fragment.options)
Mount.Type, config_parse_string, 0, offsetof(Mount, parameters_fragment.fstype)
-Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec)
+Mount.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Mount, timeout_usec)
Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
Mount.SloppyOptions, config_parse_bool, 0, offsetof(Mount, sloppy_options)
Mount.LazyUnmount, config_parse_bool, 0, offsetof(Mount, lazy_unmount)
m4_dnl
Automount.Where, config_parse_path, 0, offsetof(Automount, where)
Automount.DirectoryMode, config_parse_mode, 0, offsetof(Automount, directory_mode)
-Automount.TimeoutIdleSec, config_parse_sec, 0, offsetof(Automount, timeout_idle_usec)
+Automount.TimeoutIdleSec, config_parse_sec_fix_0, 0, offsetof(Automount, timeout_idle_usec)
m4_dnl
Swap.What, config_parse_path, 0, offsetof(Swap, parameters_fragment.what)
Swap.Priority, config_parse_int, 0, offsetof(Swap, parameters_fragment.priority)
Swap.Options, config_parse_unit_string_printf, 0, offsetof(Swap, parameters_fragment.options)
-Swap.TimeoutSec, config_parse_sec, 0, offsetof(Swap, timeout_usec)
+Swap.TimeoutSec, config_parse_sec_fix_0, 0, offsetof(Swap, timeout_usec)
EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
_cleanup_free_ char *k = NULL;
Unit *u = userdata;
int r;
+ bool fatal = ltype;
assert(filename);
assert(lvalue);
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on %s%s: %m",
+ fatal ? "" : ", ignoring", rvalue);
+ return fatal ? -ENOEXEC : 0;
}
return config_parse_path(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata);
r = socket_address_parse_and_warn(&p->address, k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
+ if (r != -EAFNOSUPPORT)
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
+
return 0;
}
r = unit_full_printf(u, f, &path);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s, ignoring: %m", f);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on %s%s: %m",
+ f, ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
if (isempty(path)) {
/* First word is either "-" or "@" with no command. */
- log_syntax(unit, LOG_ERR, filename, line, 0, "Empty path in command line, ignoring: \"%s\"", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Empty path in command line%s: \"%s\"",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (!string_is_safe(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path contains special characters, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable path contains special characters%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (!path_is_absolute(path)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path is not absolute, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable path is not absolute%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (endswith(path, "/")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Executable path specifies a directory, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Executable path specifies a directory%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
if (!separate_argv0) {
if (r == 0)
break;
if (r < 0)
- return 0;
+ return ignore ? 0 : -ENOEXEC;
r = unit_full_printf(u, word, &resolved);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to resolve unit specifiers on %s, ignoring: %m", word);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers on %s%s: %m",
+ word, ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
}
if (!n || !n[0]) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Empty executable name or zeroeth argument, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Empty executable name or zeroeth argument%s: %s",
+ ignore ? ", ignoring" : "", rvalue);
+ return ignore ? 0 : -ENOEXEC;
}
nce = new0(ExecCommand, 1);
assert(rvalue);
assert(data);
- r = safe_atoi(rvalue, &i);
- if (r < 0 || i < 0 || i >= IOPRIO_BE_NR) {
+ r = ioprio_parse_priority(rvalue, &i);
+ if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IO priority, ignoring: %s", rvalue);
return 0;
}
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers%s: %m",
+ ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
free(c->selinux_context);
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers%s: %m",
+ ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
free(c->apparmor_profile);
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %m");
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve specifiers%s: %m",
+ ignore ? ", ignoring" : "");
+ return ignore ? 0 : -ENOEXEC;
}
free(c->smack_process_label);
r = unit_name_printf(UNIT(s), rvalue, &p);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers: %s", rvalue);
+ return -ENOEXEC;
}
if (!endswith(p, ".service")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unit must be of type service: %s", rvalue);
+ return -ENOEXEC;
}
r = manager_load_unit(UNIT(s)->manager, p, NULL, &error, &x);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s, ignoring: %s", rvalue, bus_error_message(&error, r));
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load unit %s: %s", rvalue, bus_error_message(&error, r));
+ return -ENOEXEC;
}
unit_ref_set(&s->service, x);
* compatibility with older versions of systemd where 0 instead of infinity was used as indicator to turn off a
* timeout. */
- r = parse_sec(rvalue, usec);
+ r = parse_sec_fix_0(rvalue, usec);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue);
return 0;
}
- if (*usec <= 0)
- *usec = USEC_INFINITY;
-
return 0;
}
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", rvalue);
+ return -ENOEXEC;
}
if (!valid_user_group_name_or_id(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
+ return -ENOEXEC;
}
n = k;
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
- break;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax: %s", rvalue);
+ return -ENOEXEC;
}
r = unit_full_printf(u, word, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", word);
- continue;
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in %s: %m", word);
+ return -ENOEXEC;
}
if (!valid_user_group_name_or_id(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID, ignoring: %s", k);
- continue;
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
+ return -ENOEXEC;
}
r = strv_push(users, k);
r = unit_full_printf(u, rvalue, &k);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers in working directory path '%s', ignoring: %m", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolve unit specifiers in working directory path '%s'%s: %m",
+ rvalue, missing_ok ? ", ignoring" : "");
+ return missing_ok ? 0 : -ENOEXEC;
}
path_kill_slashes(k);
if (!utf8_is_valid(k)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
+ return missing_ok ? 0 : -ENOEXEC;
}
if (!path_is_absolute(k)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Working directory path '%s' is not absolute, ignoring.", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Working directory path '%s' is not absolute%s.",
+ rvalue, missing_ok ? ", ignoring" : "");
+ return missing_ok ? 0 : -ENOEXEC;
}
- free_and_replace(c->working_directory, k);
-
c->working_directory_home = false;
+ free_and_replace(c->working_directory, k);
}
c->working_directory_missing_ok = missing_ok;
void *userdata) {
ExecContext *c = data;
+ Unit *u = userdata;
const char *p;
int r;
p = rvalue;
for (;;) {
_cleanup_free_ char *source = NULL, *destination = NULL;
+ _cleanup_free_ char *sresolved = NULL, *dresolved = NULL;
char *s = NULL, *d = NULL;
bool rbind = true, ignore_enoent = false;
return 0;
}
- s = source;
+ r = unit_full_printf(u, source, &sresolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolved specifiers in \"%s\", ignoring: %m", source);
+ return 0;
+ }
+
+ s = sresolved;
if (s[0] == '-') {
ignore_enoent = true;
s++;
return 0;
}
- if (!utf8_is_valid(destination)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, destination);
+ r = unit_full_printf(u, destination, &dresolved);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to resolved specifiers in \"%s\", ignoring: %m", destination);
+ return 0;
+ }
+
+ if (!utf8_is_valid(dresolved)) {
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, dresolved);
return 0;
}
- if (!path_is_absolute(destination)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute destination path, ignoring: %s", destination);
+ if (!path_is_absolute(dresolved)) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute destination path, ignoring: %s", dresolved);
return 0;
}
- d = path_kill_slashes(destination);
+ d = path_kill_slashes(dresolved);
/* Optionally, there's also a short option string specified */
if (p && p[-1] == ':') {
return r;
r = load_from_path(u, k);
- if (r < 0)
+ if (r < 0) {
+ if (r == -ENOEXEC)
+ log_unit_notice(u, "Unit configuration has fatal error, unit will not be started.");
return r;
+ }
if (u->load_state == UNIT_STUB) {
SET_FOREACH(t, u->names, i) {
#include "missing.h"
#include "netlink-util.h"
-static int start_loopback(sd_netlink *rtnl) {
+#define LOOPBACK_SETUP_TIMEOUT_USEC (5 * USEC_PER_SEC)
+
+struct state {
+ unsigned n_messages;
+ int rcode;
+ const char *title;
+};
+
+static int generic_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ struct state *s = userdata;
+
+ assert(s);
+ assert(s->n_messages > 0);
+ s->n_messages--;
+
+ errno = 0;
+ log_debug_errno(sd_netlink_message_get_errno(m), "Failed to %s: %m", s->title);
+
+ s->rcode = sd_netlink_message_get_errno(m);
+
+ return 0;
+}
+
+static int start_loopback(sd_netlink *rtnl, struct state *s) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
+ assert(rtnl);
+ assert(s);
+
r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, LOOPBACK_IFINDEX);
if (r < 0)
return r;
if (r < 0)
return r;
- r = sd_netlink_call(rtnl, req, 0, NULL);
+ r = sd_netlink_call_async(rtnl, req, generic_handler, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL);
+ if (r < 0)
+ return r;
+
+ s->n_messages ++;
+ return 0;
+}
+
+static int add_ipv4_address(sd_netlink *rtnl, struct state *s) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(s);
+
+ r = sd_rtnl_message_new_addr(rtnl, &req, RTM_NEWADDR, LOOPBACK_IFINDEX, AF_INET);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_prefixlen(req, 8);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_HOST);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_in_addr(req, IFA_LOCAL, &(struct in_addr) { .s_addr = htobe32(INADDR_LOOPBACK) } );
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL);
if (r < 0)
return r;
+ s->n_messages ++;
+ return 0;
+}
+
+static int add_ipv6_address(sd_netlink *rtnl, struct state *s) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(rtnl);
+ assert(s);
+
+ r = sd_rtnl_message_new_addr(rtnl, &req, RTM_NEWADDR, LOOPBACK_IFINDEX, AF_INET6);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_prefixlen(req, 128);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
+ if (r < 0)
+ return r;
+
+ r = sd_rtnl_message_addr_set_scope(req, RT_SCOPE_HOST);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_message_append_in6_addr(req, IFA_LOCAL, &in6addr_loopback);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call_async(rtnl, req, generic_handler, s, USEC_INFINITY, NULL);
+ if (r < 0)
+ return r;
+
+ s->n_messages ++;
return 0;
}
if (r < 0)
return false;
- r = sd_netlink_call(rtnl, req, 0, &reply);
+ r = sd_netlink_call(rtnl, req, USEC_INFINITY, &reply);
if (r < 0)
return false;
int loopback_setup(void) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ struct state state_4 = { .title = "add address 127.0.0.1 to loopback interface" },
+ state_6 = { .title = "add address ::1 to loopback interface"},
+ state_up = { .title = "bring loopback interface up" };
int r;
r = sd_netlink_open(&rtnl);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to open netlink: %m");
+
+ /* Note that we add the IP addresses here explicitly even though the kernel does that too implicitly when
+ * setting up the loopback device. The reason we do this here a second time (and possibly race against the
+ * kernel) is that we want to synchronously wait until the IP addresses are set up correctly, see
+ *
+ * https://github.com/systemd/systemd/issues/5641 */
- r = start_loopback(rtnl);
- if (r < 0) {
+ r = add_ipv4_address(rtnl, &state_4);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enqueue IPv4 loopback address add request: %m");
+
+ r = add_ipv6_address(rtnl, &state_6);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enqueue IPv6 loopback address add request: %m");
+
+ r = start_loopback(rtnl, &state_up);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enqueue loopback interface start request: %m");
+
+ while (state_4.n_messages + state_6.n_messages + state_up.n_messages > 0) {
+ r = sd_netlink_wait(rtnl, LOOPBACK_SETUP_TIMEOUT_USEC);
+ if (r < 0)
+ return log_error_errno(r, "Failed to wait for netlink event: %m");
+
+ r = sd_netlink_process(rtnl, NULL);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to process netlink event: %m");
+ }
- /* If we lack the permissions to configure the
- * loopback device, but we find it to be already
- * configured, let's exit cleanly, in order to
- * supported unprivileged containers. */
- if (r == -EPERM && check_loopback(rtnl))
+ /* Note that we don't really care whether the addresses could be added or not */
+ if (state_up.rcode != 0) {
+ /* If we lack the permissions to configure the loopback device,
+ * but we find it to be already configured, let's exit cleanly,
+ * in order to supported unprivileged containers. */
+ if (state_up.rcode == -EPERM && check_loopback(rtnl))
return 0;
- return log_warning_errno(r, "Failed to configure loopback device: %m");
+ return log_warning_errno(state_up.rcode, "Failed to configure loopback device: %m");
}
return 0;
return ncpus;
if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
- log_warning("Failed to set CPU affinity: %m");
+ log_warning_errno(errno, "Failed to set CPU affinity: %m");
return 0;
}
static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
struct rlimit nl;
int r;
+ int min_max;
+ _cleanup_free_ char *nr_open = NULL;
assert(saved_rlimit);
arg_default_rlimit[RLIMIT_NOFILE] = rl;
}
+ /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */
+ r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
+ if (r == 0)
+ r = safe_atoi(nr_open, &min_max);
+ /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
+ if (r < 0)
+ min_max = 1024 * 1024;
+
/* Bump up the resource limit for ourselves substantially */
- nl.rlim_cur = nl.rlim_max = 64*1024;
+ nl.rlim_cur = nl.rlim_max = min_max;
r = setrlimit_closest(RLIMIT_NOFILE, &nl);
if (r < 0)
return log_warning_errno(r, "Setting RLIMIT_NOFILE failed, ignoring: %m");
if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
log_error_errno(errno, "Failed to adjust timer slack: %m");
- if (!cap_test_all(arg_capability_bounding_set)) {
+ if (arg_system && !cap_test_all(arg_capability_bounding_set)) {
r = capability_bounding_set_drop_usermode(arg_capability_bounding_set);
if (r < 0) {
log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m");
return sd_bus_error_setf(e, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(invocation_id));
}
- /* If this didn't work, we use the suffix as unit name. */
+ /* If this didn't work, we check if this is a unit name */
+ if (!unit_name_is_valid(n, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
+ return sd_bus_error_setf(e, SD_BUS_ERROR_INVALID_ARGS, "Unit name %s is neither a valid invocation ID nor unit name.", n);
+
r = manager_load_unit(m, n, NULL, e, &u);
if (r < 0)
return r;
m->n_reloading++;
for (;;) {
- char line[LINE_MAX], *l;
- const char *val;
+ char line[LINE_MAX];
+ const char *val, *l;
if (!fgets(line, sizeof(line), f)) {
if (feof(f))
uint32_t id;
if (safe_atou32(val, &id) < 0)
- log_debug("Failed to parse current job id value %s", val);
+ log_notice("Failed to parse current job id value %s", val);
else
m->current_job_id = MAX(m->current_job_id, id);
uint32_t n;
if (safe_atou32(val, &n) < 0)
- log_debug("Failed to parse installed jobs counter %s", val);
+ log_notice("Failed to parse installed jobs counter %s", val);
else
m->n_installed_jobs += n;
uint32_t n;
if (safe_atou32(val, &n) < 0)
- log_debug("Failed to parse failed jobs counter %s", val);
+ log_notice("Failed to parse failed jobs counter %s", val);
else
m->n_failed_jobs += n;
b = parse_boolean(val);
if (b < 0)
- log_debug("Failed to parse taint /usr flag %s", val);
+ log_notice("Failed to parse taint /usr flag %s", val);
else
m->taint_usr = m->taint_usr || b;
dual_timestamp_deserialize(val, &m->units_load_finish_timestamp);
else if (startswith(l, "env=")) {
r = deserialize_environment(&m->environment, l);
+ if (r == -ENOMEM)
+ goto finish;
if (r < 0)
- return r;
+ log_notice_errno(r, "Failed to parse environment entry: \"%s\": %m", l);
} else if ((val = startswith(l, "notify-fd="))) {
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse notify fd: %s", val);
+ log_notice("Failed to parse notify fd: \"%s\"", val);
else {
m->notify_event_source = sd_event_source_unref(m->notify_event_source);
safe_close(m->notify_fd);
int fd;
if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
- log_debug("Failed to parse cgroups agent fd: %s", val);
+ log_notice("Failed to parse cgroups agent fd: %s", val);
else {
m->cgroups_agent_event_source = sd_event_source_unref(m->cgroups_agent_event_source);
safe_close(m->cgroups_agent_fd);
int fd0, fd1;
if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
- log_debug("Failed to parse user lookup fd: %s", val);
+ log_notice("Failed to parse user lookup fd: %s", val);
else {
m->user_lookup_event_source = sd_event_source_unref(m->user_lookup_event_source);
safe_close_pair(m->user_lookup_fds);
log_oom();
} else if (!startswith(l, "kdbus-fd=")) /* ignore this one */
- log_debug("Unknown serialization item '%s'", l);
+ log_notice("Unknown serialization item '%s'", l);
}
for (;;) {
--- /dev/null
+libcore_la_sources = '''
+ unit.c
+ unit.h
+ unit-printf.c
+ unit-printf.h
+ job.c
+ job.h
+ manager.c
+ manager.h
+ transaction.c
+ transaction.h
+ load-fragment.c
+ load-fragment.h
+ service.c
+ service.h
+ socket.c
+ socket.h
+ busname.c
+ busname.h
+ bus-policy.c
+ bus-policy.h
+ target.c
+ target.h
+ device.c
+ device.h
+ mount.c
+ mount.h
+ automount.c
+ automount.h
+ swap.c
+ swap.h
+ timer.c
+ timer.h
+ path.c
+ path.h
+ slice.c
+ slice.h
+ scope.c
+ scope.h
+ load-dropin.c
+ load-dropin.h
+ execute.c
+ execute.h
+ dynamic-user.c
+ dynamic-user.h
+ kill.c
+ kill.h
+ dbus.c
+ dbus.h
+ dbus-manager.c
+ dbus-manager.h
+ dbus-unit.c
+ dbus-unit.h
+ dbus-job.c
+ dbus-job.h
+ dbus-service.c
+ dbus-service.h
+ dbus-socket.c
+ dbus-socket.h
+ dbus-busname.c
+ dbus-busname.h
+ dbus-target.c
+ dbus-target.h
+ dbus-device.c
+ dbus-device.h
+ dbus-mount.c
+ dbus-mount.h
+ dbus-automount.c
+ dbus-automount.h
+ dbus-swap.c
+ dbus-swap.h
+ dbus-timer.c
+ dbus-timer.h
+ dbus-path.c
+ dbus-path.h
+ dbus-slice.c
+ dbus-slice.h
+ dbus-scope.c
+ dbus-scope.h
+ dbus-execute.c
+ dbus-execute.h
+ dbus-kill.c
+ dbus-kill.h
+ dbus-cgroup.c
+ dbus-cgroup.h
+ cgroup.c
+ cgroup.h
+ selinux-access.c
+ selinux-access.h
+ selinux-setup.c
+ selinux-setup.h
+ smack-setup.c
+ smack-setup.h
+ ima-setup.c
+ ima-setup.h
+ locale-setup.h
+ locale-setup.c
+ hostname-setup.c
+ hostname-setup.h
+ machine-id-setup.c
+ machine-id-setup.h
+ mount-setup.c
+ mount-setup.h
+ kmod-setup.c
+ kmod-setup.h
+ loopback-setup.h
+ loopback-setup.c
+ namespace.c
+ namespace.h
+ killall.h
+ killall.c
+ audit-fd.c
+ audit-fd.h
+ show-status.c
+ show-status.h
+ emergency-action.c
+ emergency-action.h
+'''.split()
+
+load_fragment_gperf_gperf = custom_target(
+ 'load-fragment-gperf.gperf',
+ input : 'load-fragment-gperf.gperf.m4',
+ output: 'load-fragment-gperf.gperf',
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true)
+
+load_fragment_gperf_c = custom_target(
+ 'load-fragment-gperf.c',
+ input : load_fragment_gperf_gperf,
+ output : 'load-fragment-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+awkscript = 'load-fragment-gperf-nulstr.awk'
+load_fragment_gperf_nulstr_c = custom_target(
+ 'load-fragment-gperf-nulstr.c',
+ input : [awkscript, load_fragment_gperf_gperf],
+ output : 'load-fragment-gperf-nulstr.c',
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+libcore = static_library(
+ 'core',
+ libcore_la_sources,
+ load_fragment_gperf_c,
+ load_fragment_gperf_nulstr_c,
+ include_directories : includes,
+ link_with : [libshared_static],
+ dependencies : [threads,
+ libseccomp,
+ libpam,
+ libaudit,
+ libkmod,
+ libapparmor,
+ libmount])
+
+systemd_sources = files('main.c')
+
+systemd_shutdown_sources = files('''
+ shutdown.c
+ umount.c
+ umount.h
+ mount-setup.c
+ mount-setup.h
+ killall.c
+ killall.h
+'''.split())
+
+in_files = [['macros.systemd', rpmmacrosdir],
+ ['triggers.systemd', ''],
+ ['systemd.pc', pkgconfigdatadir]]
+
+foreach item : in_files
+ file = item[0]
+ dir = item[1]
+
+ # If 'no', disable generation completely.
+ # If '', generate, but do not install.
+ if dir != 'no'
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ if dir != ''
+ install_data(gen,
+ install_dir : dir)
+ endif
+ endif
+endforeach
+
+install_data('org.freedesktop.systemd1.conf',
+ install_dir : dbuspolicydir)
+install_data('org.freedesktop.systemd1.service',
+ install_dir : dbussystemservicedir)
+
+policy_in = configure_file(
+ input : 'org.freedesktop.systemd1.policy.in.in',
+ output : 'org.freedesktop.systemd1.policy.in',
+ configuration : substs)
+
+custom_target(
+ 'org.freedesktop.systemd1.policy',
+ input : policy_in,
+ output : 'org.freedesktop.systemd1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+
+# TODO: this might work with meson from git, see
+# https://github.com/mesonbuild/meson/issues/1441#issuecomment-283585493
+#
+# i18n.merge_file(
+# 'org.freedesktop.systemd1.policy',
+# po_dir : po_dir,
+# input : policy_in,
+# output : 'org.freedesktop.systemd1.policy',
+# install : install_polkit,
+# install_dir : polkitpolicydir)
+
+install_data('system.conf',
+ 'user.conf',
+ install_dir : pkgsysconfdir)
+
+meson.add_install_script('sh', '-c', mkdir_p.format(systemshutdowndir))
+meson.add_install_script('sh', '-c', mkdir_p.format(systemsleepdir))
+meson.add_install_script('sh', '-c', mkdir_p.format(systemgeneratordir))
+meson.add_install_script('sh', '-c', mkdir_p.format(usergeneratordir))
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(pkgsysconfdir, 'system/multi-user.target.wants')))
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(pkgsysconfdir, 'system/getty.target.wants')))
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(pkgsysconfdir, 'user')))
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'xdg/systemd')))
m->control_command_id = MOUNT_EXEC_UNMOUNT;
m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
- r = exec_command_set(m->control_command, UMOUNT_PATH, m->where, NULL);
+ r = exec_command_set(m->control_command, UMOUNT_PATH, m->where, "-c", NULL);
if (r >= 0 && m->lazy_unmount)
r = exec_command_append(m->control_command, "-l", NULL);
if (r >= 0 && m->force_unmount)
#include <linux/fs.h>
#include "alloc-util.h"
+#include "base-filesystem.h"
#include "dev-setup.h"
#include "fd-util.h"
#include "fs-util.h"
return 0;
}
-static int make_read_only(MountEntry *m, char **blacklist) {
+static int make_read_only(MountEntry *m, char **blacklist, FILE *proc_self_mountinfo) {
int r = 0;
assert(m);
+ assert(proc_self_mountinfo);
if (mount_entry_read_only(m))
- r = bind_remount_recursive(mount_entry_path(m), true, blacklist);
+ r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), true, blacklist, proc_self_mountinfo);
else if (m->mode == PRIVATE_DEV) { /* Superblock can be readonly but the submounts can't */
if (mount(NULL, mount_entry_path(m), NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
r = -errno;
return r;
}
-static bool namespace_info_mount_apivfs(const NameSpaceInfo *ns_info) {
+static bool namespace_info_mount_apivfs(const char *root_directory, const NameSpaceInfo *ns_info) {
assert(ns_info);
- /* ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=, since to protect the API VFS mounts,
- * they need to be around in the first place... */
+ /*
+ * ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=,
+ * since to protect the API VFS mounts, they need to be around in the
+ * first place... and RootDirectory= or RootImage= need to be set.
+ */
- return ns_info->mount_apivfs ||
- ns_info->protect_control_groups ||
- ns_info->protect_kernel_tunables;
+ /* root_directory should point to a mount point */
+ return root_directory &&
+ (ns_info->mount_apivfs ||
+ ns_info->protect_control_groups ||
+ ns_info->protect_kernel_tunables);
}
static unsigned namespace_calculate_mounts(
+ const char* root_directory,
const NameSpaceInfo *ns_info,
char** read_write_paths,
char** read_only_paths,
(ns_info->protect_control_groups ? 1 : 0) +
(ns_info->protect_kernel_modules ? ELEMENTSOF(protect_kernel_modules_table) : 0) +
protect_home_cnt + protect_system_cnt +
- (namespace_info_mount_apivfs(ns_info) ? ELEMENTSOF(apivfs_table) : 0);
+ (namespace_info_mount_apivfs(root_directory, ns_info) ? ELEMENTSOF(apivfs_table) : 0);
}
int setup_namespace(
}
n_mounts = namespace_calculate_mounts(
+ root_directory,
ns_info,
read_write_paths,
read_only_paths,
if (r < 0)
goto finish;
- if (namespace_info_mount_apivfs(ns_info)) {
+ if (namespace_info_mount_apivfs(root_directory, ns_info)) {
r = append_static_mounts(&m, apivfs_table, ELEMENTSOF(apivfs_table), ns_info->ignore_protect_paths);
if (r < 0)
goto finish;
}
}
+ /* Try to set up the new root directory before mounting anything there */
+ if (root_directory)
+ (void) base_filesystem_create(root_directory, UID_INVALID, GID_INVALID);
+
if (root_image) {
r = dissected_image_mount(dissected_image, root_directory, dissect_image_flags);
if (r < 0)
}
if (n_mounts > 0) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
char **blacklist;
unsigned j;
+ /* Open /proc/self/mountinfo now as it may become unavailable if we mount anything on top of /proc.
+ * For example, this is the case with the option: 'InaccessiblePaths=/proc' */
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo) {
+ r = -errno;
+ goto finish;
+ }
+
/* First round, add in all special mounts we need */
for (m = mounts; m < mounts + n_mounts; ++m) {
r = apply_mount(root_directory, m, tmp_dir, var_tmp_dir);
/* Second round, flip the ro bits if necessary. */
for (m = mounts; m < mounts + n_mounts; ++m) {
- r = make_read_only(m, blacklist);
+ r = make_read_only(m, blacklist, proc_self_mountinfo);
if (r < 0)
goto finish;
}
fmt2 = strjoina("selinux: ", fmt);
va_start(ap, fmt);
- log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt2, ap);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ log_internalv(LOG_AUTH | callback_type_to_priority(type),
+ 0, __FILE__, __LINE__, __FUNCTION__,
+ fmt2, ap);
+#pragma GCC diagnostic pop
va_end(ap);
return 0;
#include "service.h"
#include "signal-util.h"
#include "special.h"
+#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
}
r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
- if (r < 0) {
+ if (r < 0 && r != -EPERM) { /* EPERM indicates fds that aren't pollable, which is OK */
free(fs->fdname);
free(fs);
return r;
- }
-
- (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
+ } else if (r >= 0)
+ (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
LIST_PREPEND(fd_store, s->fd_store, fs);
s->n_fd_store++;
return 0;
}
-static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
+static int service_collect_fds(Service *s,
+ int **fds,
+ char ***fd_names,
+ unsigned *n_storage_fds,
+ unsigned *n_socket_fds) {
+
_cleanup_strv_free_ char **rfd_names = NULL;
_cleanup_free_ int *rfds = NULL;
- int rn_fds = 0, r;
+ unsigned rn_socket_fds = 0, rn_storage_fds = 0;
+ int r;
assert(s);
assert(fds);
assert(fd_names);
+ assert(n_socket_fds);
if (s->socket_fd >= 0) {
if (!rfd_names)
return -ENOMEM;
- rn_fds = 1;
+ rn_socket_fds = 1;
} else {
Iterator i;
Unit *u;
if (!rfds) {
rfds = cfds;
- rn_fds = cn_fds;
+ rn_socket_fds = cn_fds;
cfds = NULL;
} else {
int *t;
- t = realloc(rfds, (rn_fds + cn_fds) * sizeof(int));
+ t = realloc(rfds, (rn_socket_fds + cn_fds) * sizeof(int));
if (!t)
return -ENOMEM;
- memcpy(t + rn_fds, cfds, cn_fds * sizeof(int));
+ memcpy(t + rn_socket_fds, cfds, cn_fds * sizeof(int));
rfds = t;
- rn_fds += cn_fds;
+ rn_socket_fds += cn_fds;
}
r = strv_extend_n(&rfd_names, socket_fdname(sock), cn_fds);
if (s->n_fd_store > 0) {
ServiceFDStore *fs;
+ unsigned n_fds;
char **nl;
int *t;
- t = realloc(rfds, (rn_fds + s->n_fd_store) * sizeof(int));
+ t = realloc(rfds, (rn_socket_fds + s->n_fd_store) * sizeof(int));
if (!t)
return -ENOMEM;
rfds = t;
- nl = realloc(rfd_names, (rn_fds + s->n_fd_store + 1) * sizeof(char*));
+ nl = realloc(rfd_names, (rn_socket_fds + s->n_fd_store + 1) * sizeof(char*));
if (!nl)
return -ENOMEM;
rfd_names = nl;
+ n_fds = rn_socket_fds;
LIST_FOREACH(fd_store, fs, s->fd_store) {
- rfds[rn_fds] = fs->fd;
- rfd_names[rn_fds] = strdup(strempty(fs->fdname));
- if (!rfd_names[rn_fds])
+ rfds[n_fds] = fs->fd;
+ rfd_names[n_fds] = strdup(strempty(fs->fdname));
+ if (!rfd_names[n_fds])
return -ENOMEM;
- rn_fds++;
+ rn_storage_fds++;
+ n_fds++;
}
- rfd_names[rn_fds] = NULL;
+ rfd_names[n_fds] = NULL;
}
*fds = rfds;
*fd_names = rfd_names;
+ *n_socket_fds = rn_socket_fds;
+ *n_storage_fds = rn_storage_fds;
rfds = NULL;
rfd_names = NULL;
- return rn_fds;
+ return 0;
}
static bool service_exec_needs_notify_socket(Service *s, ExecFlags flags) {
_cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
_cleanup_free_ int *fds = NULL;
- unsigned n_fds = 0, n_env = 0;
+ unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
const char *path;
pid_t pid;
s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
s->exec_context.std_error == EXEC_OUTPUT_SOCKET) {
- r = service_collect_fds(s, &fds, &fd_names);
+ r = service_collect_fds(s, &fds, &fd_names, &n_storage_fds, &n_socket_fds);
if (r < 0)
return r;
- n_fds = r;
- log_unit_debug(UNIT(s), "Passing %i fds to service", n_fds);
+ log_unit_debug(UNIT(s), "Passing %i fds to service", n_storage_fds + n_socket_fds);
}
r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), timeout));
exec_params.environment = final_env;
exec_params.fds = fds;
exec_params.fd_names = fd_names;
- exec_params.n_fds = n_fds;
+ exec_params.n_storage_fds = n_storage_fds;
+ exec_params.n_socket_fds = n_socket_fds;
exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
exec_params.cgroup_path = path;
return !!s->exec_command[SERVICE_EXEC_RELOAD];
}
+static unsigned service_exec_command_index(Unit *u, ServiceExecCommand id, ExecCommand *current) {
+ Service *s = SERVICE(u);
+ unsigned idx = 0;
+ ExecCommand *first, *c;
+
+ assert(s);
+
+ first = s->exec_command[id];
+
+ /* Figure out where we are in the list by walking back to the beginning */
+ for (c = current; c != first; c = c->command_prev)
+ idx++;
+
+ return idx;
+}
+
+static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command) {
+ Service *s = SERVICE(u);
+ ServiceExecCommand id;
+ unsigned idx;
+ const char *type;
+ char **arg;
+ _cleanup_free_ char *args = NULL, *p = NULL;
+ size_t allocated = 0, length = 0;
+
+ assert(s);
+ assert(f);
+
+ if (!command)
+ return 0;
+
+ if (command == s->control_command) {
+ type = "control";
+ id = s->control_command_id;
+ } else {
+ type = "main";
+ id = SERVICE_EXEC_START;
+ }
+
+ idx = service_exec_command_index(u, id, command);
+
+ STRV_FOREACH(arg, command->argv) {
+ size_t n;
+ _cleanup_free_ char *e = NULL;
+
+ e = xescape(*arg, WHITESPACE);
+ if (!e)
+ return -ENOMEM;
+
+ n = strlen(e);
+ if (!GREEDY_REALLOC(args, allocated, length + 1 + n + 1))
+ return -ENOMEM;
+
+ if (length > 0)
+ args[length++] = ' ';
+
+ memcpy(args + length, e, n);
+ length += n;
+ }
+
+ if (!GREEDY_REALLOC(args, allocated, length + 1))
+ return -ENOMEM;
+ args[length++] = 0;
+
+ p = xescape(command->path, WHITESPACE);
+ if (!p)
+ return -ENOMEM;
+
+ fprintf(f, "%s-command=%s %u %s %s\n", type, service_exec_command_to_string(id), idx, p, args);
+
+ return 0;
+}
+
static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
Service *s = SERVICE(u);
ServiceFDStore *fs;
if (r < 0)
return r;
- /* FIXME: There's a minor uncleanliness here: if there are
- * multiple commands attached here, we will start from the
- * first one again */
- if (s->control_command_id >= 0)
- unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id));
+ service_serialize_exec_command(u, f, s->control_command);
+ service_serialize_exec_command(u, f, s->main_command);
r = unit_serialize_item_fd(u, f, fds, "stdin-fd", s->stdin_fd);
if (r < 0)
return 0;
}
+static int service_deserialize_exec_command(Unit *u, const char *key, const char *value) {
+ Service *s = SERVICE(u);
+ int r;
+ unsigned idx = 0, i;
+ bool control, found = false;
+ ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID;
+ ExecCommand *command = NULL;
+ _cleanup_free_ char *path = NULL;
+ _cleanup_strv_free_ char **argv = NULL;
+
+ enum ExecCommandState {
+ STATE_EXEC_COMMAND_TYPE,
+ STATE_EXEC_COMMAND_INDEX,
+ STATE_EXEC_COMMAND_PATH,
+ STATE_EXEC_COMMAND_ARGS,
+ _STATE_EXEC_COMMAND_MAX,
+ _STATE_EXEC_COMMAND_INVALID = -1,
+ } state;
+
+ assert(s);
+ assert(key);
+ assert(value);
+
+ control = streq(key, "control-command");
+
+ state = STATE_EXEC_COMMAND_TYPE;
+
+ for (;;) {
+ _cleanup_free_ char *arg = NULL;
+
+ r = extract_first_word(&value, &arg, NULL, EXTRACT_CUNESCAPE);
+ if (r == 0)
+ break;
+ else if (r < 0)
+ return r;
+
+ switch (state) {
+ case STATE_EXEC_COMMAND_TYPE:
+ id = service_exec_command_from_string(arg);
+ if (id < 0)
+ return -EINVAL;
+
+ state = STATE_EXEC_COMMAND_INDEX;
+ break;
+ case STATE_EXEC_COMMAND_INDEX:
+ r = safe_atou(arg, &idx);
+ if (r < 0)
+ return -EINVAL;
+
+ state = STATE_EXEC_COMMAND_PATH;
+ break;
+ case STATE_EXEC_COMMAND_PATH:
+ path = arg;
+ arg = NULL;
+ state = STATE_EXEC_COMMAND_ARGS;
+
+ if (!path_is_absolute(path))
+ return -EINVAL;
+ break;
+ case STATE_EXEC_COMMAND_ARGS:
+ r = strv_extend(&argv, arg);
+ if (r < 0)
+ return -ENOMEM;
+ break;
+ default:
+ assert_not_reached("Unknown error at deserialization of exec command");
+ break;
+ }
+ }
+
+ if (state != STATE_EXEC_COMMAND_ARGS)
+ return -EINVAL;
+
+ /* Let's check whether exec command on given offset matches data that we just deserialized */
+ for (command = s->exec_command[id], i = 0; command; command = command->command_next, i++) {
+ if (i != idx)
+ continue;
+
+ found = strv_equal(argv, command->argv) && streq(command->path, path);
+ break;
+ }
+
+ if (!found) {
+ /* Command at the index we serialized is different, let's look for command that exactly
+ * matches but is on different index. If there is no such command we will not resume execution. */
+ for (command = s->exec_command[id]; command; command = command->command_next)
+ if (strv_equal(command->argv, argv) && streq(command->path, path))
+ break;
+ }
+
+ if (command && control)
+ s->control_command = command;
+ else if (command)
+ s->main_command = command;
+ else
+ log_unit_warning(u, "Current command vanished from the unit file, execution of the command list won't be resumed.");
+
+ return 0;
+}
+
static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
Service *s = SERVICE(u);
int r;
s->status_text = t;
}
- } else if (streq(key, "control-command")) {
- ServiceExecCommand id;
-
- id = service_exec_command_from_string(value);
- if (id < 0)
- log_unit_debug(u, "Failed to parse exec-command value: %s", value);
- else {
- s->control_command_id = id;
- s->control_command = s->exec_command[id];
- }
} else if (streq(key, "accept-socket")) {
Unit *socket;
s->watchdog_override_enable = true;
s->watchdog_override_usec = watchdog_override_usec;
}
+ } else if (STR_IN_SET(key, "main-command", "control-command")) {
+ r = service_deserialize_exec_command(u, key, value);
+ if (r < 0)
+ log_unit_debug_errno(u, r, "Failed to parse serialized command \"%s\": %m", value);
} else
log_unit_debug(u, "Unknown serialization key: %s", key);
log_struct(f == SERVICE_SUCCESS ? LOG_DEBUG :
(code == CLD_EXITED ? LOG_NOTICE : LOG_WARNING),
- LOG_UNIT_ID(u),
LOG_UNIT_MESSAGE(u, "Main process exited, code=%s, status=%i/%s",
sigchld_code_to_string(code), status,
strna(code == CLD_EXITED
: signal_to_string(status))),
"EXIT_CODE=%s", sigchld_code_to_string(code),
"EXIT_STATUS=%i", status,
+ LOG_UNIT_ID(u),
NULL);
if (s->result == SERVICE_SUCCESS)
DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
-static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
- [NOTIFY_NONE] = "none",
- [NOTIFY_MAIN] = "main",
- [NOTIFY_EXEC] = "exec",
- [NOTIFY_ALL] = "all"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
-
static const char* const notify_state_table[_NOTIFY_STATE_MAX] = {
[NOTIFY_UNKNOWN] = "unknown",
[NOTIFY_READY] = "ready",
_SERVICE_EXEC_COMMAND_INVALID = -1
} ServiceExecCommand;
-typedef enum NotifyAccess {
- NOTIFY_NONE,
- NOTIFY_ALL,
- NOTIFY_MAIN,
- NOTIFY_EXEC,
- _NOTIFY_ACCESS_MAX,
- _NOTIFY_ACCESS_INVALID = -1
-} NotifyAccess;
-
typedef enum NotifyState {
NOTIFY_UNKNOWN,
NOTIFY_READY,
const char* service_exec_command_to_string(ServiceExecCommand i) _const_;
ServiceExecCommand service_exec_command_from_string(const char *s) _pure_;
-const char* notify_access_to_string(NotifyAccess i) _const_;
-NotifyAccess notify_access_from_string(const char *s) _pure_;
-
const char* notify_state_to_string(NotifyState i) _const_;
NotifyState notify_state_from_string(const char *s) _pure_;
_cleanup_free_ char *param = NULL;
r = read_one_line_file("/run/systemd/reboot-param", ¶m);
- if (r < 0)
+ if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read reboot parameter file: %m");
if (!isempty(param)) {
return r;
}
+static int write_onlycap_list(void) {
+ _cleanup_close_ int onlycap_fd = -1;
+ _cleanup_free_ char *list = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ size_t len = 0, allocated = 0;
+ char buf[LINE_MAX];
+ int r;
+
+ f = fopen("/etc/smack/onlycap", "re");
+ if (!f) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to read '/etc/smack/onlycap'");
+ return errno == ENOENT ? ENOENT : -errno;
+ }
+
+ FOREACH_LINE(buf, f, return -errno) {
+ size_t l;
+
+ if (isempty(truncate_nl(buf)) || strchr(COMMENTS, *buf))
+ continue;
+
+ l = strlen(buf);
+ if (!GREEDY_REALLOC(list, allocated, len + l + 1))
+ return log_oom();
+
+ stpcpy(list + len, buf)[0] = ' ';
+ len += l + 1;
+ }
+
+ if (!len)
+ return 0;
+
+ list[len - 1] = 0;
+
+ onlycap_fd = open("/sys/fs/smackfs/onlycap", O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+ if (onlycap_fd < 0) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/onlycap'");
+ return -errno; /* negative error */
+ }
+
+ r = write(onlycap_fd, list, len);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to write onlycap list(%s) to '/sys/fs/smackfs/onlycap'", list);
+
+ return 0;
+}
+
#endif
int mac_smack_setup(bool *loaded_policy) {
break;
}
+ r = write_onlycap_list();
+ switch(r) {
+ case -ENOENT:
+ log_debug("Smack is not enabled in the kernel.");
+ break;
+ case ENOENT:
+ log_debug("Smack onlycap list file '/etc/smack/onlycap' not found");
+ break;
+ case 0:
+ log_info("Successfully wrote Smack onlycap list.");
+ break;
+ default:
+ log_emergency_errno(r, "Failed to write Smack onlycap list.");
+ return r;
+ }
+
*loaded_policy = true;
#endif
else
LIST_FOREACH(port, p, s->ports)
if (p->type == SOCKET_FIFO &&
- path_equal_or_files_same(p->path, value+skip)) {
+ path_equal_or_files_same(p->path, value+skip, 0)) {
socket_port_take_fd(p, fds, fd);
break;
}
else
LIST_FOREACH(port, p, s->ports)
if (p->type == SOCKET_SPECIAL &&
- path_equal_or_files_same(p->path, value+skip)) {
+ path_equal_or_files_same(p->path, value+skip, 0)) {
socket_port_take_fd(p, fds, fd);
break;
}
else
LIST_FOREACH(port, p, s->ports)
if (p->type == SOCKET_USB_FUNCTION &&
- path_equal_or_files_same(p->path, value+skip)) {
+ path_equal_or_files_same(p->path, value+skip, 0)) {
socket_port_take_fd(p, fds, fd);
break;
}
old_state = s->state;
s->state = state;
- if (state != SWAP_ACTIVATING &&
- state != SWAP_ACTIVATING_SIGTERM &&
- state != SWAP_ACTIVATING_SIGKILL &&
- state != SWAP_ACTIVATING_DONE &&
- state != SWAP_DEACTIVATING &&
- state != SWAP_DEACTIVATING_SIGTERM &&
- state != SWAP_DEACTIVATING_SIGKILL) {
+ if (!IN_SET(state,
+ SWAP_ACTIVATING,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_DONE,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL)) {
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
swap_unwatch_control_pid(s);
s->control_command = NULL;
static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
int r;
+ KillOperation kop;
assert(s);
if (s->result == SWAP_SUCCESS)
s->result = f;
- r = unit_kill_context(
- UNIT(s),
- &s->kill_context,
- (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
- KILL_KILL : KILL_TERMINATE,
- -1,
- s->control_pid,
- false);
+ if (IN_SET(state, SWAP_ACTIVATING_SIGTERM, SWAP_DEACTIVATING_SIGTERM))
+ kop = KILL_TERMINATE;
+ else
+ kop = KILL_KILL;
+
+ r = unit_kill_context(UNIT(s), &s->kill_context, kop, -1, s->control_pid, false);
if (r < 0)
goto fail;
/* We cannot fulfill this request right now, try again later
* please! */
- if (s->state == SWAP_DEACTIVATING ||
- s->state == SWAP_DEACTIVATING_SIGTERM ||
- s->state == SWAP_DEACTIVATING_SIGKILL ||
- s->state == SWAP_ACTIVATING_SIGTERM ||
- s->state == SWAP_ACTIVATING_SIGKILL)
+ if (IN_SET(s->state,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL))
return -EAGAIN;
if (s->state == SWAP_ACTIVATING)
return 0;
- assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
+ assert(IN_SET(s->state, SWAP_DEAD, SWAP_FAILED));
if (detect_container() > 0)
return -EPERM;
assert(s);
- if (s->state == SWAP_DEACTIVATING ||
- s->state == SWAP_DEACTIVATING_SIGTERM ||
- s->state == SWAP_DEACTIVATING_SIGKILL ||
- s->state == SWAP_ACTIVATING_SIGTERM ||
- s->state == SWAP_ACTIVATING_SIGKILL)
+ if (IN_SET(s->state,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL))
return 0;
- assert(s->state == SWAP_ACTIVATING ||
- s->state == SWAP_ACTIVATING_DONE ||
- s->state == SWAP_ACTIVE);
+ assert(IN_SET(s->state, SWAP_ACTIVATING, SWAP_ACTIVATING_DONE, SWAP_ACTIVE));
if (detect_container() > 0)
return -EPERM;
struct udev_list_entry *item = NULL, *first = NULL;
_cleanup_free_ char *e = NULL;
const char *dn;
- Swap *s;
+ Unit *u;
int r = 0;
assert(m);
if (r < 0)
return r;
- s = hashmap_get(m->units, e);
- if (s)
- r = swap_set_devnode(s, dn);
+ u = manager_get_unit(m, e);
+ if (u)
+ r = swap_set_devnode(SWAP(u), dn);
first = udev_device_get_devlinks_list_entry(dev);
udev_list_entry_foreach(item, first) {
if (q < 0)
return q;
- s = hashmap_get(m->units, n);
- if (s) {
- q = swap_set_devnode(s, dn);
+ u = manager_get_unit(m, n);
+ if (u) {
+ q = swap_set_devnode(SWAP(u), dn);
if (q < 0)
r = q;
}
assert(t);
+ if (!UNIT(t)->default_dependencies)
+ return 0;
+
/* Imply ordering for requirement dependencies on target
* units. Note that when the user created a contradicting
* ordering manually we won't add anything in here to make
return r;
/* This is a new unit? Then let's add in some extras */
- if (u->load_state == UNIT_LOADED && u->default_dependencies) {
+ if (u->load_state == UNIT_LOADED) {
r = target_add_default_dependencies(t);
if (r < 0)
return r;
timer_enter_dead(t, TIMER_SUCCESS);
}
-static usec_t monotonic_to_boottime(usec_t t) {
- usec_t a, b;
-
- if (t <= 0)
- return 0;
-
- a = now(clock_boottime_or_monotonic());
- b = now(CLOCK_MONOTONIC);
-
- if (t + a > b)
- return t + a - b;
- else
- return 0;
-}
-
static void add_random(Timer *t, usec_t *v) {
char s[FORMAT_TIMESPAN_MAX];
usec_t add;
static void timer_enter_waiting(Timer *t, bool initial) {
bool found_monotonic = false, found_realtime = false;
- usec_t ts_realtime, ts_monotonic;
- usec_t base = 0;
bool leave_around = false;
+ triple_timestamp ts;
+ usec_t base = 0;
TimerValue *v;
Unit *trigger;
int r;
return;
}
- /* If we shall wake the system we use the boottime clock
- * rather than the monotonic clock. */
-
- ts_realtime = now(CLOCK_REALTIME);
- ts_monotonic = now(t->wake_system ? clock_boottime_or_monotonic() : CLOCK_MONOTONIC);
+ triple_timestamp_get(&ts);
t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
LIST_FOREACH(value, v, t->values) {
* to that. If we don't just start from
* now. */
- b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts_realtime;
+ b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts.realtime;
r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
if (r < 0)
found_realtime = true;
} else {
+
switch (v->base) {
case TIMER_ACTIVE:
if (state_translation_table[t->state] == UNIT_ACTIVE)
base = UNIT(t)->inactive_exit_timestamp.monotonic;
else
- base = ts_monotonic;
+ base = ts.monotonic;
break;
case TIMER_BOOT:
assert_not_reached("Unknown timer base");
}
- if (t->wake_system)
- base = monotonic_to_boottime(base);
-
- v->next_elapse = base + v->value;
+ v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value);
- if (!initial && v->next_elapse < ts_monotonic && IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
+ if (!initial &&
+ v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) &&
+ IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
/* This is a one time trigger, disable it now */
v->disabled = true;
continue;
add_random(t, &t->next_elapse_monotonic_or_boottime);
- left = t->next_elapse_monotonic_or_boottime > ts_monotonic ? t->next_elapse_monotonic_or_boottime - ts_monotonic : 0;
+ left = usec_sub_unsigned(t->next_elapse_monotonic_or_boottime, triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)));
log_unit_debug(UNIT(t), "Monotonic timer elapses in %s.", format_timespan(buf, sizeof(buf), left, 0));
if (t->monotonic_event_source) {
char *stamp_path;
};
+#define TIMER_MONOTONIC_CLOCK(t) ((t)->wake_system && clock_boottime_supported() ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC)
+
void timer_free_values(Timer *t);
extern const UnitVTable timer_vtable;
job_add_to_run_queue(j);
job_add_to_dbus_queue(j);
- job_start_timer(j);
+ job_start_timer(j, false);
job_shutdown_magic(j);
}
#include <errno.h>
#include <fcntl.h>
-#include <linux/dm-ioctl.h>
#include <linux/loop.h>
#include <string.h>
#include <sys/mount.h>
#include "escape.h"
#include "fd-util.h"
#include "fstab-util.h"
+#include "linux-3.13/dm-ioctl.h"
#include "list.h"
#include "mount-setup.h"
#include "path-util.h"
return 0;
}
+static bool nonunmountable_path(const char *path) {
+ return path_equal(path, "/")
+#ifndef HAVE_SPLIT_USR
+ || path_equal(path, "/usr")
+#endif
+ || path_startswith(path, "/run/initramfs");
+}
+
static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_error) {
MountPoint *m, *n;
int n_failed = 0;
* somehwere else via a bind mount. If we
* explicitly remount the super block of that
* alias read-only we hence should be
- * relatively safe regarding keeping the fs we
- * can otherwise not see dirty. */
+ * relatively safe regarding keeping dirty an fs
+ * we cannot otherwise see. */
log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
- (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
+ if (mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options) < 0) {
+ if (log_error)
+ log_notice_errno(errno, "Failed to remount '%s' read-only: %m", m->path);
+ if (nonunmountable_path(m->path))
+ n_failed++;
+ }
}
/* Skip / and /usr since we cannot unmount that
* anyway, since we are running from it. They have
* already been remounted ro. */
- if (path_equal(m->path, "/")
-#ifndef HAVE_SPLIT_USR
- || path_equal(m->path, "/usr")
-#endif
- || path_startswith(m->path, "/run/initramfs")
- )
+ if (nonunmountable_path(m->path))
continue;
/* Trying to umount. We don't force here since we rely
*changed = true;
mount_point_free(head, m);
- } else if (log_error) {
- log_warning_errno(errno, "Could not unmount %s: %m", m->path);
+ } else {
+ if (log_error)
+ log_warning_errno(errno, "Could not unmount %s: %m", m->path);
n_failed++;
}
}
/* umount one more time with logging enabled */
r = mount_points_list_umount(&mp_list_head, &umount_changed, true);
- if (r <= 0)
- goto end;
end:
mount_points_list_free(&mp_list_head);
u->on_failure_job_mode = JOB_REPLACE;
u->cgroup_inotify_wd = -1;
u->job_timeout = USEC_INFINITY;
+ u->job_running_timeout = USEC_INFINITY;
u->ref_uid = UID_INVALID;
u->ref_gid = GID_INVALID;
u->cpu_usage_last = NSEC_INFINITY;
"%s\tPerpetual: %s\n"
"%s\tSlice: %s\n"
"%s\tCGroup: %s\n"
- "%s\tCGroup realized: %s\n"
- "%s\tCGroup mask: 0x%x\n"
- "%s\tCGroup members mask: 0x%x\n",
+ "%s\tCGroup realized: %s\n",
prefix, u->id,
prefix, unit_description(u),
prefix, strna(u->instance),
prefix, yes_no(u->perpetual),
prefix, strna(unit_slice_name(u)),
prefix, strna(u->cgroup_path),
- prefix, yes_no(u->cgroup_realized),
- prefix, u->cgroup_realized_mask,
- prefix, u->cgroup_members_mask);
+ prefix, yes_no(u->cgroup_realized));
+
+ if (u->cgroup_realized_mask != 0) {
+ _cleanup_free_ char *s = NULL;
+ (void) cg_mask_to_string(u->cgroup_realized_mask, &s);
+ fprintf(f, "%s\tCGroup mask: %s\n", prefix, strnull(s));
+ }
+ if (u->cgroup_members_mask != 0) {
+ _cleanup_free_ char *s = NULL;
+ (void) cg_mask_to_string(u->cgroup_members_mask, &s);
+ fprintf(f, "%s\tCGroup members mask: %s\n", prefix, strnull(s));
+ }
SET_FOREACH(t, u->names, i)
fprintf(f, "%s\tName: %s\n", prefix, t);
goto fail;
}
+ if (u->job_running_timeout != USEC_INFINITY && u->job_running_timeout > u->job_timeout)
+ log_unit_warning(u, "JobRunningTimeoutSec= is greater than JobTimeoutSec=, it has no effect.");
+
unit_update_cgroup_members_masks(u);
}
* possible, which means we should avoid the low-level unit
* name. */
log_struct(LOG_INFO,
- mid,
- LOG_UNIT_ID(u),
LOG_MESSAGE("%s", buf),
+ LOG_UNIT_ID(u),
+ mid,
NULL);
}
if (other->job)
continue;
+ if (!other->coldplugged)
+ /* We might yet create a job for the other unit… */
+ continue;
+
if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
continue;
return 0;
}
+ old_owner = isempty(old_owner) ? NULL : old_owner;
+ new_owner = isempty(new_owner) ? NULL : new_owner;
+
if (UNIT_VTABLE(u)->bus_name_owner_change)
UNIT_VTABLE(u)->bus_name_owner_change(u, name, old_owner, new_owner);
return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
}
+static int unit_serialize_cgroup_mask(FILE *f, const char *key, CGroupMask mask) {
+ _cleanup_free_ char *s = NULL;
+ int r = 0;
+
+ assert(f);
+ assert(key);
+
+ if (mask != 0) {
+ r = cg_mask_to_string(mask, &s);
+ if (r >= 0) {
+ fputs(key, f);
+ fputc('=', f);
+ fputs(s, f);
+ fputc('\n', f);
+ }
+ }
+ return r;
+}
+
int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
int r;
if (u->cgroup_path)
unit_serialize_item(u, f, "cgroup", u->cgroup_path);
unit_serialize_item(u, f, "cgroup-realized", yes_no(u->cgroup_realized));
+ (void) unit_serialize_cgroup_mask(f, "cgroup-realized-mask", u->cgroup_realized_mask);
+ (void) unit_serialize_cgroup_mask(f, "cgroup-enabled-mask", u->cgroup_enabled_mask);
if (uid_is_valid(u->ref_uid))
unit_serialize_item_format(u, f, "ref-uid", UID_FMT, u->ref_uid);
continue;
+ } else if (streq(l, "cgroup-realized-mask")) {
+
+ r = cg_mask_from_string(v, &u->cgroup_realized_mask);
+ if (r < 0)
+ log_unit_debug(u, "Failed to parse cgroup-realized-mask %s, ignoring.", v);
+ continue;
+
+ } else if (streq(l, "cgroup-enabled-mask")) {
+
+ r = cg_mask_from_string(v, &u->cgroup_enabled_mask);
+ if (r < 0)
+ log_unit_debug(u, "Failed to parse cgroup-enabled-mask %s, ignoring.", v);
+ continue;
+
} else if (streq(l, "ref-uid")) {
uid_t uid;
/* Job timeout and action to take */
usec_t job_timeout;
+ usec_t job_running_timeout;
EmergencyAction job_timeout_action;
char *job_timeout_reboot_arg;
};
return config_parse_many_nulstr(PKGSYSCONFDIR "/coredump.conf",
- CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
- "Coredump\0",
- config_item_table_lookup, items,
- false, NULL);
+ CONF_PATHS_NULSTR("systemd/coredump.conf.d"),
+ "Coredump\0",
+ config_item_table_lookup, items,
+ false, NULL);
}
static inline uint64_t storage_size_max(void) {
if (journald_crash) {
/* We cannot log to the journal, so just print the MESSAGE.
* The target was set previously to something safe. */
- log_struct(LOG_ERR, core_message, NULL);
+ log_dispatch(LOG_ERR, 0, core_message);
return 0;
}
- if (core_message)
- IOVEC_SET_STRING(iovec[n_iovec++], core_message);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_message);
if (truncated)
IOVEC_SET_STRING(iovec[n_iovec++], "COREDUMP_TRUNCATED=1");
log_error_errno(r, "Failed to parse journal entry on stdin: %m");
goto finish;
}
- if (r == 1)
+ if (r == 1 || /* complete entry */
+ journal_importer_eof(&importer)) /* end of data */
break;
}
--- /dev/null
+systemd_coredump_sources = files('''
+ coredump.c
+ coredump-vacuum.c
+ coredump-vacuum.h
+'''.split())
+
+if conf.get('HAVE_ELFUTILS', false)
+ systemd_coredump_sources += files(['stacktrace.c',
+ 'stacktrace.h'])
+endif
+
+coredumpctl_sources = files('coredumpctl.c')
+
+install_data('coredump.conf',
+ install_dir : pkgsysconfdir)
+
+tests += [
+ [['src/coredump/test-coredump-vacuum.c',
+ 'src/coredump/coredump-vacuum.c',
+ 'src/coredump/coredump-vacuum.h'],
+ [],
+ [],
+ 'ENABLE_COREDUMP', 'manual'],
+]
arg_type = CRYPT_PLAIN;
else if ((val = startswith(option, "timeout="))) {
- r = parse_sec(val, &arg_timeout);
+ r = parse_sec_fix_0(val, &arg_timeout);
if (r < 0) {
log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
return 0;
return k;
}
-static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *toppath, const char *drop) {
+static int enumerate_dir_d(
+ OrderedHashmap *top,
+ OrderedHashmap *bottom,
+ OrderedHashmap *drops,
+ const char *toppath, const char *drop) {
+
_cleanup_free_ char *unit = NULL;
_cleanup_free_ char *path = NULL;
_cleanup_strv_free_ char **list = NULL;
if (r < 0)
return log_error_errno(r, "Failed to enumerate %s: %m", path);
+ strv_sort(list);
+
STRV_FOREACH(file, list) {
- Hashmap *h;
+ OrderedHashmap *h;
int k;
char *p;
char *d;
d = p + strlen(toppath) + 1;
log_debug("Adding at top: %s %s %s", d, special_glyph(ARROW), p);
- k = hashmap_put(top, d, p);
+ k = ordered_hashmap_put(top, d, p);
if (k >= 0) {
p = strdup(p);
if (!p)
}
log_debug("Adding at bottom: %s %s %s", d, special_glyph(ARROW), p);
- free(hashmap_remove(bottom, d));
- k = hashmap_put(bottom, d, p);
+ free(ordered_hashmap_remove(bottom, d));
+ k = ordered_hashmap_put(bottom, d, p);
if (k < 0) {
free(p);
return k;
}
- h = hashmap_get(drops, unit);
+ h = ordered_hashmap_get(drops, unit);
if (!h) {
- h = hashmap_new(&string_hash_ops);
+ h = ordered_hashmap_new(&string_hash_ops);
if (!h)
return -ENOMEM;
- hashmap_put(drops, unit, h);
+ ordered_hashmap_put(drops, unit, h);
unit = strdup(unit);
if (!unit)
return -ENOMEM;
log_debug("Adding to drops: %s %s %s %s %s",
unit, special_glyph(ARROW), basename(p), special_glyph(ARROW), p);
- k = hashmap_put(h, basename(p), p);
+ k = ordered_hashmap_put(h, basename(p), p);
if (k < 0) {
free(p);
if (k != -EEXIST)
return 0;
}
-static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *path, bool dropins) {
- _cleanup_closedir_ DIR *d;
+static int enumerate_dir(
+ OrderedHashmap *top,
+ OrderedHashmap *bottom,
+ OrderedHashmap *drops,
+ const char *path, bool dropins) {
+
+ _cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
+ _cleanup_strv_free_ char **files = NULL, **dirs = NULL;
+ size_t n_files = 0, allocated_files = 0, n_dirs = 0, allocated_dirs = 0;
+ char **t;
+ int r;
assert(top);
assert(bottom);
}
FOREACH_DIRENT_ALL(de, d, return -errno) {
- int k;
- char *p;
-
dirent_ensure_type(d, de);
- if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d"))
- enumerate_dir_d(top, bottom, drops, path, de->d_name);
+ if (dropins && de->d_type == DT_DIR && endswith(de->d_name, ".d")) {
+ if (!GREEDY_REALLOC0(dirs, allocated_dirs, n_dirs + 2))
+ return -ENOMEM;
+
+ dirs[n_dirs] = strdup(de->d_name);
+ if (!dirs[n_dirs])
+ return -ENOMEM;
+ n_dirs ++;
+ }
if (!dirent_is_file(de))
continue;
- p = strjoin(path, "/", de->d_name);
+ if (!GREEDY_REALLOC0(files, allocated_files, n_files + 2))
+ return -ENOMEM;
+
+ files[n_files] = strdup(de->d_name);
+ if (!files[n_files])
+ return -ENOMEM;
+ n_files ++;
+ }
+
+ strv_sort(dirs);
+ strv_sort(files);
+
+ STRV_FOREACH(t, dirs) {
+ r = enumerate_dir_d(top, bottom, drops, path, *t);
+ if (r < 0)
+ return r;
+ }
+
+ STRV_FOREACH(t, files) {
+ _cleanup_free_ char *p = NULL;
+
+ p = strjoin(path, "/", *t);
if (!p)
return -ENOMEM;
log_debug("Adding at top: %s %s %s", basename(p), special_glyph(ARROW), p);
- k = hashmap_put(top, basename(p), p);
- if (k >= 0) {
+ r = ordered_hashmap_put(top, basename(p), p);
+ if (r >= 0) {
p = strdup(p);
if (!p)
return -ENOMEM;
- } else if (k != -EEXIST) {
- free(p);
- return k;
- }
+ } else if (r != -EEXIST)
+ return r;
log_debug("Adding at bottom: %s %s %s", basename(p), special_glyph(ARROW), p);
- free(hashmap_remove(bottom, basename(p)));
- k = hashmap_put(bottom, basename(p), p);
- if (k < 0) {
- free(p);
- return k;
- }
+ free(ordered_hashmap_remove(bottom, basename(p)));
+ r = ordered_hashmap_put(bottom, basename(p), p);
+ if (r < 0)
+ return r;
+ p = NULL;
}
+
return 0;
}
static int process_suffix(const char *suffix, const char *onlyprefix) {
const char *p;
char *f;
- Hashmap *top, *bottom, *drops;
- Hashmap *h;
+ OrderedHashmap *top, *bottom, *drops;
+ OrderedHashmap *h;
char *key;
int r = 0, k;
Iterator i, j;
dropins = nulstr_contains(have_dropins, suffix);
- top = hashmap_new(&string_hash_ops);
- bottom = hashmap_new(&string_hash_ops);
- drops = hashmap_new(&string_hash_ops);
+ top = ordered_hashmap_new(&string_hash_ops);
+ bottom = ordered_hashmap_new(&string_hash_ops);
+ drops = ordered_hashmap_new(&string_hash_ops);
if (!top || !bottom || !drops) {
r = -ENOMEM;
goto finish;
r = k;
}
- HASHMAP_FOREACH_KEY(f, key, top, i) {
+ ORDERED_HASHMAP_FOREACH_KEY(f, key, top, i) {
char *o;
- o = hashmap_get(bottom, key);
+ o = ordered_hashmap_get(bottom, key);
assert(o);
if (!onlyprefix || startswith(o, onlyprefix)) {
}
}
- h = hashmap_get(drops, key);
+ h = ordered_hashmap_get(drops, key);
if (h)
- HASHMAP_FOREACH(o, h, j)
+ ORDERED_HASHMAP_FOREACH(o, h, j)
if (!onlyprefix || startswith(o, onlyprefix))
n_found += notify_override_extended(f, o);
}
finish:
- hashmap_free_free(top);
- hashmap_free_free(bottom);
+ ordered_hashmap_free_free(top);
+ ordered_hashmap_free_free(bottom);
- HASHMAP_FOREACH_KEY(h, key, drops, i) {
- hashmap_free_free(hashmap_remove(drops, key));
- hashmap_remove(drops, key);
+ ORDERED_HASHMAP_FOREACH_KEY(h, key, drops, i) {
+ ordered_hashmap_free_free(ordered_hashmap_remove(drops, key));
+ ordered_hashmap_remove(drops, key);
free(key);
}
- hashmap_free(drops);
+ ordered_hashmap_free(drops);
return r < 0 ? r : n_found;
}
t = strchr(*i, '=');
assert(t);
- q = shell_maybe_quote(t + 1);
+ q = shell_maybe_quote(t + 1, ESCAPE_BACKSLASH);
if (!q)
return log_oom();
if (!arg_root_password)
return 0;
- r = dev_urandom(raw, 16);
+ r = acquire_random_bytes(raw, 16, true);
if (r < 0)
return log_error_errno(r, "Failed to get salt: %m");
#include "alloc-util.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "fileio.h"
#include "fstab-util.h"
#include "generator.h"
}
static int write_timeout(FILE *f, const char *where, const char *opts,
- const char *filter, const char *variable) {
+ const char *filter, const char *variable) {
_cleanup_free_ char *timeout = NULL;
char timespan[FORMAT_TIMESPAN_MAX];
usec_t u;
if (r == 0)
return 0;
- r = parse_sec(timeout, &u);
+ r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
return 0;
const char *dest,
const char *what,
const char *where,
+ const char *original_where,
const char *fstype,
const char *opts,
int passno,
"Documentation=man:fstab(5) man:systemd-fstab-generator(8)\n",
source);
- if (!noauto && !nofail && !automount)
+ if (STRPTR_IN_SET(fstype, "nfs", "nfs4") && !automount &&
+ fstab_test_yes_no_option(opts, "bg\0" "fg\0")) {
+ /* The default retry timeout that mount.nfs uses for 'bg' mounts
+ * is 10000 minutes, where as it uses 2 minutes for 'fg' mounts.
+ * As we are making 'bg' mounts look like an 'fg' mount to
+ * mount.nfs (so systemd can manage the job-control aspects of 'bg'),
+ * we need to explicitly preserve that default, and also ensure
+ * the systemd mount-timeout doesn't interfere.
+ * By placing these options first, they can be over-ridden by
+ * settings in /etc/fstab. */
+ opts = strjoina("x-systemd.mount-timeout=infinity,retry=10000,", opts, ",fg");
+ nofail = true;
+ }
+
+ if (!nofail && !automount)
fprintf(f, "Before=%s\n", post);
if (!automount && opts) {
return r;
}
- fprintf(f,
- "\n"
- "[Mount]\n"
- "Where=%s\n",
- where);
+ fprintf(f, "\n[Mount]\n");
+ if (original_where)
+ fprintf(f, "# Canonicalized from %s\n", original_where);
+ fprintf(f, "Where=%s\n", where);
r = write_what(f, what);
if (r < 0)
if (r < 0)
return r;
+ r = generator_write_device_deps(dest, what, where, opts);
+ if (r < 0)
+ return r;
+
r = write_mount_timeout(f, where, opts);
if (r < 0)
return r;
}
while ((me = getmntent(f))) {
- _cleanup_free_ char *where = NULL, *what = NULL;
+ _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
bool noauto, nofail;
int k;
if (!where)
return log_oom();
- if (is_path(where))
+ if (is_path(where)) {
path_kill_slashes(where);
+ /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
+ * mount units, but causes problems since it historically worked to have symlinks in e.g.
+ * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
+ * where a symlink refers to another mount target; this works assuming the sub-mountpoint
+ * target is the final directory.
+ */
+ r = chase_symlinks(where, initrd ? "/sysroot" : NULL,
+ CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
+ &canonical_where);
+ if (r < 0)
+ /* In this case for now we continue on as if it wasn't a symlink */
+ log_warning_errno(r, "Failed to read symlink target for %s: %m", where);
+ else {
+ if (streq(canonical_where, where))
+ canonical_where = mfree(canonical_where);
+ else
+ log_debug("Canonicalized what=%s where=%s to %s",
+ what, where, canonical_where);
+ }
+ }
noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
k = add_mount(arg_dest,
what,
- where,
+ canonical_where ?: where,
+ canonical_where ? where: NULL,
me->mnt_type,
me->mnt_opts,
me->mnt_passno,
return add_mount(arg_dest,
what,
"/sysroot",
+ NULL,
arg_root_fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
return add_mount(arg_dest,
what,
"/sysroot/usr",
+ NULL,
arg_usr_fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
return add_mount(arg_dest_late,
"tmpfs",
"/var",
+ NULL,
"tmpfs",
"mode=0755",
0,
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <blkid/blkid.h>
+#include <blkid.h>
#include <stdlib.h>
#include <sys/statfs.h>
#include <unistd.h>
assert(path);
+ /* Disable the swap auto logic if at least one swap is defined in /etc/fstab, see #6192. */
+ r = fstab_has_fstype("swap");
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse fstab: %m");
+ if (r > 0) {
+ log_debug("swap specified in fstab, ignoring.");
+ return 0;
+ }
+
log_debug("Adding swap: %s", path);
r = unit_name_from_path(path, ".swap", &name);
esp = access("/efi/", F_OK) >= 0 ? "/efi" : "/boot";
/* We create an .automount which is not overridden by the .mount from the fstab generator. */
- if (fstab_is_mount_point(esp)) {
+ r = fstab_is_mount_point(esp);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse fstab: %m");
+ if (r > 0) {
log_debug("%s specified in fstab, ignoring.", esp);
return 0;
}
--- /dev/null
+if conf.get('ENABLE_HOSTNAMED', false)
+ install_data('org.freedesktop.hostname1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.hostname1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.hostname1.policy',
+ input : 'org.freedesktop.hostname1.policy.in',
+ output : 'org.freedesktop.hostname1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
#include "hwdb-util.h"
#include "label.h"
#include "mkdir.h"
+#include "path-util.h"
#include "selinux-util.h"
#include "strbuf.h"
#include "string-util.h"
int64_t size;
struct trie_header_f h = {
.signature = HWDB_SIG,
- .tool_version = htole64(atoi(VERSION)),
+ .tool_version = htole64(atoi(PACKAGE_VERSION)),
.header_size = htole64(sizeof(struct trie_header_f)),
.node_size = htole64(sizeof(struct trie_node_f)),
.child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
log_debug("strings dedup'ed: %8zu bytes (%8zu)",
trie->strings->dedup_len, trie->strings->dedup_count);
- hwdb_bin = strjoin(arg_root, "/", arg_hwdb_bin_dir, "/hwdb.bin");
+ hwdb_bin = path_join(arg_root, arg_hwdb_bin_dir, "hwdb.bin");
if (!hwdb_bin)
return -ENOMEM;
}
if (l == 0) {
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
- log_error("Premature end of file: %m");
+ log_error("Premature end of file.");
r = -EIO;
goto finish;
}
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size);
if (r < 0) {
- log_error("Failed to detect file compression: %m");
+ log_error_errno(r, "Failed to detect file compression: %m");
goto finish;
}
if (r == 0) /* Need more data */
}
if (l == 0) {
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
- log_error("Premature end of file: %m");
+ log_error("Premature end of file.");
r = -EIO;
goto finish;
}
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size);
if (r < 0) {
- log_error("Failed to detect file compression: %m");
+ log_error_errno(r, "Failed to detect file compression: %m");
goto finish;
}
if (r == 0) /* Need more data */
--- /dev/null
+systemd_importd_sources = files('''
+ importd.c
+'''.split())
+
+systemd_pull_sources = files('''
+ pull.c
+ pull-raw.c
+ pull-raw.h
+ pull-tar.c
+ pull-tar.h
+ pull-job.c
+ pull-job.h
+ pull-common.c
+ pull-common.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+ curl-util.c
+ curl-util.h
+ qcow2-util.c
+ qcow2-util.h
+'''.split())
+
+systemd_import_sources = files('''
+ import.c
+ import-raw.c
+ import-raw.h
+ import-tar.c
+ import-tar.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+ qcow2-util.c
+ qcow2-util.h
+'''.split())
+
+systemd_export_sources = files('''
+ export.c
+ export-tar.c
+ export-tar.h
+ export-raw.c
+ export-raw.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+'''.split())
+
+if conf.get('ENABLE_IMPORTD', false)
+ install_data('org.freedesktop.import1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.import1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.import1.policy',
+ input : 'org.freedesktop.import1.policy.in',
+ output : 'org.freedesktop.import1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+
+ install_data('import-pubring.gpg',
+ install_dir : rootlibexecdir)
+ # TODO: shouldn't this be in pkgdatadir?
+endif
+
+tests += [
+ [['src/import/test-qcow2.c',
+ 'src/import/qcow2-util.c',
+ 'src/import/qcow2-util.h'],
+ [libshared],
+ [libz],
+ 'HAVE_ZLIB', 'manual'],
+]
_cleanup_(pull_job_unrefp) PullJob *checksum_job = NULL, *signature_job = NULL;
int r;
+ const char *chksums = NULL;
assert(ret_checksum_job);
assert(ret_signature_job);
assert(glue);
if (verify != IMPORT_VERIFY_NO) {
- _cleanup_free_ char *checksum_url = NULL;
+ _cleanup_free_ char *checksum_url = NULL, *fn = NULL;
- /* Queue job for the SHA256SUMS file for the image */
- r = import_url_change_last_component(url, "SHA256SUMS", &checksum_url);
+ /* Queue jobs for the checksum file for the image. */
+ r = import_url_last_component(url, &fn);
+ if (r < 0)
+ return r;
+
+ chksums = strjoina(fn, ".sha256");
+
+ r = import_url_change_last_component(url, chksums, &checksum_url);
if (r < 0)
return r;
line,
strlen(line));
+ if (!p) {
+ line = strjoina(job->checksum, " ", fn, "\n");
+
+ p = memmem(checksum_job->payload,
+ checksum_job->payload_size,
+ line,
+ strlen(line));
+ }
+
if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) {
log_error("DOWNLOAD INVALID: Checksum of %s file did not checkout, file has been tampered with.", fn);
return -EBADMSG;
PullJob *signature_job) {
_cleanup_close_pair_ int gpg_pipe[2] = { -1, -1 };
- _cleanup_free_ char *fn = NULL;
_cleanup_close_ int sig_file = -1;
char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX";
_cleanup_(sigkill_waitp) pid_t pid = 0;
if (!signature_job)
return 0;
+ if (checksum_job->style == VERIFICATION_PER_FILE)
+ signature_job = checksum_job;
+
assert(signature_job->state == PULL_JOB_DONE);
if (!signature_job->payload || signature_job->payload_size <= 0) {
cmd[k++] = "--keyring=" VENDOR_KEYRING_PATH;
cmd[k++] = "--verify";
- cmd[k++] = sig_file_path;
- cmd[k++] = "-";
- cmd[k++] = NULL;
+ if (checksum_job->style == VERIFICATION_PER_DIRECTORY) {
+ cmd[k++] = sig_file_path;
+ cmd[k++] = "-";
+ cmd[k++] = NULL;
+ }
stdio_unset_cloexec();
#include "alloc-util.h"
#include "fd-util.h"
#include "hexdecoct.h"
+#include "import-util.h"
#include "io-util.h"
#include "machine-pool.h"
#include "parse-util.h"
+#include "pull-common.h"
#include "pull-job.h"
#include "string-util.h"
#include "strv.h"
j->on_finished(j);
}
+static int pull_job_restart(PullJob *j) {
+ int r;
+ char *chksum_url = NULL;
+
+ r = import_url_change_last_component(j->url, "SHA256SUMS", &chksum_url);
+ if (r < 0)
+ return r;
+
+ free(j->url);
+ j->url = chksum_url;
+ j->state = PULL_JOB_INIT;
+ j->payload = mfree(j->payload);
+ j->payload_size = 0;
+ j->payload_allocated = 0;
+ j->written_compressed = 0;
+ j->written_uncompressed = 0;
+ j->written_since_last_grow = 0;
+
+ r = pull_job_begin(j);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
PullJob *j = NULL;
CURLcode code;
r = 0;
goto finish;
} else if (status >= 300) {
+ if (status == 404 && j->style == VERIFICATION_PER_FILE) {
+
+ /* retry pull job with SHA256SUMS file */
+ r = pull_job_restart(j);
+ if (r < 0)
+ goto finish;
+
+ code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
+ if (code != CURLE_OK) {
+ log_error("Failed to retrieve response code: %s", curl_easy_strerror(code));
+ r = -EIO;
+ goto finish;
+ }
+
+ if (status == 0) {
+ j->style = VERIFICATION_PER_DIRECTORY;
+ return;
+ }
+ }
+
log_error("HTTP request to %s failed with code %li.", j->url, status);
r = -EIO;
goto finish;
j->glue = glue;
j->content_length = (uint64_t) -1;
j->start_usec = now(CLOCK_MONOTONIC);
- j->compressed_max = j->uncompressed_max = 8LLU * 1024LLU * 1024LLU * 1024LLU; /* 8GB */
+ j->compressed_max = j->uncompressed_max = 64LLU * 1024LLU * 1024LLU * 1024LLU; /* 64GB safety limit */
+ j->style = VERIFICATION_STYLE_UNSET;
j->url = strdup(url);
if (!j->url)
_PULL_JOB_STATE_INVALID = -1,
} PullJobState;
+typedef enum VerificationStyle {
+ VERIFICATION_STYLE_UNSET,
+ VERIFICATION_PER_FILE, /* SuSE-style ".sha256" files with inline signature */
+ VERIFICATION_PER_DIRECTORY, /* Ubuntu-style SHA256SUM files with detach SHA256SUM.gpg signatures */
+} VerificationStyle;
+
#define PULL_JOB_IS_COMPLETE(j) (IN_SET((j)->state, PULL_JOB_DONE, PULL_JOB_FAILED))
struct PullJob {
bool grow_machine_directory;
uint64_t written_since_last_grow;
+
+ VerificationStyle style;
};
int pull_job_new(PullJob **job, const char *url, CurlGlue *glue, void *userdata);
assert(suffix);
assert(path);
- /* Regenerate final name for this auxiliary file, we might know the etag of the raw file now, and we shoud
+ /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and we should
* incorporate it in the file name if we can */
*path = mfree(*path);
r = raw_pull_determine_path(i, suffix, path);
} else if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
- } else if (j->error != 0) {
+ } else if (j->error != 0 && j != i->signature_job) {
if (j == i->checksum_job)
log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)");
- else if (j == i->signature_job)
- log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
else
log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)");
if (!raw_pull_is_done(i))
return;
+ if (i->signature_job && i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
+ log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
+
+ r = i->signature_job->error;
+ goto finish;
+ }
+
if (i->roothash_job)
i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
if (i->settings_job)
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
if (r < 0) {
- log_error_errno(r, "Failed to move RAW file into place: %m");
+ log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
goto finish;
}
const char *extra,
char **temp_path) {
- _cleanup_free_ char *p = NULL;
int r;
assert(i);
if (i->checksum_job) {
i->checksum_job->on_progress = raw_pull_job_on_progress;
+ i->checksum_job->style = VERIFICATION_PER_FILE;
r = pull_job_begin(i->checksum_job);
if (r < 0)
free(i->settings_path);
free(i->image_root);
free(i->local);
+
return mfree(i);
}
if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
- } else if (j->error != 0) {
+ } else if (j->error != 0 && j != i->signature_job) {
if (j == i->checksum_job)
log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)");
- else if (j == i->signature_job)
- log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
else
log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)");
if (!tar_pull_is_done(i))
return;
+ if (i->signature_job && i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
+ log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
+
+ r = i->signature_job->error;
+ goto finish;
+ }
+
i->tar_job->disk_fd = safe_close(i->tar_job->disk_fd);
if (i->settings_job)
i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
if (r < 0) {
- log_error_errno(r, "Failed to rename to final image name: %m");
+ log_error_errno(r, "Failed to rename to final image name to %s: %m", i->final_path);
goto finish;
}
if (i->settings_job &&
i->settings_job->error == 0) {
- assert(i->settings_temp_path);
- assert(i->settings_path);
-
- /* Also move the settings file into place, if it exist. Note that we do so only if we also
+ /* Also move the settings file into place, if it exists. Note that we do so only if we also
* moved the tar file in place, to keep things strictly in sync. */
+ assert(i->settings_temp_path);
+ /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and
+ * we should incorporate it in the file name if we can */
i->settings_path = mfree(i->settings_path);
+
r = tar_pull_determine_path(i, ".nspawn", &i->settings_path);
if (r < 0)
goto finish;
r = rename_noreplace(AT_FDCWD, i->settings_temp_path, AT_FDCWD, i->settings_path);
if (r < 0) {
- log_error_errno(r, "Failed to rename settings file: %m");
+ log_error_errno(r, "Failed to rename settings file to %s: %m", i->settings_path);
goto finish;
}
if (i->checksum_job) {
i->checksum_job->on_progress = tar_pull_job_on_progress;
+ i->checksum_job->style = VERIFICATION_PER_FILE;
r = pull_job_begin(i->checksum_job);
if (r < 0)
/**
* Initialize zero-filled source with given values. On success, takes
- * ownerhship of fd and writer, otherwise does not touch them.
+ * ownership of fd, name, and writer, otherwise does not touch them.
*/
RemoteSource* source_new(int fd, bool passive_fd, char *name, Writer *writer) {
log_warning("Failed to process data for connection %p", connection);
if (r == -E2BIG)
return mhd_respondf(connection,
- r, MHD_HTTP_REQUEST_ENTITY_TOO_LARGE,
+ r, MHD_HTTP_PAYLOAD_TOO_LARGE,
"Entry is too large, maximum is " STRINGIFY(DATA_SIZE_MAX) " bytes.");
else
return mhd_respondf(connection,
{}};
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-remote.conf",
- CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
- "Remote\0", config_item_table_lookup, items,
- false, NULL);
+ CONF_PATHS_NULSTR("systemd/journal-remote.conf.d"),
+ "Remote\0", config_item_table_lookup, items,
+ false, NULL);
}
static void help(void) {
return;
after = now(CLOCK_MONOTONIC);
- elapsed_time = usec_sub(after, u->watchdog_timestamp);
+ elapsed_time = usec_sub_unsigned(after, u->watchdog_timestamp);
if (elapsed_time > u->watchdog_usec / 2) {
log_debug("Update watchdog timer");
sd_notify(false, "WATCHDOG=1");
{}};
return config_parse_many_nulstr(PKGSYSCONFDIR "/journal-upload.conf",
- CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
- "Upload\0", config_item_table_lookup, items,
- false, NULL);
+ CONF_PATHS_NULSTR("systemd/journal-upload.conf.d"),
+ "Upload\0", config_item_table_lookup, items,
+ false, NULL);
}
static void help(void) {
-#!/usr/bin/python3
+#!/usr/bin/env python3
import sys
import argparse
--- /dev/null
+systemd_journal_upload_sources = files('''
+ journal-upload.h
+ journal-upload.c
+ journal-upload-journal.c
+'''.split())
+
+systemd_journal_remote_sources = files('''
+ journal-remote-parse.h
+ journal-remote-parse.c
+ journal-remote-write.h
+ journal-remote-write.c
+ journal-remote.h
+ journal-remote.c
+ microhttpd-util.h
+ microhttpd-util.c
+'''.split())
+
+systemd_journal_gatewayd_sources = files('''
+ journal-gatewayd.c
+ microhttpd-util.h
+ microhttpd-util.c
+'''.split())
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_LIBCURL', false)
+ journal_upload_conf = configure_file(
+ input : 'journal-upload.conf.in',
+ output : 'journal-upload.conf',
+ configuration : substs)
+ install_data(journal_upload_conf,
+ install_dir : pkgsysconfdir)
+endif
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_MICROHTTPD', false)
+ journal_remote_conf = configure_file(
+ input : 'journal-remote.conf.in',
+ output : 'journal-remote.conf',
+ configuration : substs)
+ install_data(journal_remote_conf,
+ install_dir : pkgsysconfdir)
+
+ install_data('browse.html',
+ install_dir : join_paths(pkgdatadir, 'gatewayd'))
+
+ meson.add_install_script('sh', '-c',
+ mkdir_p.format('/var/log/journal/remote'))
+ meson.add_install_script('sh', '-c',
+ 'chown 0:0 $DESTDIR/var/log/journal/remote &&
+ chmod 755 $DESTDIR/var/log/journal/remote || :')
+endif
errno = -error;
fmt = strjoina(format, "\n");
va_start(ap, format);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
r = vasprintf(&m, fmt, ap);
+#pragma GCC diagnostic pop
va_end(ap);
if (r < 0)
# define MHD_HTTP_NOT_ACCEPTABLE MHD_HTTP_METHOD_NOT_ACCEPTABLE
#endif
+/* Renamed in µhttpd 0.9.51 */
+#ifndef MHD_USE_PIPE_FOR_SHUTDOWN
+# define MHD_USE_ITC MHD_USE_PIPE_FOR_SHUTDOWN
+#endif
+
/* Renamed in µhttpd 0.9.52 */
#ifndef MHD_USE_EPOLL_LINUX_ONLY
# define MHD_USE_EPOLL MHD_USE_EPOLL_LINUX_ONLY
#endif
-/* Renamed in µhttpd 0.9.51 */
-#ifndef MHD_USE_PIPE_FOR_SHUTDOWN
-# define MHD_USE_ITC MHD_USE_PIPE_FOR_SHUTDOWN
+/* Both the old and new names are defines, check for the new one. */
+
+/* Renamed in µhttpd 0.9.53 */
+#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE
+# define MHD_HTTP_PAYLOAD_TOO_LARGE MHD_HTTP_REQUEST_ENTITY_TOO_LARGE
#endif
#if MHD_VERSION < 0x00094203
--- /dev/null
+BEGIN{
+ print "const char *audit_type_to_string(int type) {\n\tswitch(type) {"
+}
+{
+ printf " case AUDIT_%s: return \"%s\";\n", $1, $1
+}
+END{
+ print " default: return NULL;\n\t}\n}\n"
+}
#define RND_GEN_Q 0x02
#define RND_GEN_X 0x03
+#pragma GCC diagnostic ignored "-Wpointer-arith"
+/* TODO: remove void* arithmetic and this work-around */
+
/******************************************************************************/
static void mpi_export(void *buf, size_t buflen, const gcry_mpi_t x) {
--- /dev/null
+#!/bin/sh -eu
+
+cpp="$1"
+shift
+
+includes=""
+for i in "$@"; do
+ includes="$includes -include $i"
+done
+
+$cpp -dM $includes - </dev/null | \
+ grep -vE 'AUDIT_.*(FIRST|LAST)_' | \
+ sed -r -n 's/^#define\s+AUDIT_(\w+)\s+([0-9]{4})\s*$$/\1\t\2/p' | \
+ sort -k2
f->offline_state = OFFLINE_JOINED;
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
return -EIO;
return 0;
}
}
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
return -EIO;
switch (f->header->state) {
journal_file_set_offline(f, true);
- if (f->mmap && f->fd >= 0)
- mmap_cache_close_fd(f->mmap, f->fd);
+ if (f->mmap && f->cache_fd)
+ mmap_cache_free_fd(f->mmap, f->cache_fd);
if (f->fd >= 0 && f->defrag_on_close) {
}
static int journal_file_verify_header(JournalFile *f) {
+ uint64_t arena_size, header_size;
+
assert(f);
assert(f->header);
if (f->header->state >= _STATE_MAX)
return -EBADMSG;
+ header_size = le64toh(f->header->header_size);
+
/* The first addition was n_data, so check that we are at least this large */
- if (le64toh(f->header->header_size) < HEADER_SIZE_MIN)
+ if (header_size < HEADER_SIZE_MIN)
return -EBADMSG;
if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
return -EBADMSG;
- if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size)
+ arena_size = le64toh(f->header->arena_size);
+
+ if (UINT64_MAX - header_size < arena_size || header_size + arena_size > (uint64_t) f->last_stat.st_size)
return -ENODATA;
- if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size)))
+ if (le64toh(f->header->tail_object_offset) > header_size + arena_size)
return -ENODATA;
if (!VALID64(le64toh(f->header->data_hash_table_offset)) ||
return -EBUSY;
}
+ if (f->header->field_hash_table_size == 0 || f->header->data_hash_table_size == 0)
+ return -EBADMSG;
+
/* Don't permit appending to files from the future. Because otherwise the realtime timestamps wouldn't
* be strictly ordered in the entries in the file anymore, and we can't have that since it breaks
* bisection. */
* for sure, since we always call posix_fallocate()
* ourselves */
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
return -EIO;
old_size =
return -EADDRNOTAVAIL;
}
- return mmap_cache_get(f->mmap, f->fd, f->prot, type_to_context(type), keep_always, offset, size, &f->last_stat, ret);
+ return mmap_cache_get(f->mmap, f->cache_fd, f->prot, type_to_context(type), keep_always, offset, size, &f->last_stat, ret);
}
static uint64_t minimum_header_size(Object *o) {
* it is very likely just an effect of a nullified replacement
* mapping page */
- if (mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd))
r = -EIO;
if (f->post_change_timer)
f->close_fd = true;
}
+ f->cache_fd = mmap_cache_add_fd(f->mmap, f->fd);
+ if (!f->cache_fd) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
r = journal_file_fstat(f);
if (r < 0)
goto fail;
goto fail;
}
- r = mmap_cache_get(f->mmap, f->fd, f->prot, CONTEXT_HEADER, true, 0, PAGE_ALIGN(sizeof(Header)), &f->last_stat, &h);
+ r = mmap_cache_get(f->mmap, f->cache_fd, f->prot, CONTEXT_HEADER, true, 0, PAGE_ALIGN(sizeof(Header)), &f->last_stat, &h);
if (r < 0)
goto fail;
#endif
}
- if (mmap_cache_got_sigbus(f->mmap, f->fd)) {
+ if (mmap_cache_got_sigbus(f->mmap, f->cache_fd)) {
r = -EIO;
goto fail;
}
return 0;
fail:
- if (f->fd >= 0 && mmap_cache_got_sigbus(f->mmap, f->fd))
+ if (f->cache_fd && mmap_cache_got_sigbus(f->mmap, f->cache_fd))
r = -EIO;
(void) journal_file_close(f);
r = journal_file_append_entry_internal(to, &ts, xor_hash, items, n, seqnum, ret, offset);
- if (mmap_cache_got_sigbus(to->mmap, to->fd))
+ if (mmap_cache_got_sigbus(to->mmap, to->cache_fd))
return -EIO;
return r;
typedef struct JournalFile {
int fd;
+ MMapFileDescriptor *cache_fd;
mode_t mode;
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
#include <errno.h>
#include <qrencode.h>
#include <stdbool.h>
#include <stdlib.h>
#include "journal-qrcode.h"
+#include "macro.h"
#define WHITE_ON_BLACK "\033[40;37;1m"
#define NORMAL "\033[0m"
return 0;
}
-static int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
+static int contains_uint64(MMapCache *m, MMapFileDescriptor *f, uint64_t n, uint64_t p) {
uint64_t a, b;
int r;
assert(m);
- assert(fd >= 0);
+ assert(f);
/* Bisection ... */
c = (a + b) / 2;
- r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
+ r = mmap_cache_get(m, f, PROT_READ|PROT_WRITE, 0, false, c * sizeof(uint64_t), sizeof(uint64_t), NULL, (void **) &z);
if (r < 0)
return r;
static int entry_points_to_data(
JournalFile *f,
- int entry_fd,
+ MMapFileDescriptor *cache_entry_fd,
uint64_t n_entries,
uint64_t entry_p,
uint64_t data_p) {
bool found = false;
assert(f);
- assert(entry_fd >= 0);
+ assert(cache_entry_fd);
- if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
+ if (!contains_uint64(f->mmap, cache_entry_fd, n_entries, entry_p)) {
error(data_p, "Data object references invalid entry at "OFSfmt, entry_p);
return -EBADMSG;
}
static int verify_data(
JournalFile *f,
Object *o, uint64_t p,
- int entry_fd, uint64_t n_entries,
- int entry_array_fd, uint64_t n_entry_arrays) {
+ MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+ MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays) {
uint64_t i, n, a, last, q;
int r;
assert(f);
assert(o);
- assert(entry_fd >= 0);
- assert(entry_array_fd >= 0);
+ assert(cache_entry_fd);
+ assert(cache_entry_array_fd);
n = le64toh(o->data.n_entries);
a = le64toh(o->data.entry_array_offset);
assert(o->data.entry_offset);
last = q = le64toh(o->data.entry_offset);
- r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+ r = entry_points_to_data(f, cache_entry_fd, n_entries, q, p);
if (r < 0)
return r;
return -EBADMSG;
}
- if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+ if (!contains_uint64(f->mmap, cache_entry_array_fd, n_entry_arrays, a)) {
error(p, "Invalid array offset "OFSfmt, a);
return -EBADMSG;
}
}
last = q;
- r = entry_points_to_data(f, entry_fd, n_entries, q, p);
+ r = entry_points_to_data(f, cache_entry_fd, n_entries, q, p);
if (r < 0)
return r;
static int verify_hash_table(
JournalFile *f,
- int data_fd, uint64_t n_data,
- int entry_fd, uint64_t n_entries,
- int entry_array_fd, uint64_t n_entry_arrays,
+ MMapFileDescriptor *cache_data_fd, uint64_t n_data,
+ MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+ MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays,
usec_t *last_usec,
bool show_progress) {
int r;
assert(f);
- assert(data_fd >= 0);
- assert(entry_fd >= 0);
- assert(entry_array_fd >= 0);
+ assert(cache_data_fd);
+ assert(cache_entry_fd);
+ assert(cache_entry_array_fd);
assert(last_usec);
n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
Object *o;
uint64_t next;
- if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
+ if (!contains_uint64(f->mmap, cache_data_fd, n_data, p)) {
error(p, "Invalid data object at hash entry %"PRIu64" of %"PRIu64, i, n);
return -EBADMSG;
}
return -EBADMSG;
}
- r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays);
+ r = verify_data(f, o, p, cache_entry_fd, n_entries, cache_entry_array_fd, n_entry_arrays);
if (r < 0)
return r;
static int verify_entry(
JournalFile *f,
Object *o, uint64_t p,
- int data_fd, uint64_t n_data) {
+ MMapFileDescriptor *cache_data_fd, uint64_t n_data) {
uint64_t i, n;
int r;
assert(f);
assert(o);
- assert(data_fd >= 0);
+ assert(cache_data_fd);
n = journal_file_entry_n_items(o);
for (i = 0; i < n; i++) {
q = le64toh(o->entry.items[i].object_offset);
h = le64toh(o->entry.items[i].hash);
- if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
+ if (!contains_uint64(f->mmap, cache_data_fd, n_data, q)) {
error(p, "Invalid data object of entry");
return -EBADMSG;
}
static int verify_entry_array(
JournalFile *f,
- int data_fd, uint64_t n_data,
- int entry_fd, uint64_t n_entries,
- int entry_array_fd, uint64_t n_entry_arrays,
+ MMapFileDescriptor *cache_data_fd, uint64_t n_data,
+ MMapFileDescriptor *cache_entry_fd, uint64_t n_entries,
+ MMapFileDescriptor *cache_entry_array_fd, uint64_t n_entry_arrays,
usec_t *last_usec,
bool show_progress) {
int r;
assert(f);
- assert(data_fd >= 0);
- assert(entry_fd >= 0);
- assert(entry_array_fd >= 0);
+ assert(cache_data_fd);
+ assert(cache_entry_fd);
+ assert(cache_entry_array_fd);
assert(last_usec);
n = le64toh(f->header->n_entries);
return -EBADMSG;
}
- if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
+ if (!contains_uint64(f->mmap, cache_entry_array_fd, n_entry_arrays, a)) {
error(a, "Invalid array %"PRIu64" of %"PRIu64, i, n);
return -EBADMSG;
}
}
last = p;
- if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
+ if (!contains_uint64(f->mmap, cache_entry_fd, n_entries, p)) {
error(a, "Invalid array entry at %"PRIu64" of %"PRIu64, i, n);
return -EBADMSG;
}
if (r < 0)
return r;
- r = verify_entry(f, o, p, data_fd, n_data);
+ r = verify_entry(f, o, p, cache_data_fd, n_data);
if (r < 0)
return r;
uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0, n_tags = 0;
usec_t last_usec = 0;
int data_fd = -1, entry_fd = -1, entry_array_fd = -1;
+ MMapFileDescriptor *cache_data_fd = NULL, *cache_entry_fd = NULL, *cache_entry_array_fd = NULL;
unsigned i;
bool found_last = false;
const char *tmp_dir = NULL;
goto fail;
}
+ cache_data_fd = mmap_cache_add_fd(f->mmap, data_fd);
+ if (!cache_data_fd) {
+ r = log_oom();
+ goto fail;
+ }
+
+ cache_entry_fd = mmap_cache_add_fd(f->mmap, entry_fd);
+ if (!cache_entry_fd) {
+ r = log_oom();
+ goto fail;
+ }
+
+ cache_entry_array_fd = mmap_cache_add_fd(f->mmap, entry_array_fd);
+ if (!cache_entry_array_fd) {
+ r = log_oom();
+ goto fail;
+ }
+
if (le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SUPPORTED) {
log_error("Cannot verify file with unknown extensions.");
r = -EOPNOTSUPP;
* referenced is consistent. */
r = verify_entry_array(f,
- data_fd, n_data,
- entry_fd, n_entries,
- entry_array_fd, n_entry_arrays,
+ cache_data_fd, n_data,
+ cache_entry_fd, n_entries,
+ cache_entry_array_fd, n_entry_arrays,
&last_usec,
show_progress);
if (r < 0)
goto fail;
r = verify_hash_table(f,
- data_fd, n_data,
- entry_fd, n_entries,
- entry_array_fd, n_entry_arrays,
+ cache_data_fd, n_data,
+ cache_entry_fd, n_entries,
+ cache_entry_array_fd, n_entry_arrays,
&last_usec,
show_progress);
if (r < 0)
if (show_progress)
flush_progress();
- mmap_cache_close_fd(f->mmap, data_fd);
- mmap_cache_close_fd(f->mmap, entry_fd);
- mmap_cache_close_fd(f->mmap, entry_array_fd);
+ mmap_cache_free_fd(f->mmap, cache_data_fd);
+ mmap_cache_free_fd(f->mmap, cache_entry_fd);
+ mmap_cache_free_fd(f->mmap, cache_entry_array_fd);
safe_close(data_fd);
safe_close(entry_fd);
(unsigned long long) f->last_stat.st_size,
100 * p / f->last_stat.st_size);
- if (data_fd >= 0) {
- mmap_cache_close_fd(f->mmap, data_fd);
+ if (data_fd >= 0)
safe_close(data_fd);
- }
- if (entry_fd >= 0) {
- mmap_cache_close_fd(f->mmap, entry_fd);
+ if (entry_fd >= 0)
safe_close(entry_fd);
- }
- if (entry_array_fd >= 0) {
- mmap_cache_close_fd(f->mmap, entry_array_fd);
+ if (entry_array_fd >= 0)
safe_close(entry_array_fd);
- }
+
+ if (cache_data_fd)
+ mmap_cache_free_fd(f->mmap, cache_data_fd);
+
+ if (cache_entry_fd)
+ mmap_cache_free_fd(f->mmap, cache_entry_fd);
+
+ if (cache_entry_array_fd)
+ mmap_cache_free_fd(f->mmap, cache_entry_array_fd);
return r;
}
" --no-tail Show all lines, even in follow mode\n"
" -r --reverse Show the newest entries first\n"
" -o --output=STRING Change journal output mode (short, short-precise,\n"
- " short-iso, short-full, short-monotonic, short-unix,\n"
- " verbose, export, json, json-pretty, json-sse, cat)\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix, verbose, export,\n"
+ " json, json-pretty, json-sse, cat)\n"
" --utc Express time in Coordinated Universal Time (UTC)\n"
" -x --catalog Add message explanations where available\n"
" --no-full Ellipsize fields\n"
log_error_errno(r, "Failed to iterate through journal: %m");
goto finish;
}
- if (r == 0) {
- if (arg_follow)
- need_seek = true;
- else {
- if (!arg_quiet)
- printf("-- No entries --\n");
- goto finish;
- }
- }
+ if (r == 0)
+ need_seek = true;
if (!arg_follow)
pager_open(arg_no_pager, arg_pager_end);
- if (!arg_quiet) {
+ if (!arg_quiet && (arg_lines != 0 || arg_follow)) {
usec_t start, end;
char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
}
if (!arg_follow) {
+ if (n_shown == 0 && !arg_quiet)
+ printf("-- No entries --\n");
+
if (arg_show_cursor) {
_cleanup_free_ char *cursor = NULL;
break;
}
+ fflush(stdout);
r = sd_journal_wait(j, (uint64_t) -1);
if (r < 0) {
log_error_errno(r, "Couldn't wait for journal event: %m");
}
finish:
+ fflush(stdout);
pager_close();
strv_free(arg_file);
/* First: timestamp */
if (prefix_timestamp()) {
assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
- xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
+ xsprintf(tbuf, "[%5"PRI_TIME".%06"PRI_NSEC"] ",
ts.tv_sec,
- ts.tv_nsec / 1000);
+ (nsec_t)ts.tv_nsec / 1000);
IOVEC_SET_STRING(iovec[n++], tbuf);
}
#include "selinux-util.h"
#include "socket-util.h"
#include "string-util.h"
+#include "unaligned.h"
bool valid_user_field(const char *p, size_t l, bool allow_protected) {
const char *a;
return ucred && ucred->uid == 0;
}
-void server_process_native_message(
+static void server_process_entry_meta(
+ const char *p, size_t l,
+ const struct ucred *ucred,
+ int *priority,
+ char **identifier,
+ char **message,
+ pid_t *object_pid) {
+
+ /* We need to determine the priority of this entry for the rate limiting logic */
+
+ if (l == 10 &&
+ startswith(p, "PRIORITY=") &&
+ p[9] >= '0' && p[9] <= '9')
+ *priority = (*priority & LOG_FACMASK) | (p[9] - '0');
+
+ else if (l == 17 &&
+ startswith(p, "SYSLOG_FACILITY=") &&
+ p[16] >= '0' && p[16] <= '9')
+ *priority = (*priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
+
+ else if (l == 18 &&
+ startswith(p, "SYSLOG_FACILITY=") &&
+ p[16] >= '0' && p[16] <= '9' &&
+ p[17] >= '0' && p[17] <= '9')
+ *priority = (*priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
+
+ else if (l >= 19 &&
+ startswith(p, "SYSLOG_IDENTIFIER=")) {
+ char *t;
+
+ t = strndup(p + 18, l - 18);
+ if (t) {
+ free(*identifier);
+ *identifier = t;
+ }
+
+ } else if (l >= 8 &&
+ startswith(p, "MESSAGE=")) {
+ char *t;
+
+ t = strndup(p + 8, l - 8);
+ if (t) {
+ free(*message);
+ *message = t;
+ }
+
+ } else if (l > strlen("OBJECT_PID=") &&
+ l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
+ startswith(p, "OBJECT_PID=") &&
+ allow_object_pid(ucred)) {
+ char buf[DECIMAL_STR_MAX(pid_t)];
+ memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
+ buf[l-strlen("OBJECT_PID=")] = '\0';
+
+ (void) parse_pid(buf, object_pid);
+ }
+}
+
+static int server_process_entry(
Server *s,
- const void *buffer, size_t buffer_size,
+ const void *buffer, size_t *remaining,
const struct ucred *ucred,
const struct timeval *tv,
const char *label, size_t label_len) {
+ /* Process a single entry from a native message.
+ * Returns 0 if nothing special happened and the message processing should continue,
+ * and a negative or positive value otherwise.
+ *
+ * Note that *remaining is altered on both success and failure. */
+
struct iovec *iovec = NULL;
unsigned n = 0, j, tn = (unsigned) -1;
const char *p;
- size_t remaining, m = 0, entry_size = 0;
+ size_t m = 0, entry_size = 0;
int priority = LOG_INFO;
char *identifier = NULL, *message = NULL;
pid_t object_pid = 0;
-
- assert(s);
- assert(buffer || buffer_size == 0);
+ int r = 0;
p = buffer;
- remaining = buffer_size;
- while (remaining > 0) {
+ while (*remaining > 0) {
const char *e, *q;
- e = memchr(p, '\n', remaining);
+ e = memchr(p, '\n', *remaining);
if (!e) {
/* Trailing noise, let's ignore it, and flush what we collected */
log_debug("Received message with trailing noise, ignoring.");
+ r = 1; /* finish processing of the message */
break;
}
if (e == p) {
/* Entry separator */
-
- if (entry_size + n + 1 > ENTRY_SIZE_MAX) { /* data + separators + trailer */
- log_debug("Entry is too big with %u properties and %zu bytes, ignoring.", n, entry_size);
- continue;
- }
-
- server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority, object_pid);
- n = 0;
- priority = LOG_INFO;
- entry_size = 0;
-
- p++;
- remaining--;
- continue;
+ *remaining -= 1;
+ break;
}
if (*p == '.' || *p == '#') {
/* Ignore control commands for now, and
* comments too. */
- remaining -= (e - p) + 1;
+ *remaining -= (e - p) + 1;
p = e + 1;
continue;
}
/* n existing properties, 1 new, +1 for _TRANSPORT */
if (!GREEDY_REALLOC(iovec, m, n + 2 + N_IOVEC_META_FIELDS + N_IOVEC_OBJECT_FIELDS)) {
- log_oom();
+ r = log_oom();
break;
}
/* If the field name starts with an
* underscore, skip the variable,
- * since that indidates a trusted
+ * since that indicates a trusted
* field */
iovec[n].iov_base = (char*) p;
iovec[n].iov_len = l;
- entry_size += iovec[n].iov_len;
+ entry_size += l;
n++;
- /* We need to determine the priority
- * of this entry for the rate limiting
- * logic */
- if (l == 10 &&
- startswith(p, "PRIORITY=") &&
- p[9] >= '0' && p[9] <= '9')
- priority = (priority & LOG_FACMASK) | (p[9] - '0');
-
- else if (l == 17 &&
- startswith(p, "SYSLOG_FACILITY=") &&
- p[16] >= '0' && p[16] <= '9')
- priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3);
-
- else if (l == 18 &&
- startswith(p, "SYSLOG_FACILITY=") &&
- p[16] >= '0' && p[16] <= '9' &&
- p[17] >= '0' && p[17] <= '9')
- priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3);
-
- else if (l >= 19 &&
- startswith(p, "SYSLOG_IDENTIFIER=")) {
- char *t;
-
- t = strndup(p + 18, l - 18);
- if (t) {
- free(identifier);
- identifier = t;
- }
-
- } else if (l >= 8 &&
- startswith(p, "MESSAGE=")) {
- char *t;
-
- t = strndup(p + 8, l - 8);
- if (t) {
- free(message);
- message = t;
- }
-
- } else if (l > strlen("OBJECT_PID=") &&
- l < strlen("OBJECT_PID=") + DECIMAL_STR_MAX(pid_t) &&
- startswith(p, "OBJECT_PID=") &&
- allow_object_pid(ucred)) {
- char buf[DECIMAL_STR_MAX(pid_t)];
- memcpy(buf, p + strlen("OBJECT_PID="), l - strlen("OBJECT_PID="));
- buf[l-strlen("OBJECT_PID=")] = '\0';
-
- /* ignore error */
- parse_pid(buf, &object_pid);
- }
+ server_process_entry_meta(p, l, ucred,
+ &priority,
+ &identifier,
+ &message,
+ &object_pid);
}
- remaining -= (e - p) + 1;
+ *remaining -= (e - p) + 1;
p = e + 1;
continue;
} else {
- le64_t l_le;
uint64_t l;
char *k;
- if (remaining < e - p + 1 + sizeof(uint64_t) + 1) {
+ if (*remaining < e - p + 1 + sizeof(uint64_t) + 1) {
log_debug("Failed to parse message, ignoring.");
break;
}
- memcpy(&l_le, e + 1, sizeof(uint64_t));
- l = le64toh(l_le);
+ l = unaligned_read_le64(e + 1);
if (l > DATA_SIZE_MAX) {
log_debug("Received binary data block of %"PRIu64" bytes is too large, ignoring.", l);
break;
}
- if ((uint64_t) remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
+ if ((uint64_t) *remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
e[1+sizeof(uint64_t)+l] != '\n') {
log_debug("Failed to parse message, ignoring.");
break;
iovec[n].iov_len = (e - p) + 1 + l;
entry_size += iovec[n].iov_len;
n++;
+
+ server_process_entry_meta(k, (e - p) + 1 + l, ucred,
+ &priority,
+ &identifier,
+ &message,
+ &object_pid);
} else
free(k);
- remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
+ *remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1;
p = e + 1 + sizeof(uint64_t) + l + 1;
}
}
- if (n <= 0)
+ if (n <= 0) {
+ r = 1;
goto finish;
+ }
tn = n++;
IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal");
if (message) {
if (s->forward_to_syslog)
- server_forward_syslog(s, priority, identifier, message, ucred, tv);
+ server_forward_syslog(s, syslog_fixup_facility(priority), identifier, message, ucred, tv);
if (s->forward_to_kmsg)
server_forward_kmsg(s, priority, identifier, message, ucred);
continue;
if (iovec[j].iov_base < buffer ||
- (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size)
+ (const char*) iovec[j].iov_base >= p + *remaining)
free(iovec[j].iov_base);
}
free(iovec);
free(identifier);
free(message);
+
+ return r;
+}
+
+void server_process_native_message(
+ Server *s,
+ const void *buffer, size_t buffer_size,
+ const struct ucred *ucred,
+ const struct timeval *tv,
+ const char *label, size_t label_len) {
+
+ int r;
+ size_t remaining = buffer_size;
+
+ assert(s);
+ assert(buffer || buffer_size == 0);
+
+ do {
+ r = server_process_entry(s,
+ (const uint8_t*) buffer + (buffer_size - remaining), &remaining,
+ ucred, tv, label, label_len);
+ } while (r == 0);
}
void server_process_native_file(
return log_error_errno(errno, "SO_PASSCRED failed: %m");
#ifdef HAVE_SELINUX
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
if (r < 0)
log_warning_errno(errno, "SO_PASSSEC failed: %m");
}
#ifdef HAVE_SELINUX
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
if (label) {
x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
assert(s);
return config_parse_many_nulstr(PKGSYSCONFDIR "/journald.conf",
- CONF_PATHS_NULSTR("systemd/journald.conf.d"),
- "Journal\0",
- config_item_perf_lookup, journald_gperf_lookup,
- false, s);
+ CONF_PATHS_NULSTR("systemd/journald.conf.d"),
+ "Journal\0",
+ config_item_perf_lookup, journald_gperf_lookup,
+ false, s);
}
static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
free(s->tty_path);
free(s->cgroup_root);
free(s->hostname_field);
+ free(s->runtime_storage.path);
+ free(s->system_storage.path);
if (s->mmap)
mmap_cache_unref(s->mmap);
typedef struct JournalStorage {
const char *name;
- const char *path;
+ char *path;
JournalMetrics metrics;
JournalStorageSpace space;
if (r < 0)
return log_error_errno(r, "Failed to determine peer credentials: %m");
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = getpeersec(fd, &stream->label);
if (r < 0 && r != -EOPNOTSUPP)
(void) log_warning_errno(r, "Failed to determine peer security context: %m");
return log_error_errno(errno, "SO_PASSCRED failed: %m");
#ifdef HAVE_SELINUX
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one));
if (r < 0)
log_warning_errno(errno, "SO_PASSSEC failed: %m");
--- /dev/null
+journal_internal_sources = files('''
+ audit-type.c
+ audit-type.h
+ catalog.c
+ catalog.h
+ compress.c
+ compress.h
+ journal-def.h
+ journal-file.c
+ journal-file.h
+ journal-send.c
+ journal-vacuum.c
+ journal-vacuum.h
+ journal-verify.c
+ journal-verify.h
+ lookup3.c
+ lookup3.h
+ mmap-cache.c
+ mmap-cache.h
+ sd-journal.c
+'''.split())
+
+if conf.get('HAVE_GCRYPT', false)
+ journal_internal_sources += files('''
+ journal-authenticate.c
+ journal-authenticate.h
+ fsprg.c
+ fsprg.h
+ '''.split())
+
+ journal_internal_sources += gcrypt_util_sources
+endif
+
+############################################################
+
+audit_type_includes = [config_h,
+ missing_h,
+ 'linux/audit.h']
+if conf.get('HAVE_AUDIT', false)
+ audit_type_includes += 'libaudit.h'
+endif
+
+generate_audit_type_list = find_program('generate-audit_type-list.sh')
+audit_type_list_txt = custom_target(
+ 'audit_type-list.txt',
+ output : 'audit_type-list.txt',
+ command : [generate_audit_type_list, cpp] + audit_type_includes,
+ capture : true)
+
+audit_type_to_name = custom_target(
+ 'audit_type-to-name.h',
+ input : ['audit_type-to-name.awk', audit_type_list_txt],
+ output : 'audit_type-to-name.h',
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+journal_internal_sources += [audit_type_to_name]
+
+############################################################
+
+libjournal_core_sources = files('''
+ journald-kmsg.c
+ journald-kmsg.h
+ journald-syslog.c
+ journald-syslog.h
+ journald-stream.c
+ journald-stream.h
+ journald-server.c
+ journald-server.h
+ journald-console.c
+ journald-console.h
+ journald-wall.c
+ journald-wall.h
+ journald-native.c
+ journald-native.h
+ journald-audit.c
+ journald-audit.h
+ journald-rate-limit.c
+ journald-rate-limit.h
+ journal-internal.h
+'''.split())
+
+systemd_journald_sources = files('''
+ journald.c
+ journald-server.h
+'''.split())
+
+journald_gperf_c = custom_target(
+ 'journald-gperf.c',
+ input : 'journald-gperf.gperf',
+ output : 'journald-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_cat_sources = files('cat.c')
+
+journalctl_sources = files('journalctl.c')
+
+if conf.get('HAVE_QRENCODE', false)
+ journalctl_sources += files('journal-qrcode.c',
+ 'journal-qrcode.h')
+endif
+
+install_data('journald.conf',
+ install_dir : pkgsysconfdir)
+
+meson.add_install_script(
+ 'sh', '-c',
+ mkdir_p.format('/var/log/journal'))
+meson.add_install_script(
+ 'sh', '-c',
+ 'chown 0:0 $DESTDIR/var/log/journal &&
+ chmod 755 $DESTDIR/var/log/journal || :')
+if get_option('adm-group')
+ meson.add_install_script(
+ 'sh', '-c',
+ 'setfacl -nm g:adm:rx,d:g:adm:rx $DESTDIR/var/log/journal || :')
+endif
+if get_option('wheel-group')
+ meson.add_install_script(
+ 'sh', '-c',
+ 'setfacl -nm g:wheel:rx,d:g:wheel:rx $DESTDIR/var/log/journal || :')
+endif
typedef struct Window Window;
typedef struct Context Context;
-typedef struct FileDescriptor FileDescriptor;
struct Window {
MMapCache *cache;
uint64_t offset;
size_t size;
- FileDescriptor *fd;
+ MMapFileDescriptor *fd;
LIST_FIELDS(Window, by_fd);
LIST_FIELDS(Window, unused);
LIST_FIELDS(Context, by_window);
};
-struct FileDescriptor {
+struct MMapFileDescriptor {
MMapCache *cache;
int fd;
bool sigbus;
free(w);
}
-_pure_ static bool window_matches(Window *w, int fd, int prot, uint64_t offset, size_t size) {
+_pure_ static bool window_matches(Window *w, MMapFileDescriptor *f, int prot, uint64_t offset, size_t size) {
assert(w);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
return
w->fd &&
- fd == w->fd->fd &&
+ f->fd == w->fd->fd &&
prot == w->prot &&
offset >= w->offset &&
offset + size <= w->offset + w->size;
}
-static Window *window_add(MMapCache *m, FileDescriptor *fd, int prot, bool keep_always, uint64_t offset, size_t size, void *ptr) {
+static Window *window_add(MMapCache *m, MMapFileDescriptor *f, int prot, bool keep_always, uint64_t offset, size_t size, void *ptr) {
Window *w;
assert(m);
- assert(fd);
+ assert(f);
if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
}
w->cache = m;
- w->fd = fd;
+ w->fd = f;
w->prot = prot;
w->keep_always = keep_always;
w->offset = offset;
w->size = size;
w->ptr = ptr;
- LIST_PREPEND(by_fd, fd->windows, w);
+ LIST_PREPEND(by_fd, f->windows, w);
return w;
}
free(c);
}
-static void fd_free(FileDescriptor *f) {
- assert(f);
-
- while (f->windows)
- window_free(f->windows);
-
- if (f->cache)
- assert_se(hashmap_remove(f->cache->fds, FD_TO_PTR(f->fd)));
-
- free(f);
-}
-
-static FileDescriptor* fd_add(MMapCache *m, int fd) {
- FileDescriptor *f;
- int r;
-
- assert(m);
- assert(fd >= 0);
-
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (f)
- return f;
-
- r = hashmap_ensure_allocated(&m->fds, NULL);
- if (r < 0)
- return NULL;
-
- f = new0(FileDescriptor, 1);
- if (!f)
- return NULL;
-
- f->cache = m;
- f->fd = fd;
-
- r = hashmap_put(m->fds, FD_TO_PTR(fd), f);
- if (r < 0)
- return mfree(f);
-
- return f;
-}
-
static void mmap_cache_free(MMapCache *m) {
- FileDescriptor *f;
int i;
assert(m);
if (m->contexts[i])
context_free(m->contexts[i]);
- while ((f = hashmap_first(m->fds)))
- fd_free(f);
-
hashmap_free(m->fds);
while (m->unused)
static int try_context(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
assert(ret);
if (!c->window)
return 0;
- if (!window_matches(c->window, fd, prot, offset, size)) {
+ if (!window_matches(c->window, f, prot, offset, size)) {
/* Drop the reference to the window, since it's unnecessary now */
context_detach_window(c);
static int find_mmap(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
size_t size,
void **ret) {
- FileDescriptor *f;
Window *w;
Context *c;
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (!f)
- return 0;
-
- assert(f->fd == fd);
-
if (f->sigbus)
return -EIO;
LIST_FOREACH(by_fd, w, f->windows)
- if (window_matches(w, fd, prot, offset, size))
+ if (window_matches(w, f, prot, offset, size))
break;
if (!w)
return 1;
}
-static int mmap_try_harder(MMapCache *m, void *addr, int fd, int prot, int flags, uint64_t offset, size_t size, void **res) {
+static int mmap_try_harder(MMapCache *m, void *addr, MMapFileDescriptor *f, int prot, int flags, uint64_t offset, size_t size, void **res) {
void *ptr;
assert(m);
- assert(fd >= 0);
+ assert(f);
assert(res);
for (;;) {
int r;
- ptr = mmap(addr, size, prot, flags, fd, offset);
+ ptr = mmap(addr, size, prot, flags, f->fd, offset);
if (ptr != MAP_FAILED)
break;
if (errno != ENOMEM)
static int add_mmap(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
uint64_t woffset, wsize;
Context *c;
- FileDescriptor *f;
Window *w;
void *d;
int r;
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
assert(ret);
wsize = PAGE_ALIGN(st->st_size - woffset);
}
- r = mmap_try_harder(m, NULL, fd, prot, MAP_SHARED, woffset, wsize, &d);
+ r = mmap_try_harder(m, NULL, f, prot, MAP_SHARED, woffset, wsize, &d);
if (r < 0)
return r;
if (!c)
goto outofmem;
- f = fd_add(m, fd);
- if (!f)
- goto outofmem;
-
w = window_add(m, f, prot, keep_always, woffset, wsize, d);
if (!w)
goto outofmem;
int mmap_cache_get(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
assert(m);
assert(m->n_ref > 0);
- assert(fd >= 0);
+ assert(f);
assert(size > 0);
assert(ret);
assert(context < MMAP_CACHE_MAX_CONTEXTS);
/* Check whether the current context is the right one already */
- r = try_context(m, fd, prot, context, keep_always, offset, size, ret);
+ r = try_context(m, f, prot, context, keep_always, offset, size, ret);
if (r != 0) {
m->n_hit++;
return r;
}
/* Search for a matching mmap */
- r = find_mmap(m, fd, prot, context, keep_always, offset, size, ret);
+ r = find_mmap(m, f, prot, context, keep_always, offset, size, ret);
if (r != 0) {
m->n_hit++;
return r;
m->n_missed++;
/* Create a new mmap */
- return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret);
+ return add_mmap(m, f, prot, context, keep_always, offset, size, st, ret);
}
unsigned mmap_cache_get_hit(MMapCache *m) {
static void mmap_cache_process_sigbus(MMapCache *m) {
bool found = false;
- FileDescriptor *f;
+ MMapFileDescriptor *f;
Iterator i;
int r;
}
}
-bool mmap_cache_got_sigbus(MMapCache *m, int fd) {
- FileDescriptor *f;
-
+bool mmap_cache_got_sigbus(MMapCache *m, MMapFileDescriptor *f) {
assert(m);
- assert(fd >= 0);
+ assert(f);
mmap_cache_process_sigbus(m);
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (!f)
- return false;
-
return f->sigbus;
}
-void mmap_cache_close_fd(MMapCache *m, int fd) {
- FileDescriptor *f;
+MMapFileDescriptor* mmap_cache_add_fd(MMapCache *m, int fd) {
+ MMapFileDescriptor *f;
+ int r;
assert(m);
assert(fd >= 0);
+ f = hashmap_get(m->fds, FD_TO_PTR(fd));
+ if (f)
+ return f;
+
+ r = hashmap_ensure_allocated(&m->fds, NULL);
+ if (r < 0)
+ return NULL;
+
+ f = new0(MMapFileDescriptor, 1);
+ if (!f)
+ return NULL;
+
+ f->cache = m;
+ f->fd = fd;
+
+ r = hashmap_put(m->fds, FD_TO_PTR(fd), f);
+ if (r < 0)
+ return mfree(f);
+
+ return f;
+}
+
+void mmap_cache_free_fd(MMapCache *m, MMapFileDescriptor *f) {
+ assert(m);
+ assert(f);
+
/* Make sure that any queued SIGBUS are first dispatched, so
* that we don't end up with a SIGBUS entry we cannot relate
* to any existing memory map */
mmap_cache_process_sigbus(m);
- f = hashmap_get(m->fds, FD_TO_PTR(fd));
- if (!f)
- return;
+ while (f->windows)
+ window_free(f->windows);
+
+ if (f->cache)
+ assert_se(hashmap_remove(f->cache->fds, FD_TO_PTR(f->fd)));
- fd_free(f);
+ free(f);
}
#define MMAP_CACHE_MAX_CONTEXTS 9
typedef struct MMapCache MMapCache;
+typedef struct MMapFileDescriptor MMapFileDescriptor;
MMapCache* mmap_cache_new(void);
MMapCache* mmap_cache_ref(MMapCache *m);
int mmap_cache_get(
MMapCache *m,
- int fd,
+ MMapFileDescriptor *f,
int prot,
unsigned context,
bool keep_always,
size_t size,
struct stat *st,
void **ret);
-void mmap_cache_close_fd(MMapCache *m, int fd);
+MMapFileDescriptor * mmap_cache_add_fd(MMapCache *m, int fd);
+void mmap_cache_free_fd(MMapCache *m, MMapFileDescriptor *f);
unsigned mmap_cache_get_hit(MMapCache *m);
unsigned mmap_cache_get_missed(MMapCache *m);
-bool mmap_cache_got_sigbus(MMapCache *m, int fd);
+bool mmap_cache_got_sigbus(MMapCache *m, MMapFileDescriptor *f);
if (skip == 0) {
/* If this is not a discrete skip, then at least
* resolve the current location */
- if (j->current_location.type != LOCATION_DISCRETE)
- return real_journal_next(j, direction);
+ if (j->current_location.type != LOCATION_DISCRETE) {
+ r = real_journal_next(j, direction);
+ if (r < 0)
+ return r;
+ }
return 0;
}
assert_return(!journal_pid_changed(j), -ECHILD);
j->last_process_usec = now(CLOCK_MONOTONIC);
+ j->last_invalidate_counter = j->current_invalidate_counter;
for (;;) {
union inotify_event_buffer buffer;
typedef int (decompress_t)(const void *src, uint64_t src_size,
void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
+
static usec_t arg_duration = 2 * USEC_PER_SEC;
static size_t arg_start;
100 - compressed * 100. / total,
skipped);
}
+#endif
int main(int argc, char *argv[]) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
const char *i;
log_set_max_level(LOG_INFO);
#endif
}
return 0;
+#else
+ return EXIT_TEST_SKIP;
+#endif
}
typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
static void test_compress_decompress(int compression,
compress_blob_t compress,
decompress_blob_t decompress,
assert_se(unlink(pattern) == 0);
assert_se(unlink(pattern2) == 0);
}
+#endif
#ifdef HAVE_LZ4
static void test_lz4_decompress_partial(void) {
#endif
int main(int argc, char *argv[]) {
+#if defined(HAVE_XZ) || defined(HAVE_LZ4)
const char text[] =
"text\0foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF"
"foofoofoofoo AAAA aaaaaaaaa ghost busters barbarbar FFF";
#endif
return 0;
+#else
+ return EXIT_TEST_SKIP;
+#endif
}
#include "util.h"
int main(int argc, char *argv[]) {
+ MMapFileDescriptor *fx;
int x, y, z, r;
char px[] = "/tmp/testmmapXXXXXXX", py[] = "/tmp/testmmapYXXXXXX", pz[] = "/tmp/testmmapZXXXXXX";
MMapCache *m;
assert_se(x >= 0);
unlink(px);
+ assert_se(fx = mmap_cache_add_fd(m, x));
+
y = mkostemp_safe(py);
assert_se(y >= 0);
unlink(py);
assert_se(z >= 0);
unlink(pz);
- r = mmap_cache_get(m, x, PROT_READ, 0, false, 1, 2, NULL, &p);
+ r = mmap_cache_get(m, fx, PROT_READ, 0, false, 1, 2, NULL, &p);
assert_se(r >= 0);
- r = mmap_cache_get(m, x, PROT_READ, 0, false, 2, 2, NULL, &q);
+ r = mmap_cache_get(m, fx, PROT_READ, 0, false, 2, 2, NULL, &q);
assert_se(r >= 0);
assert_se((uint8_t*) p + 1 == (uint8_t*) q);
- r = mmap_cache_get(m, x, PROT_READ, 1, false, 3, 2, NULL, &q);
+ r = mmap_cache_get(m, fx, PROT_READ, 1, false, 3, 2, NULL, &q);
assert_se(r >= 0);
assert_se((uint8_t*) p + 2 == (uint8_t*) q);
- r = mmap_cache_get(m, x, PROT_READ, 0, false, 16ULL*1024ULL*1024ULL, 2, NULL, &p);
+ r = mmap_cache_get(m, fx, PROT_READ, 0, false, 16ULL*1024ULL*1024ULL, 2, NULL, &p);
assert_se(r >= 0);
- r = mmap_cache_get(m, x, PROT_READ, 1, false, 16ULL*1024ULL*1024ULL+1, 2, NULL, &q);
+ r = mmap_cache_get(m, fx, PROT_READ, 1, false, 16ULL*1024ULL*1024ULL+1, 2, NULL, &q);
assert_se(r >= 0);
assert_se((uint8_t*) p + 1 == (uint8_t*) q);
+ mmap_cache_free_fd(m, fx);
mmap_cache_unref(m);
safe_close(x);
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
-[[ $1 == "add" ]] || exit 0
[[ $2 ]] || exit 1
-exec depmod -a "$2"
+case "$1" in
+ add)
+ exec depmod -a "$2"
+ ;;
+ remove)
+ exec rm -f /lib/modules/"$2"/modules.{alias{,.bin},builtin.bin,dep{,.bin},devname,softdep,symbols{,.bin}}
+ ;;
+ *)
+ exit 0
+esac
BOOT_DIR_ABS="$3"
KERNEL_IMAGE="$4"
-if [[ -f /etc/machine-id ]]; then
- read MACHINE_ID < /etc/machine-id
+if ! [[ $KERNEL_INSTALL_MACHINE_ID ]]; then
+ exit 0
fi
-if ! [[ $MACHINE_ID ]]; then
- exit 1
-fi
+MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID
BOOT_DIR="/$MACHINE_ID/$KERNEL_VERSION"
BOOT_ROOT=${BOOT_DIR_ABS%$BOOT_DIR}
read MACHINE_ID < /etc/machine-id
fi
-if ! [[ $MACHINE_ID ]]; then
- echo "Could not determine your machine ID from /etc/machine-id." >&2
- echo "Please run 'systemd-machine-id-setup' as root. See man:machine-id(5)" >&2
- exit 1
-fi
-
if [[ ! $COMMAND ]] || [[ ! $KERNEL_VERSION ]]; then
echo "Not enough arguments" >&2
exit 1
fi
-if [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
+if ! [[ $MACHINE_ID ]]; then
+ BOOT_DIR_ABS=$(mktemp -d /tmp/kernel-install.XXXXX) || exit 1
+ trap "rm -rf '$BOOT_DIR_ABS'" EXIT INT QUIT PIPE
+elif [[ -d /efi/loader/entries ]] || [[ -d /efi/$MACHINE_ID ]]; then
BOOT_DIR_ABS="/efi/$MACHINE_ID/$KERNEL_VERSION"
elif [[ -d /boot/loader/entries ]] || [[ -d /boot/$MACHINE_ID ]]; then
BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
BOOT_DIR_ABS="/boot/$MACHINE_ID/$KERNEL_VERSION"
fi
+export KERNEL_INSTALL_MACHINE_ID=$MACHINE_ID
+
ret=0
readarray -t PLUGINS <<<"$(
"$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE"
x=$?
if [[ $x == $SKIP_REMAINING ]]; then
- exit 0
+ ret=0
+ break
fi
((ret+=$x))
fi
done
+
+ if ! [[ $MACHINE_ID ]] && ! rmdir "$BOOT_DIR_ABS"; then
+ echo "Warning: In kernel-install plugins, requiring BOOT_DIR_ABS to be preset is deprecated." >&2
+ echo " All plugins should not put anything in BOOT_DIR_ABS if the environment" >&2
+ echo " variable KERNEL_INSTALL_MACHINE_ID is empty." >&2
+ rm -rf "$BOOT_DIR_ABS"
+ ((ret+=$?))
+ fi
;;
remove)
"$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS"
x=$?
if [[ $x == $SKIP_REMAINING ]]; then
- exit 0
+ ret=0
+ break
fi
((ret+=$x))
fi
--- /dev/null
+install_data('kernel-install',
+ install_mode : 'rwxr-xr-x',
+ install_dir : bindir)
+
+install_data('50-depmod.install',
+ '90-loaderentry.install',
+ install_mode : 'rwxr-xr-x',
+ install_dir : kernelinstalldir)
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'kernel/install.d')))
uint16_t mtu; /* 0 if unset */
char *domainname;
+ char **search_domains;
char *hostname;
char *root_path;
int dhcp_lease_new(sd_dhcp_lease **ret);
int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void *userdata);
+int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains);
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len);
int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease);
#include "fd-util.h"
#include "icmp6-util.h"
#include "socket-util.h"
+#include "in-addr-util.h"
#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
-int icmp6_bind_router_solicitation(int index) {
- struct icmp6_filter filter = { };
- struct ipv6_mreq mreq = {
- .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
- .ipv6mr_interface = index,
- };
+static int icmp6_bind_router_message(const struct icmp6_filter *filter,
+ const struct ipv6_mreq *mreq) {
+ int index = mreq->ipv6mr_interface;
_cleanup_close_ int s = -1;
char ifname[IF_NAMESIZE] = "";
static const int zero = 0, one = 1, hops = 255;
if (s < 0)
return -errno;
- ICMP6_FILTER_SETBLOCKALL(&filter);
- ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
- r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter));
+ r = setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, filter, sizeof(*filter));
+ if (r < 0)
+ return -errno;
+
+ r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq, sizeof(*mreq));
if (r < 0)
return -errno;
if (r < 0)
return -errno;
- r = setsockopt(s, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
+ r = setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hops, sizeof(hops));
if (r < 0)
return -errno;
return r;
}
+int icmp6_bind_router_solicitation(int index) {
+ struct icmp6_filter filter = {};
+ struct ipv6_mreq mreq = {
+ .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
+ .ipv6mr_interface = index,
+ };
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
+
+ return icmp6_bind_router_message(&filter, &mreq);
+}
+
+int icmp6_bind_router_advertisement(int index) {
+ struct icmp6_filter filter = {};
+ struct ipv6_mreq mreq = {
+ .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
+ .ipv6mr_interface = index,
+ };
+
+ ICMP6_FILTER_SETBLOCKALL(&filter);
+ ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
+
+ return icmp6_bind_router_message(&filter, &mreq);
+}
+
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
struct sockaddr_in6 dst = {
.sin6_family = AF_INET6,
return 0;
}
+
+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
+ triple_timestamp *timestamp) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
+ CMSG_SPACE(sizeof(struct timeval))];
+ } control = {};
+ struct iovec iov = {};
+ union sockaddr_union sa = {};
+ struct msghdr msg = {
+ .msg_name = &sa.sa,
+ .msg_namelen = sizeof(sa),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ };
+ struct cmsghdr *cmsg;
+ ssize_t len;
+
+ iov.iov_base = buffer;
+ iov.iov_len = size;
+
+ len = recvmsg(fd, &msg, MSG_DONTWAIT);
+ if (len < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
+
+ return -errno;
+ }
+
+ if ((size_t) len != size)
+ return -EINVAL;
+
+ if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
+ sa.in6.sin6_family == AF_INET6) {
+
+ *dst = sa.in6.sin6_addr;
+ if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0)
+ return -EADDRNOTAVAIL;
+
+ } else if (msg.msg_namelen > 0)
+ return -EPFNOSUPPORT;
+
+ /* namelen == 0 only happens when running the test-suite over a socketpair */
+
+ assert(!(msg.msg_flags & MSG_CTRUNC));
+ assert(!(msg.msg_flags & MSG_TRUNC));
+
+ CMSG_FOREACH(cmsg, &msg) {
+ if (cmsg->cmsg_level == SOL_IPV6 &&
+ cmsg->cmsg_type == IPV6_HOPLIMIT &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ int hops = *(int*) CMSG_DATA(cmsg);
+
+ if (hops != 255)
+ return -EMULTIHOP;
+ }
+
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SO_TIMESTAMP &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
+ triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
+ }
+
+ if (!triple_timestamp_is_set(timestamp))
+ triple_timestamp_get(timestamp);
+
+ return 0;
+}
#include <net/ethernet.h>
+#include "time-util.h"
+
+#define IN6ADDR_ALL_ROUTERS_MULTICAST_INIT \
+ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 } } }
+
+#define IN6ADDR_ALL_NODES_MULTICAST_INIT \
+ { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
+
int icmp6_bind_router_solicitation(int index);
+int icmp6_bind_router_advertisement(int index);
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
+ triple_timestamp *timestamp);
log_lldp("End marker TLV not zero-sized, ignoring datagram.");
return -EBADMSG;
}
- if (left != 0) {
- log_lldp("Trailing garbage in datagram, ignoring datagram.");
- return -EBADMSG;
- }
+
+ /* Note that after processing the SD_LLDP_TYPE_END left could still be > 0
+ * as the message may contain padding (see IEEE 802.1AB-2016, sec. 8.5.12) */
goto end_marker;
--- /dev/null
+sources = files('''
+ sd-dhcp-client.c
+ sd-dhcp-server.c
+ dhcp-network.c
+ dhcp-option.c
+ dhcp-packet.c
+ dhcp-internal.h
+ dhcp-server-internal.h
+ dhcp-protocol.h
+ dhcp-lease-internal.h
+ sd-dhcp-lease.c
+ sd-ipv4ll.c
+ sd-ipv4acd.c
+ arp-util.h
+ arp-util.c
+ network-internal.c
+ sd-ndisc.c
+ ndisc-internal.h
+ ndisc-router.h
+ ndisc-router.c
+ sd-radv.c
+ radv-internal.h
+ icmp6-util.h
+ icmp6-util.c
+ sd-dhcp6-client.c
+ dhcp6-internal.h
+ dhcp6-protocol.h
+ dhcp6-network.c
+ dhcp6-option.c
+ dhcp6-lease-internal.h
+ sd-dhcp6-lease.c
+ dhcp-identifier.h
+ dhcp-identifier.c
+ lldp-internal.h
+ lldp-network.h
+ lldp-network.c
+ lldp-neighbor.h
+ lldp-neighbor.c
+ sd-lldp.c
+'''.split())
+
+network_internal_h = files('network-internal.h')
+
+libsystemd_network = static_library(
+ 'systemd-network',
+ sources,
+ network_internal_h,
+ include_directories : includes)
#include "sd-ndisc.h"
+#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
+#define NDISC_MAX_ROUTER_SOLICITATION_INTERVAL (3600U * USEC_PER_SEC)
+#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
+
struct sd_ndisc {
unsigned n_ref;
sd_event_source *recv_event_source;
sd_event_source *timeout_event_source;
+ sd_event_source *timeout_no_ra;
- unsigned nd_sent;
+ usec_t retransmit_time;
sd_ndisc_callback_t callback;
void *userdata;
return 0;
}
+int config_parse_bridge_port_priority(
+ 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) {
+
+ uint16_t i;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou16(rvalue, &i);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse bridge port priority, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (i > LINK_BRIDGE_PORT_PRIORITY_MAX) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Bridge port priority is larger than maximum %u, ignoring: %s", LINK_BRIDGE_PORT_PRIORITY_MAX, rvalue);
+ return 0;
+ }
+
+ *((uint16_t *)data) = i;
+
+ return 0;
+}
+
+
void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size) {
unsigned i;
#include "condition.h"
#include "udev.h"
+#define LINK_BRIDGE_PORT_PRIORITY_INVALID 128
+#define LINK_BRIDGE_PORT_PRIORITY_MAX 63
+
bool net_match_config(const struct ether_addr *match_mac,
char * const *match_path,
char * const *match_driver,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_bridge_port_priority(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);
+
int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result);
const char *net_get_name(struct udev_device *device);
--- /dev/null
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-radv.h"
+
+#include "log.h"
+#include "list.h"
+#include "sparse-endian.h"
+
+#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC (200*USEC_PER_SEC)
+#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC (600*USEC_PER_SEC)
+assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
+
+#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
+#define SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS 3
+#define SD_RADV_MAX_FINAL_RTR_ADVERTISEMENTS 3
+#define SD_RADV_MIN_DELAY_BETWEEN_RAS 3
+#define SD_RADV_MAX_RA_DELAY_TIME_USEC (500*USEC_PER_MSEC)
+
+enum RAdvState {
+ SD_RADV_STATE_IDLE = 0,
+ SD_RADV_STATE_ADVERTISING = 1,
+};
+typedef enum RAdvState RAdvState;
+
+struct sd_radv {
+ unsigned n_ref;
+ RAdvState state;
+
+ int ifindex;
+
+ sd_event *event;
+ int event_priority;
+
+ struct ether_addr mac_addr;
+ uint8_t hop_limit;
+ uint8_t flags;
+ uint32_t mtu;
+ uint16_t lifetime;
+
+ int fd;
+ unsigned ra_sent;
+ sd_event_source *recv_event_source;
+ sd_event_source *timeout_event_source;
+
+ unsigned n_prefixes;
+ LIST_HEAD(sd_radv_prefix, prefixes);
+};
+
+struct sd_radv_prefix {
+ unsigned n_ref;
+
+ struct {
+ uint8_t type;
+ uint8_t length;
+ uint8_t prefixlen;
+ uint8_t flags;
+ be32_t valid_lifetime;
+ be32_t preferred_lifetime;
+ uint32_t reserved;
+ struct in6_addr in6_addr;
+ } _packed_ opt;
+
+ LIST_FIELDS(struct sd_radv_prefix, prefix);
+};
+
+#define log_radv_full(level, error, fmt, ...) log_internal(level, error, __FILE__, __LINE__, __func__, "RADV: " fmt, ##__VA_ARGS__)
+#define log_radv_errno(error, fmt, ...) log_radv_full(LOG_DEBUG, error, fmt, ##__VA_ARGS__)
+#define log_radv_warning_errno(error, fmt, ...) log_radv_full(LOG_WARNING, error, fmt, ##__VA_ARGS__)
+#define log_radv(fmt, ...) log_radv_errno(0, fmt, ##__VA_ARGS__)
if (errno == EAGAIN || errno == EINTR)
return 0;
- return log_dhcp_client_errno(client, errno, "Could not receive message from UDP socket: %m");
+ return log_dhcp_client_errno(client, errno,
+ "Could not receive message from UDP socket: %m");
}
if ((size_t) len < sizeof(DHCPMessage)) {
log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
if (errno == EAGAIN || errno == EINTR)
return 0;
- log_dhcp_client(client, "Could not receive message from raw socket: %m");
-
- return -errno;
+ return log_dhcp_client_errno(client, errno,
+ "Could not receive message from raw socket: %m");
} else if ((size_t)len < sizeof(DHCPPacket))
return 0;
return (int) lease->static_route_size;
}
+int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
+ unsigned r;
+
+ assert_return(lease, -EINVAL);
+ assert_return(domains, -EINVAL);
+
+ r = strv_length(lease->search_domains);
+ if (r > 0) {
+ *domains = lease->search_domains;
+ return (int) r;
+ }
+
+ return -ENODATA;
+}
+
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
assert_return(lease, -EINVAL);
assert_return(data, -EINVAL);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
+ strv_free(lease->search_domains);
return mfree(lease);
}
r = lease_parse_u16(option, len, &lease->mtu, 68);
if (r < 0)
log_debug_errno(r, "Failed to parse MTU, ignoring: %m");
+ if (lease->mtu < DHCP_DEFAULT_MIN_SIZE) {
+ log_debug("MTU value of %" PRIu16 " too small. Using default MTU value of %d instead.", lease->mtu, DHCP_DEFAULT_MIN_SIZE);
+ lease->mtu = DHCP_DEFAULT_MIN_SIZE;
+ }
+
break;
case SD_DHCP_OPTION_DOMAIN_NAME:
break;
+ case SD_DHCP_OPTION_DOMAIN_SEARCH_LIST:
+ r = dhcp_lease_parse_search_domains(option, len, &lease->search_domains);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse Domain Search List, ignoring: %m");
+ break;
+
case SD_DHCP_OPTION_HOST_NAME:
r = lease_parse_domain(option, len, &lease->hostname);
if (r < 0) {
return 0;
}
+/* Parses compressed domain names. */
+int dhcp_lease_parse_search_domains(const uint8_t *option, size_t len, char ***domains) {
+ _cleanup_strv_free_ char **names = NULL;
+ size_t pos = 0, cnt = 0;
+ int r;
+
+ assert(domains);
+ assert_return(option && len > 0, -ENODATA);
+
+ while (pos < len) {
+ _cleanup_free_ char *name = NULL;
+ size_t n = 0, allocated = 0;
+ size_t jump_barrier = pos, next_chunk = 0;
+ bool first = true;
+
+ for (;;) {
+ uint8_t c;
+ c = option[pos++];
+
+ if (c == 0) {
+ /* End of name */
+ break;
+ } else if (c <= 63) {
+ const char *label;
+
+ /* Literal label */
+ label = (const char*) (option + pos);
+ pos += c;
+ if (pos >= len)
+ return -EBADMSG;
+
+ if (!GREEDY_REALLOC(name, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
+ return -ENOMEM;
+
+ if (first)
+ first = false;
+ else
+ name[n++] = '.';
+
+ r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
+ if (r < 0)
+ return r;
+
+ n += r;
+ } else if ((c & 0xc0) == 0xc0) {
+ /* Pointer */
+
+ uint8_t d;
+ uint16_t ptr;
+
+ if (pos >= len)
+ return -EBADMSG;
+
+ d = option[pos++];
+ ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
+
+ /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
+ if (ptr >= jump_barrier)
+ return -EBADMSG;
+ jump_barrier = ptr;
+
+ /* Save current location so we don't end up re-parsing what's parsed so far. */
+ if (next_chunk == 0)
+ next_chunk = pos;
+
+ pos = ptr;
+ } else
+ return -EBADMSG;
+ }
+
+ if (!GREEDY_REALLOC(name, allocated, n + 1))
+ return -ENOMEM;
+ name[n] = 0;
+
+ r = strv_extend(&names, name);
+ if (r < 0)
+ return r;
+
+ cnt++;
+
+ if (next_chunk != 0)
+ pos = next_chunk;
+ }
+
+ *domains = names;
+ names = NULL;
+
+ return cnt;
+}
+
int dhcp_lease_insert_private_option(sd_dhcp_lease *lease, uint8_t tag, const void *data, uint8_t len) {
struct sd_dhcp_raw_option *cur, *option;
const char *string;
uint16_t mtu;
_cleanup_free_ sd_dhcp_route **routes = NULL;
+ char **search_domains = NULL;
uint32_t t1, t2, lifetime;
int r;
if (r >= 0)
fprintf(f, "DOMAINNAME=%s\n", string);
+ r = sd_dhcp_lease_get_search_domains(lease, &search_domains);
+ if (r > 0) {
+ fputs("DOMAIN_SEARCH_LIST=", f);
+ fputstrv(f, search_domains, NULL, NULL);
+ fputs("\n", f);
+ }
+
r = sd_dhcp_lease_get_hostname(lease, &string);
if (r >= 0)
fprintf(f, "HOSTNAME=%s\n", string);
*ntp = NULL,
*mtu = NULL,
*routes = NULL,
+ *domains = NULL,
*client_id_hex = NULL,
*vendor_specific_hex = NULL,
*lifetime = NULL,
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
+ "DOMAIN_SEARCH_LIST", &domains,
"ROOT_PATH", &lease->root_path,
"ROUTES", &routes,
"CLIENTID", &client_id_hex,
log_debug_errno(r, "Failed to parse MTU %s, ignoring: %m", mtu);
}
+ if (domains) {
+ _cleanup_strv_free_ char **a = NULL;
+ a = strv_split(domains, " ");
+ if (!a)
+ return -ENOMEM;
+
+ if (!strv_isempty(a)) {
+ lease->search_domains = a;
+ a = NULL;
+ }
+ }
+
if (routes) {
r = deserialize_dhcp_routes(
&lease->static_route,
#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
+static void dhcp_lease_free(DHCPLease *lease) {
+ if (!lease)
+ return;
+
+ free(lease->client_id.data);
+ free(lease);
+}
+
/* configures the server's address and subnet, and optionally the pool's size and offset into the subnet
* the whole pool must fit into the subnet, and may not contain the first (any) nor last (broadcast) address
* moreover, the server's own address may be in the pool, and is in that case reserved in order not to
assert_return(address, -EINVAL);
assert_return(address->s_addr != INADDR_ANY, -EINVAL);
assert_return(prefixlen <= 32, -ERANGE);
- assert_return(server->address == INADDR_ANY, -EBUSY);
assert_se(in_addr_prefixlen_to_netmask(&netmask_addr, prefixlen));
netmask = netmask_addr.s_addr;
else
size = size_max;
- server->bound_leases = new0(DHCPLease*, size);
- if (!server->bound_leases)
- return -ENOMEM;
+ if (server->address != address->s_addr || server->netmask != netmask || server->pool_size != size || server->pool_offset != offset) {
+ DHCPLease *lease;
+
+ free(server->bound_leases);
+ server->bound_leases = new0(DHCPLease*, size);
+ if (!server->bound_leases)
+ return -ENOMEM;
+
+ server->pool_offset = offset;
+ server->pool_size = size;
- server->pool_offset = offset;
- server->pool_size = size;
+ server->address = address->s_addr;
+ server->netmask = netmask;
+ server->subnet = address->s_addr & netmask;
- server->address = address->s_addr;
- server->netmask = netmask;
- server->subnet = address->s_addr & netmask;
+ if (server_off >= offset && server_off - offset < size)
+ server->bound_leases[server_off - offset] = &server->invalid_lease;
- if (server_off >= offset && server_off - offset < size)
- server->bound_leases[server_off - offset] = &server->invalid_lease;
+ /* Drop any leases associated with the old address range */
+ while ((lease = hashmap_steal_first(server->leases_by_client_id)))
+ dhcp_lease_free(lease);
+ }
return 0;
}
.compare = client_id_compare_func
};
-static void dhcp_lease_free(DHCPLease *lease) {
- if (!lease)
- return;
-
- free(lease->client_id.data);
- free(lease);
-}
-
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
DHCPLease *lease;
server->address = htobe32(INADDR_ANY);
server->netmask = htobe32(INADDR_ANY);
server->ifindex = ifindex;
+
server->leases_by_client_id = hashmap_new(&client_id_hash_ops);
+ if (!server->leases_by_client_id)
+ return -ENOMEM;
+
server->default_lease_time = DIV_ROUND_UP(DHCP_DEFAULT_LEASE_TIME_USEC, USEC_PER_SEC);
server->max_lease_time = DIV_ROUND_UP(DHCP_MAX_LEASE_TIME_USEC, USEC_PER_SEC);
if (!existing_lease) {
lease = new0(DHCPLease, 1);
+ if (!lease)
+ return -ENOMEM;
lease->address = address;
lease->client_id.data = memdup(req->client_id.data,
req->client_id.length);
return sd_ipv4ll_set_address(ll, &(struct in_addr) { addr });
}
+int sd_ipv4ll_restart(sd_ipv4ll *ll) {
+ ll->address = 0;
+
+ return sd_ipv4ll_start(ll);
+}
+
#define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
int sd_ipv4ll_start(sd_ipv4ll *ll) {
***/
#include <arpa/inet.h>
+#include <linux/sockios.h>
#include "sd-lldp.h"
#include "in-addr-util.h"
#include "ndisc-internal.h"
#include "ndisc-router.h"
+#include "random-util.h"
#include "socket-util.h"
#include "string-util.h"
#include "util.h"
-#define NDISC_ROUTER_SOLICITATION_INTERVAL (4U * USEC_PER_SEC)
-#define NDISC_MAX_ROUTER_SOLICITATIONS 3U
+#define NDISC_TIMEOUT_NO_RA_USEC (NDISC_ROUTER_SOLICITATION_INTERVAL * NDISC_MAX_ROUTER_SOLICITATIONS)
static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event event, sd_ndisc_router *rt) {
assert(ndisc);
assert(nd);
nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
+ nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
+ nd->retransmit_time = 0;
nd->recv_event_source = sd_event_source_unref(nd->recv_event_source);
nd->fd = safe_close(nd->fd);
static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
_cleanup_(sd_ndisc_router_unrefp) sd_ndisc_router *rt = NULL;
sd_ndisc *nd = userdata;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
- CMSG_SPACE(sizeof(struct timeval))];
- } control = {};
- struct iovec iov = {};
- union sockaddr_union sa = {};
- struct msghdr msg = {
- .msg_name = &sa.sa,
- .msg_namelen = sizeof(sa),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg;
- ssize_t len, buflen;
+ ssize_t buflen;
+ int r;
+ _cleanup_free_ char *addr = NULL;
assert(s);
assert(nd);
if (!rt)
return -ENOMEM;
- iov.iov_base = NDISC_ROUTER_RAW(rt);
- iov.iov_len = rt->raw_size;
-
- len = recvmsg(fd, &msg, MSG_DONTWAIT);
- if (len < 0) {
- if (errno == EAGAIN || errno == EINTR)
- return 0;
-
- return log_ndisc_errno(errno, "Could not receive message from ICMPv6 socket: %m");
- }
-
- if ((size_t) len != rt->raw_size) {
- log_ndisc("Packet size mismatch.");
- return -EINVAL;
- }
-
- if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
- sa.in6.sin6_family == AF_INET6) {
-
- if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr) <= 0) {
- _cleanup_free_ char *addr = NULL;
-
- (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &sa.in6.sin6_addr, &addr);
- log_ndisc("Received RA from non-link-local address %s. Ignoring.", strna(addr));
- return 0;
- }
-
- rt->address = sa.in6.sin6_addr;
-
- } else if (msg.msg_namelen > 0) {
- log_ndisc("Received invalid source address size from ICMPv6 socket: %zu bytes", (size_t) msg.msg_namelen);
- return -EINVAL;
- }
-
- /* namelen == 0 only happens when running the test-suite over a socketpair */
-
- assert(!(msg.msg_flags & MSG_CTRUNC));
- assert(!(msg.msg_flags & MSG_TRUNC));
-
- CMSG_FOREACH(cmsg, &msg) {
- if (cmsg->cmsg_level == SOL_IPV6 &&
- cmsg->cmsg_type == IPV6_HOPLIMIT &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
- int hops = *(int*) CMSG_DATA(cmsg);
-
- if (hops != 255) {
- log_ndisc("Received RA with invalid hop limit %d. Ignoring.", hops);
- return 0;
- }
+ r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address,
+ &rt->timestamp);
+ if (r < 0) {
+ switch (r) {
+ case -EADDRNOTAVAIL:
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &rt->address, &addr);
+ log_ndisc("Received RA from non-link-local address %s. Ignoring", addr);
+ break;
+
+ case -EMULTIHOP:
+ log_ndisc("Received RA with invalid hop limit. Ignoring.");
+ break;
+
+ case -EPFNOSUPPORT:
+ log_ndisc("Received invalid source address from ICMPv6 socket.");
+ break;
}
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SO_TIMESTAMP &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
- triple_timestamp_from_realtime(&rt->timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
+ return 0;
}
- if (!triple_timestamp_is_set(&rt->timestamp))
- triple_timestamp_get(&rt->timestamp);
-
nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
return ndisc_handle_datagram(nd, rt);
}
+static usec_t ndisc_timeout_compute_random(usec_t val) {
+ /* compute a time that is random within ±10% of the given value */
+ return val - val / 10 +
+ (random_u64() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
+}
+
static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
sd_ndisc *nd = userdata;
- usec_t time_now, next_timeout;
+ usec_t time_now;
int r;
+ char time_string[FORMAT_TIMESPAN_MAX];
assert(s);
assert(nd);
assert(nd->event);
- if (nd->nd_sent >= NDISC_MAX_ROUTER_SOLICITATIONS) {
- nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
- ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
- return 0;
+ assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
+
+ nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source);
+
+ if (!nd->retransmit_time)
+ nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL);
+ else {
+ if (nd->retransmit_time > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 2)
+ nd->retransmit_time = ndisc_timeout_compute_random(NDISC_MAX_ROUTER_SOLICITATION_INTERVAL);
+ else
+ nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time);
}
- r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
- if (r < 0) {
- log_ndisc_errno(r, "Error sending Router Solicitation: %m");
+ r = sd_event_add_time(nd->event, &nd->timeout_event_source,
+ clock_boottime_or_monotonic(),
+ time_now + nd->retransmit_time,
+ 10 * USEC_PER_MSEC, ndisc_timeout, nd);
+ if (r < 0)
goto fail;
- }
- log_ndisc("Sent Router Solicitation");
- nd->nd_sent++;
+ r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority);
+ if (r < 0)
+ goto fail;
- assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0);
- next_timeout = time_now + NDISC_ROUTER_SOLICITATION_INTERVAL;
+ (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout-no-ra");
- r = sd_event_source_set_time(nd->timeout_event_source, next_timeout);
+ r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
if (r < 0) {
- log_ndisc_errno(r, "Error updating timer: %m");
+ log_ndisc_errno(r, "Error reenabling timer: %m");
goto fail;
}
- r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT);
+ r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
if (r < 0) {
- log_ndisc_errno(r, "Error reenabling timer: %m");
+ log_ndisc_errno(r, "Error sending Router Solicitation: %m");
goto fail;
}
+ log_ndisc("Sent Router Solicitation, next solicitation in %s",
+ format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+ nd->retransmit_time, USEC_PER_SEC));
+
return 0;
fail:
return 0;
}
+static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata) {
+ sd_ndisc *nd = userdata;
+
+ assert(s);
+ assert(nd);
+
+ log_ndisc("No RA received before link confirmation timeout");
+
+ nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra);
+ ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);
+
+ return 0;
+}
+
_public_ int sd_ndisc_stop(sd_ndisc *nd) {
assert_return(nd, -EINVAL);
_public_ int sd_ndisc_start(sd_ndisc *nd) {
int r;
+ usec_t time_now;
assert_return(nd, -EINVAL);
assert_return(nd->event, -EINVAL);
assert(!nd->recv_event_source);
assert(!nd->timeout_event_source);
+ r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0)
+ goto fail;
+
nd->fd = icmp6_bind_router_solicitation(nd->ifindex);
if (nd->fd < 0)
return nd->fd;
(void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout");
+ r = sd_event_add_time(nd->event, &nd->timeout_no_ra,
+ clock_boottime_or_monotonic(),
+ time_now + NDISC_TIMEOUT_NO_RA_USEC,
+ 10 * USEC_PER_MSEC, ndisc_timeout_no_ra, nd);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(nd->timeout_no_ra, nd->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(nd->timeout_no_ra, "ndisc-timeout-no-ra");
+
log_ndisc("Started IPv6 Router Solicitation client");
return 1;
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/icmp6.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <linux/in6.h>
+
+#include "sd-radv.h"
+
+#include "macro.h"
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "icmp6-util.h"
+#include "in-addr-util.h"
+#include "radv-internal.h"
+#include "socket-util.h"
+#include "string-util.h"
+#include "util.h"
+#include "random-util.h"
+
+_public_ int sd_radv_new(sd_radv **ret) {
+ _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL;
+
+ assert_return(ret, -EINVAL);
+
+ ra = new0(sd_radv, 1);
+ if (!ra)
+ return -ENOMEM;
+
+ ra->n_ref = 1;
+ ra->fd = -1;
+
+ LIST_HEAD_INIT(ra->prefixes);
+
+ *ret = ra;
+ ra = NULL;
+
+ return 0;
+}
+
+_public_ int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority) {
+ int r;
+
+ assert_return(ra, -EINVAL);
+ assert_return(!ra->event, -EBUSY);
+
+ if (event)
+ ra->event = sd_event_ref(event);
+ else {
+ r = sd_event_default(&ra->event);
+ if (r < 0)
+ return 0;
+ }
+
+ ra->event_priority = priority;
+
+ return 0;
+}
+
+_public_ int sd_radv_detach_event(sd_radv *ra) {
+
+ assert_return(ra, -EINVAL);
+
+ ra->event = sd_event_unref(ra->event);
+ return 0;
+}
+
+_public_ sd_event *sd_radv_get_event(sd_radv *ra) {
+ assert_return(ra, NULL);
+
+ return ra->event;
+}
+
+static void radv_reset(sd_radv *ra) {
+
+ ra->timeout_event_source =
+ sd_event_source_unref(ra->timeout_event_source);
+
+ ra->recv_event_source =
+ sd_event_source_unref(ra->recv_event_source);
+
+ ra->ra_sent = 0;
+}
+
+_public_ sd_radv *sd_radv_ref(sd_radv *ra) {
+ if (!ra)
+ return NULL;
+
+ assert(ra->n_ref > 0);
+ ra->n_ref++;
+
+ return ra;
+}
+
+_public_ sd_radv *sd_radv_unref(sd_radv *ra) {
+ if (!ra)
+ return NULL;
+
+ assert(ra->n_ref > 0);
+ ra->n_ref--;
+
+ if (ra->n_ref > 0)
+ return NULL;
+
+ while (ra->prefixes) {
+ sd_radv_prefix *p = ra->prefixes;
+
+ LIST_REMOVE(prefix, ra->prefixes, p);
+ sd_radv_prefix_unref(p);
+ }
+
+ radv_reset(ra);
+
+ sd_radv_detach_event(ra);
+ return mfree(ra);
+}
+
+static int radv_send(sd_radv *ra, const struct in6_addr *dst,
+ const uint32_t router_lifetime) {
+ static const struct ether_addr mac_zero = {};
+ sd_radv_prefix *p;
+ struct sockaddr_in6 dst_addr = {
+ .sin6_family = AF_INET6,
+ .sin6_addr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
+ };
+ struct nd_router_advert adv = {};
+ struct {
+ struct nd_opt_hdr opthdr;
+ struct ether_addr slladdr;
+ } _packed_ opt_mac = {
+ .opthdr = {
+ .nd_opt_type = ND_OPT_SOURCE_LINKADDR,
+ .nd_opt_len = (sizeof(struct nd_opt_hdr) +
+ sizeof(struct ether_addr) - 1) /8 + 1,
+ },
+ };
+ struct nd_opt_mtu opt_mtu = {
+ .nd_opt_mtu_type = ND_OPT_MTU,
+ .nd_opt_mtu_len = 1,
+ };
+ /* Reserve iov space for RA header, linkaddr, MTU + N prefixes */
+ struct iovec iov[3 + ra->n_prefixes];
+ struct msghdr msg = {
+ .msg_name = &dst_addr,
+ .msg_namelen = sizeof(dst_addr),
+ .msg_iov = iov,
+ };
+
+ if (dst && !in_addr_is_null(AF_INET6, (union in_addr_union*) dst))
+ dst_addr.sin6_addr = *dst;
+
+ adv.nd_ra_type = ND_ROUTER_ADVERT;
+ adv.nd_ra_curhoplimit = ra->hop_limit;
+ adv.nd_ra_flags_reserved = ra->flags;
+ adv.nd_ra_router_lifetime = htobe16(router_lifetime);
+ iov[msg.msg_iovlen].iov_base = &adv;
+ iov[msg.msg_iovlen].iov_len = sizeof(adv);
+ msg.msg_iovlen++;
+
+ /* MAC address is optional, either because the link does not use L2
+ addresses or load sharing is desired. See RFC 4861, Section 4.2 */
+ if (memcmp(&mac_zero, &ra->mac_addr, sizeof(mac_zero))) {
+ opt_mac.slladdr = ra->mac_addr;
+ iov[msg.msg_iovlen].iov_base = &opt_mac;
+ iov[msg.msg_iovlen].iov_len = sizeof(opt_mac);
+ msg.msg_iovlen++;
+ }
+
+ if (ra->mtu) {
+ opt_mtu.nd_opt_mtu_mtu = htobe32(ra->mtu);
+ iov[msg.msg_iovlen].iov_base = &opt_mtu;
+ iov[msg.msg_iovlen].iov_len = sizeof(opt_mtu);
+ msg.msg_iovlen++;
+ }
+
+ LIST_FOREACH(prefix, p, ra->prefixes) {
+ iov[msg.msg_iovlen].iov_base = &p->opt;
+ iov[msg.msg_iovlen].iov_len = sizeof(p->opt);
+ msg.msg_iovlen++;
+ }
+
+ if (sendmsg(ra->fd, &msg, 0) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ sd_radv *ra = userdata;
+ _cleanup_free_ char *addr = NULL;
+ struct in6_addr src;
+ triple_timestamp timestamp;
+ int r;
+ ssize_t buflen;
+ _cleanup_free_ char *buf = NULL;
+
+ assert(s);
+ assert(ra);
+ assert(ra->event);
+
+ buflen = next_datagram_size_fd(fd);
+
+ if ((unsigned) buflen < sizeof(struct nd_router_solicit))
+ return log_radv("Too short packet received");
+
+ buf = new0(char, buflen);
+ if (!buf)
+ return 0;
+
+ r = icmp6_receive(fd, buf, buflen, &src, ×tamp);
+ if (r < 0) {
+ switch (r) {
+ case -EADDRNOTAVAIL:
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
+ log_radv("Received RS from non-link-local address %s. Ignoring", addr);
+ break;
+
+ case -EMULTIHOP:
+ log_radv("Received RS with invalid hop limit. Ignoring.");
+ break;
+
+ case -EPFNOSUPPORT:
+ log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
+ break;
+
+ default:
+ log_radv_warning_errno(r, "Error receiving from ICMPv6 socket: %m");
+ break;
+ }
+
+ return 0;
+ }
+
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr);
+
+ r = radv_send(ra, &src, ra->lifetime);
+ if (r < 0)
+ log_radv_warning_errno(r, "Unable to send solicited Router Advertisment to %s: %m", addr);
+ else
+ log_radv("Sent solicited Router Advertisement to %s", addr);
+
+ return 0;
+}
+
+static usec_t radv_compute_timeout(usec_t min, usec_t max) {
+ assert_return(min <= max, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC);
+
+ return min + (random_u32() % (max - min));
+}
+
+static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
+ int r;
+ sd_radv *ra = userdata;
+ usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC;
+ usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC;
+ usec_t time_now, timeout;
+ char time_string[FORMAT_TIMESPAN_MAX];
+
+ assert(s);
+ assert(ra);
+ assert(ra->event);
+
+ ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source);
+
+ r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0)
+ goto fail;
+
+ r = radv_send(ra, NULL, ra->lifetime);
+ if (r < 0)
+ log_radv_warning_errno(r, "Unable to send Router Advertisement: %m");
+
+ /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
+ if (ra->ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS) {
+ max_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC;
+ min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3;
+ }
+
+ timeout = radv_compute_timeout(min_timeout, max_timeout);
+
+ log_radv("Next Router Advertisement in %s",
+ format_timespan(time_string, FORMAT_TIMESPAN_MAX,
+ timeout, USEC_PER_SEC));
+
+ r = sd_event_add_time(ra->event, &ra->timeout_event_source,
+ clock_boottime_or_monotonic(),
+ time_now + timeout, MSEC_PER_SEC,
+ radv_timeout, ra);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(ra->timeout_event_source,
+ ra->event_priority);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_description(ra->timeout_event_source,
+ "radv-timeout");
+ if (r < 0)
+ goto fail;
+
+ ra->ra_sent++;
+
+fail:
+ if (r < 0)
+ sd_radv_stop(ra);
+
+ return 0;
+}
+
+_public_ int sd_radv_stop(sd_radv *ra) {
+ int r;
+
+ assert_return(ra, -EINVAL);
+
+ log_radv("Stopping IPv6 Router Advertisement daemon");
+
+ /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
+ with zero lifetime */
+ r = radv_send(ra, NULL, 0);
+ if (r < 0)
+ log_radv_warning_errno(r, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
+
+ radv_reset(ra);
+ ra->fd = safe_close(ra->fd);
+ ra->state = SD_RADV_STATE_IDLE;
+
+ return 0;
+}
+
+_public_ int sd_radv_start(sd_radv *ra) {
+ int r = 0;
+
+ assert_return(ra, -EINVAL);
+ assert_return(ra->event, -EINVAL);
+ assert_return(ra->ifindex > 0, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return 0;
+
+ r = sd_event_add_time(ra->event, &ra->timeout_event_source,
+ clock_boottime_or_monotonic(), 0, 0,
+ radv_timeout, ra);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(ra->timeout_event_source,
+ ra->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(ra->timeout_event_source,
+ "radv-timeout");
+
+ r = icmp6_bind_router_advertisement(ra->ifindex);
+ if (r < 0)
+ goto fail;
+
+ ra->fd = r;
+
+ r = sd_event_add_io(ra->event, &ra->recv_event_source, ra->fd, EPOLLIN, radv_recv, ra);
+ if (r < 0)
+ goto fail;
+
+ r = sd_event_source_set_priority(ra->recv_event_source, ra->event_priority);
+ if (r < 0)
+ goto fail;
+
+ (void) sd_event_source_set_description(ra->recv_event_source, "radv-receive-message");
+
+ ra->state = SD_RADV_STATE_ADVERTISING;
+
+ log_radv("Started IPv6 Router Advertisement daemon");
+
+ return 0;
+
+ fail:
+ radv_reset(ra);
+
+ return r;
+}
+
+_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
+ assert_return(ra, -EINVAL);
+ assert_return(ifindex >= -1, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ ra->ifindex = ifindex;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ if (mac_addr)
+ ra->mac_addr = *mac_addr;
+ else
+ zero(ra->mac_addr);
+
+ return 0;
+}
+
+_public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) {
+ assert_return(ra, -EINVAL);
+ assert_return(mtu >= 1280, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ ra->mtu = mtu;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ ra->hop_limit = hop_limit;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
+ preference value MUST be set to (00) by the sender..." */
+ if (router_lifetime == 0 &&
+ (ra->flags & (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM << 3))
+ return -ETIME;
+
+ ra->lifetime = router_lifetime;
+
+ return 0;
+}
+
+_public_ int sd_radv_set_managed_information(sd_radv *ra, int managed) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ SET_FLAG(ra->flags, ND_RA_FLAG_MANAGED, managed);
+
+ return 0;
+}
+
+_public_ int sd_radv_set_other_information(sd_radv *ra, int other) {
+ assert_return(ra, -EINVAL);
+
+ if (ra->state != SD_RADV_STATE_IDLE)
+ return -EBUSY;
+
+ SET_FLAG(ra->flags, ND_RA_FLAG_OTHER, other);
+
+ return 0;
+}
+
+_public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
+ int r = 0;
+
+ assert_return(ra, -EINVAL);
+ assert_return(IN_SET(preference,
+ SD_NDISC_PREFERENCE_LOW,
+ SD_NDISC_PREFERENCE_MEDIUM,
+ SD_NDISC_PREFERENCE_HIGH), -EINVAL);
+
+ ra->flags = (ra->flags & ~(0x3 << 3)) | (preference << 3);
+
+ return r;
+}
+
+_public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) {
+ sd_radv_prefix *cur;
+ _cleanup_free_ char *addr_p = NULL;
+
+ assert_return(ra, -EINVAL);
+
+ if (!p)
+ return -EINVAL;
+
+ LIST_FOREACH(prefix, cur, ra->prefixes) {
+ int r;
+
+ r = in_addr_prefix_intersect(AF_INET6,
+ (union in_addr_union*) &cur->opt.in6_addr,
+ cur->opt.prefixlen,
+ (union in_addr_union*) &p->opt.in6_addr,
+ p->opt.prefixlen);
+ if (r > 0) {
+ _cleanup_free_ char *addr_cur = NULL;
+
+ (void) in_addr_to_string(AF_INET6,
+ (union in_addr_union*) &cur->opt.in6_addr,
+ &addr_cur);
+ (void) in_addr_to_string(AF_INET6,
+ (union in_addr_union*) &p->opt.in6_addr,
+ &addr_p);
+
+ log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
+ addr_cur, cur->opt.prefixlen,
+ addr_p, p->opt.prefixlen);
+
+ return -EEXIST;
+ }
+ }
+
+ p = sd_radv_prefix_ref(p);
+
+ LIST_APPEND(prefix, ra->prefixes, p);
+
+ ra->n_prefixes++;
+
+ (void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p);
+ log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_new(sd_radv_prefix **ret) {
+ _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
+
+ assert_return(ret, -EINVAL);
+
+ p = new0(sd_radv_prefix, 1);
+ if (!p)
+ return -ENOMEM;
+
+ p->n_ref = 1;
+
+ p->opt.type = ND_OPT_PREFIX_INFORMATION;
+ p->opt.length = (sizeof(p->opt) - 1) /8 + 1;
+
+ p->opt.prefixlen = 64;
+
+ /* RFC 4861, Section 6.2.1 */
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, true);
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, true);
+ p->opt.preferred_lifetime = htobe32(604800);
+ p->opt.valid_lifetime = htobe32(2592000);
+
+ LIST_INIT(prefix, p);
+
+ *ret = p;
+ p = NULL;
+
+ return 0;
+}
+
+_public_ sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *p) {
+ if (!p)
+ return NULL;
+
+ assert(p->n_ref > 0);
+ p->n_ref++;
+
+ return p;
+}
+
+_public_ sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *p) {
+ if (!p)
+ return NULL;
+
+ assert(p->n_ref > 0);
+ p->n_ref--;
+
+ if (p->n_ref > 0)
+ return NULL;
+
+ return mfree(p);
+}
+
+_public_ int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
+ unsigned char prefixlen) {
+ assert_return(p, -EINVAL);
+ assert_return(in6_addr, -EINVAL);
+
+ if (prefixlen < 3 || prefixlen > 128)
+ return -EINVAL;
+
+ if (prefixlen > 64)
+ /* unusual but allowed, log it */
+ log_radv("Unusual prefix length %d greater than 64", prefixlen);
+
+ p->opt.in6_addr = *in6_addr;
+ p->opt.prefixlen = prefixlen;
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink) {
+ assert_return(p, -EINVAL);
+
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_ONLINK, onlink);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
+ int address_autoconfiguration) {
+ assert_return(p, -EINVAL);
+
+ SET_FLAG(p->opt.flags, ND_OPT_PI_FLAG_AUTO, address_autoconfiguration);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
+ uint32_t valid_lifetime) {
+ assert_return(p, -EINVAL);
+
+ p->opt.valid_lifetime = htobe32(valid_lifetime);
+
+ return 0;
+}
+
+_public_ int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
+ uint32_t preferred_lifetime) {
+ assert_return(p, -EINVAL);
+
+ p->opt.preferred_lifetime = htobe32(preferred_lifetime);
+
+ return 0;
+}
assert_se(sd_dhcp_server_configure_pool(server, &address_any, 28, 0, 0) == -EINVAL);
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 38, 0, 0) == -ERANGE);
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
- assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) == -EBUSY);
+ assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
test_pool(&address_any, 1, -EINVAL);
test_pool(&address_lo, 1, 0);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
be32_t pa, const struct ether_addr *ha) {
struct ether_arp ea = {};
- assert(fd >= 0);
- assert(ifindex > 0);
- assert(pa != 0);
- assert(ha);
+ assert_se(fd >= 0);
+ assert_se(ifindex > 0);
+ assert_se(pa != 0);
+ assert_se(ha);
return arp_network_send_raw_socket(fd, ifindex, &ea);
}
be32_t pa, const struct ether_addr *ha) {
struct ether_arp ea = {};
- assert(fd >= 0);
- assert(ifindex > 0);
- assert(pa != 0);
- assert(ha);
+ assert_se(fd >= 0);
+ assert_se(ifindex > 0);
+ assert_se(pa != 0);
+ assert_se(ha);
return arp_network_send_raw_socket(fd, ifindex, &ea);
}
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/icmp6.h>
+#include <arpa/inet.h>
+
+#include "sd-radv.h"
+
+#include "alloc-util.h"
+#include "hexdecoct.h"
+#include "icmp6-util.h"
+#include "socket-util.h"
+#include "strv.h"
+
+static struct ether_addr mac_addr = {
+ .ether_addr_octet = { 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 }
+};
+
+static uint8_t advertisement[] = {
+ /* ICMPv6 Router Advertisement, no checksum */
+ 0x86, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x00, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Source Link Layer Address Option */
+ 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
+ /* Prefix Information Option */
+ 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
+ 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Prefix Information Option */
+ 0x03, 0x04, 0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00,
+ 0x00, 0x09, 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Prefix Information Option */
+ 0x03, 0x04, 0x30, 0xc0, 0x00, 0x27, 0x8d, 0x00,
+ 0x00, 0x09, 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* Recursive DNS Server Option - not yet supported */
+ 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ /* DNS Search List Option - not yet supported */
+ 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
+ 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
+ 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static sd_event_source *test_hangcheck;
+static bool test_stopped;
+static int test_fd[2];
+static sd_event_source *recv_router_advertisement;
+static struct {
+ struct in6_addr address;
+ unsigned char prefixlen;
+ uint32_t valid;
+ uint32_t preferred;
+ bool succesful;
+} prefix[] = {
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
+ 500, 440, true },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
+ /* indicate default valid and preferred lifetimes for the test code */
+ 0, 0, true },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 58,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 120,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 12,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 48,
+ 0, 0, true },
+ { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60,
+ 0, 0,
+ /* indicate that this prefix already exists */
+ false },
+};
+
+static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
+ void *userdata) {
+ assert_se(false);
+
+ return 0;
+}
+
+static void test_radv_prefix(void) {
+ sd_radv_prefix *p;
+
+ printf("* %s\n", __FUNCTION__);
+
+ assert_se(sd_radv_prefix_new(&p) >= 0);
+
+ assert_se(sd_radv_prefix_set_onlink(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_onlink(p, true) >= 0);
+ assert_se(sd_radv_prefix_set_onlink(p, false) >= 0);
+
+ assert_se(sd_radv_prefix_set_address_autoconfiguration(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_address_autoconfiguration(p, true) >= 0);
+ assert_se(sd_radv_prefix_set_address_autoconfiguration(p, false) >= 0);
+
+ assert_se(sd_radv_prefix_set_valid_lifetime(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, ~0) >= 0);
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, 42) >= 0);
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, 0) >= 0);
+
+ assert_se(sd_radv_prefix_set_preferred_lifetime(NULL, true) < 0);
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, ~0) >= 0);
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, 42) >= 0);
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, 0) >= 0);
+
+ assert_se(sd_radv_prefix_set_prefix(NULL, NULL, 0) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, NULL, 0) < 0);
+
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 64) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 0) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 1) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 2) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 3) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 125) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 128) >= 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 129) < 0);
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 255) < 0);
+
+ p = sd_radv_prefix_unref(p);
+ assert_se(!p);
+}
+
+static void test_radv(void) {
+ sd_radv *ra;
+
+ printf("* %s\n", __FUNCTION__);
+
+ assert_se(sd_radv_new(&ra) >= 0);
+ assert_se(ra);
+
+ assert_se(sd_radv_set_ifindex(NULL, 0) < 0);
+ assert_se(sd_radv_set_ifindex(ra, 0) >= 0);
+ assert_se(sd_radv_set_ifindex(ra, -1) >= 0);
+ assert_se(sd_radv_set_ifindex(ra, -2) < 0);
+ assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
+
+ assert_se(sd_radv_set_mac(NULL, NULL) < 0);
+ assert_se(sd_radv_set_mac(ra, NULL) >= 0);
+ assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
+
+ assert_se(sd_radv_set_mtu(NULL, 0) < 0);
+ assert_se(sd_radv_set_mtu(ra, 0) < 0);
+ assert_se(sd_radv_set_mtu(ra, 1279) < 0);
+ assert_se(sd_radv_set_mtu(ra, 1280) >= 0);
+ assert_se(sd_radv_set_mtu(ra, ~0) >= 0);
+
+ assert_se(sd_radv_set_hop_limit(NULL, 0) < 0);
+ assert_se(sd_radv_set_hop_limit(ra, 0) >= 0);
+ assert_se(sd_radv_set_hop_limit(ra, ~0) >= 0);
+
+ assert_se(sd_radv_set_router_lifetime(NULL, 0) < 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, ~0) >= 0);
+
+ assert_se(sd_radv_set_preference(NULL, 0) < 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_LOW) >= 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
+ assert_se(sd_radv_set_preference(ra, ~0) < 0);
+
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 42000) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 0) < 0);
+ assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
+
+ assert_se(sd_radv_set_managed_information(NULL, true) < 0);
+ assert_se(sd_radv_set_managed_information(ra, true) >= 0);
+ assert_se(sd_radv_set_managed_information(ra, false) >= 0);
+
+ assert_se(sd_radv_set_other_information(NULL, true) < 0);
+ assert_se(sd_radv_set_other_information(ra, true) >= 0);
+ assert_se(sd_radv_set_other_information(ra, false) >= 0);
+
+ ra = sd_radv_unref(ra);
+ assert_se(!ra);
+}
+
+int icmp6_bind_router_solicitation(int index) {
+ return -ENOSYS;
+}
+
+int icmp6_bind_router_advertisement(int index) {
+ assert_se(index == 42);
+
+ return test_fd[1];
+}
+
+int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+
+ return 0;
+}
+
+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
+ struct in6_addr *dst, triple_timestamp *timestamp) {
+ assert_se(read (fd, iov_base, iov_len) == (ssize_t)iov_len);
+
+ if (timestamp)
+ triple_timestamp_get(timestamp);
+
+ return 0;
+}
+
+static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+ sd_radv *ra = userdata;
+ unsigned char buf[120];
+ size_t i;
+
+ read(test_fd[0], &buf, sizeof(buf));
+
+ /* router lifetime must be zero when test is stopped */
+ if (test_stopped) {
+ advertisement[6] = 0x00;
+ advertisement[7] = 0x00;
+ }
+
+ printf ("Received Router Advertisement with lifetime %u\n",
+ (advertisement[6] << 8) + advertisement[7]);
+
+ /* test only up to buf size, rest is not yet implemented */
+ for (i = 0; i < sizeof(buf); i++) {
+ printf("0x%02x", buf[i]);
+
+ assert_se(buf[i] == advertisement[i]);
+
+ if ((i + 1) % 8)
+ printf(", ");
+ else
+ printf("\n");
+ }
+
+ if (test_stopped) {
+ sd_event *e;
+
+ e = sd_radv_get_event(ra);
+ sd_event_exit(e, 0);
+
+ return 0;
+ }
+
+ assert_se(sd_radv_stop(ra) >= 0);
+ test_stopped = true;
+
+ return 0;
+}
+
+static void test_ra(void) {
+ sd_event *e;
+ sd_radv *ra;
+ usec_t time_now = now(clock_boottime_or_monotonic());
+ unsigned int i;
+
+ printf("* %s\n", __FUNCTION__);
+
+ assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, test_fd) >= 0);
+
+ assert_se(sd_event_new(&e) >= 0);
+
+ assert_se(sd_radv_new(&ra) >= 0);
+ assert_se(ra);
+
+ assert_se(sd_radv_attach_event(ra, e, 0) >= 0);
+
+ assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
+ assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
+ assert_se(sd_radv_set_router_lifetime(ra, 180) >= 0);
+ assert_se(sd_radv_set_hop_limit(ra, 64) >= 0);
+ assert_se(sd_radv_set_managed_information(ra, true) >= 0);
+ assert_se(sd_radv_set_other_information(ra, true) >= 0);
+
+ for (i = 0; i < ELEMENTSOF(prefix); i++) {
+ sd_radv_prefix *p;
+
+ printf("Test prefix %u\n", i);
+ assert_se(sd_radv_prefix_new(&p) >= 0);
+
+ assert_se(sd_radv_prefix_set_prefix(p, &prefix[i].address,
+ prefix[i].prefixlen) >= 0);
+ if (prefix[i].valid)
+ assert_se(sd_radv_prefix_set_valid_lifetime(p, prefix[i].valid) >= 0);
+ if (prefix[i].preferred)
+ assert_se(sd_radv_prefix_set_preferred_lifetime(p, prefix[i].preferred) >= 0);
+
+ assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].succesful);
+ assert_se(sd_radv_add_prefix(ra, p) < 0);
+
+ p = sd_radv_prefix_unref(p);
+ assert_se(!p);
+ }
+
+ assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0],
+ EPOLLIN, radv_recv, ra) >= 0);
+
+ assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
+ time_now + 2 *USEC_PER_SEC, 0,
+ test_rs_hangcheck, NULL) >= 0);
+
+ assert_se(sd_radv_start(ra) >= 0);
+
+ sd_event_loop(e);
+
+ test_hangcheck = sd_event_source_unref(test_hangcheck);
+
+ ra = sd_radv_unref(ra);
+ assert_se(!ra);
+
+ close(test_fd[0]);
+
+ sd_event_unref(e);
+}
+
+int main(int argc, char *argv[]) {
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_radv_prefix();
+ test_radv();
+ test_ra();
+
+ printf("* done\n");
+ return 0;
+}
#include "icmp6-util.h"
#include "socket-util.h"
#include "strv.h"
+#include "ndisc-internal.h"
static struct ether_addr mac_addr = {
.ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
static bool verbose = false;
static sd_event_source *test_hangcheck;
static int test_fd[2];
+static sd_ndisc *test_timeout_nd;
typedef int (*send_ra_t)(uint8_t flags);
static send_ra_t send_ra_function;
return test_fd[0];
}
+int icmp6_bind_router_advertisement(int index) {
+
+ return -ENOSYS;
+}
+
+int icmp6_receive(int fd, void *iov_base, size_t iov_len,
+ struct in6_addr *dst, triple_timestamp *timestamp) {
+ assert (read (fd, iov_base, iov_len) == (ssize_t)iov_len);
+
+ if (timestamp)
+ triple_timestamp_get(timestamp);
+
+ return 0;
+}
+
static int send_ra(uint8_t flags) {
uint8_t advertisement[] = {
0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4,
}
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
+ if (!send_ra_function)
+ return 0;
+
return send_ra_function(0);
}
sd_event_unref(e);
}
+static int test_timeout_value(uint8_t flags) {
+ static int count = 0;
+ static usec_t last = 0;
+ sd_ndisc *nd = test_timeout_nd;
+ usec_t min, max;
+ char time_string_min[FORMAT_TIMESPAN_MAX];
+ char time_string_nd[FORMAT_TIMESPAN_MAX];
+ char time_string_max[FORMAT_TIMESPAN_MAX];
+
+ assert_se(nd);
+ assert_se(nd->event);
+
+ if (++count >= 20)
+ sd_event_exit(nd->event, 0);
+
+ if (last == 0) {
+ /* initial RT = IRT + RAND*IRT */
+ min = NDISC_ROUTER_SOLICITATION_INTERVAL -
+ NDISC_ROUTER_SOLICITATION_INTERVAL / 10;
+ max = NDISC_ROUTER_SOLICITATION_INTERVAL +
+ NDISC_ROUTER_SOLICITATION_INTERVAL / 10;
+ } else {
+ /* next RT = 2*RTprev + RAND*RTprev */
+ min = 2 * last - last / 10;
+ max = 2 * last + last / 10;
+ }
+
+ /* final RT > MRT */
+ if (last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL) {
+ min = NDISC_MAX_ROUTER_SOLICITATION_INTERVAL -
+ NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10;
+ max = NDISC_MAX_ROUTER_SOLICITATION_INTERVAL +
+ NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10;
+ }
+
+ format_timespan(time_string_min, FORMAT_TIMESPAN_MAX,
+ min, USEC_PER_MSEC);
+ format_timespan(time_string_nd, FORMAT_TIMESPAN_MAX,
+ nd->retransmit_time, USEC_PER_MSEC);
+ format_timespan(time_string_max, FORMAT_TIMESPAN_MAX,
+ max, USEC_PER_MSEC);
+
+ log_info("backoff timeout interval %2d %s%s <= %s <= %s",
+ count,
+ (last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL)? "(max) ": "",
+ time_string_min, time_string_nd, time_string_max);
+
+ assert_se(min <= nd->retransmit_time);
+ assert_se(max >= nd->retransmit_time);
+
+ last = nd->retransmit_time;
+
+ assert_se(sd_event_source_set_time(nd->timeout_event_source, 0) >= 0);
+
+ return 0;
+}
+
+static void test_timeout(void) {
+ sd_event *e;
+ sd_ndisc *nd;
+ usec_t time_now = now(clock_boottime_or_monotonic());
+
+ if (verbose)
+ printf("* %s\n", __FUNCTION__);
+
+ send_ra_function = test_timeout_value;
+
+ assert_se(sd_event_new(&e) >= 0);
+
+ assert_se(sd_ndisc_new(&nd) >= 0);
+ assert_se(nd);
+
+ test_timeout_nd = nd;
+
+ assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0);
+
+ assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0);
+ assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0);
+
+ assert_se(sd_event_add_time(e, &test_hangcheck, clock_boottime_or_monotonic(),
+ time_now + 2U * USEC_PER_SEC, 0,
+ test_rs_hangcheck, NULL) >= 0);
+
+ assert_se(sd_ndisc_start(nd) >= 0);
+
+ sd_event_loop(e);
+
+ test_hangcheck = sd_event_source_unref(test_hangcheck);
+
+ nd = sd_ndisc_unref(nd);
+
+ sd_event_unref(e);
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
log_open();
test_rs();
+ test_timeout();
return 0;
}
--- /dev/null
+#include <errno.h>
+
+#include "dhcp-lease-internal.h"
+#include "macro.h"
+#include "string-util.h"
+#include "strv.h"
+
+/* According to RFC1035 section 4.1.4, a domain name in a message can be either:
+ * - a sequence of labels ending in a zero octet
+ * - a pointer
+ * - a sequence of labels ending with a pointer
+ */
+static void test_dhcp_lease_parse_search_domains_basic(void) {
+ int r;
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
+ 0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00,
+ };
+
+ r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
+ assert_se(r == 2);
+ assert_se(streq(domains[0], "FOO.BAR"));
+ assert_se(streq(domains[1], "ABCD.EFG"));
+}
+
+static void test_dhcp_lease_parse_search_domains_ptr(void) {
+ int r;
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x00, 0xC0, 0x00,
+ };
+
+ r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
+ assert_se(r == 2);
+ assert_se(streq(domains[0], "FOO"));
+ assert_se(streq(domains[1], "FOO"));
+}
+
+static void test_dhcp_lease_parse_search_domains_labels_and_ptr(void) {
+ int r;
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
+ 0x03, 'A', 'B', 'C', 0xC0, 0x04,
+ };
+
+ r = dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains);
+ assert_se(r == 2);
+ assert_se(streq(domains[0], "FOO.BAR"));
+ assert_se(streq(domains[1], "ABC.BAR"));
+}
+
+/* Tests for exceptions. */
+
+static void test_dhcp_lease_parse_search_domains_no_data(void) {
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[3] = {0, 0, 0};
+
+ assert_se(dhcp_lease_parse_search_domains(NULL, 0, &domains) == -ENODATA);
+ assert_se(dhcp_lease_parse_search_domains(optionbuf, 0, &domains) == -ENODATA);
+}
+
+static void test_dhcp_lease_parse_search_domains_loops(void) {
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x00, 0x03, 'B', 'A', 'R', 0xC0, 0x06,
+ };
+
+ assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf), &domains) == -EBADMSG);
+}
+
+static void test_dhcp_lease_parse_search_domains_wrong_len(void) {
+ _cleanup_strv_free_ char **domains = NULL;
+ static const uint8_t optionbuf[] = {
+ 0x03, 'F', 'O', 'O', 0x03, 'B', 'A', 'R', 0x00,
+ 0x04, 'A', 'B', 'C', 'D', 0x03, 'E', 'F', 'G', 0x00,
+ };
+
+ assert_se(dhcp_lease_parse_search_domains(optionbuf, sizeof(optionbuf) - 5, &domains) == -EBADMSG);
+}
+
+int main(int argc, char *argv[]) {
+ test_dhcp_lease_parse_search_domains_basic();
+ test_dhcp_lease_parse_search_domains_ptr();
+ test_dhcp_lease_parse_search_domains_labels_and_ptr();
+ test_dhcp_lease_parse_search_domains_no_data();
+ test_dhcp_lease_parse_search_domains_loops();
+ test_dhcp_lease_parse_search_domains_wrong_len();
+}
sd_id128_get_machine_app_specific;
sd_is_socket_sockaddr;
} LIBSYSTEMD_232;
+
+LIBSYSTEMD_234 {
+global:
+ sd_bus_message_appendv;
+} LIBSYSTEMD_233;
--- /dev/null
+sd_login_c = files('sd-login/sd-login.c')
+
+libsystemd_internal_sources = files('''
+ sd-bus/bus-bloom.c
+ sd-bus/bus-bloom.h
+ sd-bus/bus-common-errors.c
+ sd-bus/bus-common-errors.h
+ sd-bus/bus-container.c
+ sd-bus/bus-container.h
+ sd-bus/bus-control.c
+ sd-bus/bus-control.h
+ sd-bus/bus-convenience.c
+ sd-bus/bus-creds.c
+ sd-bus/bus-creds.h
+ sd-bus/bus-dump.c
+ sd-bus/bus-dump.h
+ sd-bus/bus-error.c
+ sd-bus/bus-error.h
+ sd-bus/bus-gvariant.c
+ sd-bus/bus-gvariant.h
+ sd-bus/bus-internal.c
+ sd-bus/bus-internal.h
+ sd-bus/bus-introspect.c
+ sd-bus/bus-introspect.h
+ sd-bus/bus-kernel.c
+ sd-bus/bus-kernel.h
+ sd-bus/bus-match.c
+ sd-bus/bus-match.h
+ sd-bus/bus-message.c
+ sd-bus/bus-message.h
+ sd-bus/bus-objects.c
+ sd-bus/bus-objects.h
+ sd-bus/bus-protocol.h
+ sd-bus/bus-signature.c
+ sd-bus/bus-signature.h
+ sd-bus/bus-slot.c
+ sd-bus/bus-slot.h
+ sd-bus/bus-socket.c
+ sd-bus/bus-socket.h
+ sd-bus/bus-track.c
+ sd-bus/bus-track.h
+ sd-bus/bus-type.c
+ sd-bus/bus-type.h
+ sd-bus/kdbus.h
+ sd-bus/sd-bus.c
+ sd-daemon/sd-daemon.c
+ sd-device/device-enumerator-private.h
+ sd-device/device-enumerator.c
+ sd-device/device-internal.h
+ sd-device/device-private.c
+ sd-device/device-private.h
+ sd-device/device-util.h
+ sd-device/sd-device.c
+ sd-event/sd-event.c
+ sd-hwdb/hwdb-internal.h
+ sd-hwdb/hwdb-util.h
+ sd-hwdb/sd-hwdb.c
+ sd-id128/id128-util.c
+ sd-id128/id128-util.h
+ sd-id128/sd-id128.c
+ sd-netlink/local-addresses.c
+ sd-netlink/local-addresses.h
+ sd-netlink/netlink-internal.h
+ sd-netlink/netlink-message.c
+ sd-netlink/netlink-socket.c
+ sd-netlink/netlink-types.c
+ sd-netlink/netlink-types.h
+ sd-netlink/netlink-util.c
+ sd-netlink/netlink-util.h
+ sd-netlink/rtnl-message.c
+ sd-netlink/sd-netlink.c
+ sd-network/network-util.c
+ sd-network/network-util.h
+ sd-network/sd-network.c
+ sd-path/sd-path.c
+ sd-resolve/sd-resolve.c
+ sd-utf8/sd-utf8.c
+'''.split()) + sd_login_c
+
+libsystemd_internal = static_library(
+ 'systemd',
+ libsystemd_internal_sources,
+ install : false,
+ include_directories : includes,
+ link_with : libbasic,
+ dependencies : [threads,
+ librt])
+
+libsystemd_sym = 'src/libsystemd/libsystemd.sym'
+
+libsystemd_pc = configure_file(
+ input : 'libsystemd.pc.in',
+ output : 'libsystemd.pc',
+ configuration : substs)
+install_data(libsystemd_pc,
+ install_dir : pkgconfiglibdir)
+++ /dev/null
-Known differences between dbus1 and kdbus:
-
-- NameAcquired/NameLost is gone entirely on kdbus backends if
- libsystemd is used. It is still added in by systemd-bus-proxyd
- for old dbus1 clients, and it is available if libsystemd is used
- against the classic dbus1 daemon. If you want to write compatible
- code with libsystem-bus you need to explicitly subscribe to
- NameOwnerChanged signals and just ignore NameAcquired/NameLost
-
-- Applications have to deal with spurious signals they didn't expect,
- due to the probabilistic bloom filters. They need to handle this
- anyway, given that any client can send anything to arbitrary clients
- anyway, even in dbus1, so not much changes.
-
-- clients of the system bus when kdbus is used must roll their own
- security. Only legacy dbus1 clients get the old XML policy enforced,
- which is implemented by systemd-bus-proxyd.
-
-- Serial numbers of synthesized messages are always (uint32_t) -1.
-
-- NameOwnerChanged is a synthetic message, generated locally and not
- by the driver. On dbus1 only the Disconnected message was
- synthesized like this.
-
-- There's no standard per-session bus anymore. Only a per-user bus.
increased from 32bit to 64bit, too!
The header field identifiers have been extended from 8bit to
-64bit. This has been done to simplify things (as kdbus otherwise uses
-exclusively 64bit types, unless there is a strong reason not to), and
-has no effect on the serialization size, as due to alignment for each
-8bit header field identifier 56 bits of padding had to be added.
+64bit. This has been done to simplify things, and has no effect
+on the serialization size, as due to alignment for each 8bit
+header field identifier 56 bits of padding had to be added.
Note that the header size changed, due to these changes. However,
consider that on dbus1 the beginning of the fields array contains the
And that's already it.
-Note: to simplify parsing, valid kdbus/dbus2 messages must include the
-entire fixed header and additional header fields in a single non-memfd
-message part. Also, the signature string of the body variant all the
-way to the end of the message must be in a single non-memfd part
-too. The parts for this extended header and footer can be the same
-one, and can also continue any amount of additional body bytes.
-
-Note: on kdbus only native endian messages marshalled in gvariant may
- be sent. If a client receives a message in non-native endianness
- or in dbus1 marshalling it shall ignore the message.
+Note: To simplify parsing, valid dbus2 messages must include the entire
+ fixed header and additional header fields in a single non-memfd
+ message part. Also, the signature string of the body variant all the
+ way to the end of the message must be in a single non-memfd part
+ too. The parts for this extended header and footer can be the same
+ one, and can also continue any amount of additional body bytes.
Note: The GVariant "MAYBE" type is not supported, so that messages can
be fully converted forth and back between dbus1 and gvariant
+++ /dev/null
-A few hints on supporting kdbus as backend in your favorite D-Bus library.
-
-~~~
-
-Before you read this, have a look at the DIFFERENCES and
-GVARIANT_SERIALIZATION texts you find in the same directory where you
-found this.
-
-We invite you to port your favorite D-Bus protocol implementation
-over to kdbus. However, there are a couple of complexities
-involved. On kdbus we only speak GVariant marshaling, kdbus clients
-ignore traffic in dbus1 marshaling. Thus, you need to add a second,
-GVariant compatible marshaler to your library first.
-
-After you have done that: here's the basic principle how kdbus works:
-
-You connect to a bus by opening its bus node in /sys/fs/kdbus/. All
-buses have a device node there, it starts with a numeric UID of the
-owner of the bus, followed by a dash and a string identifying the
-bus. The system bus is thus called /sys/fs/kdbus/0-system, and for user
-buses the device node is /sys/fs/kdbus/1000-user (if 1000 is your user
-id).
-
-(Before we proceed, please always keep a copy of libsystemd next
-to you, ultimately that's where the details are, this document simply
-is a rough overview to help you grok things.)
-
-CONNECTING
-
-To connect to a bus, simply open() its device node and issue the
-KDBUS_CMD_HELLO call. That's it. Now you are connected. Do not send
-Hello messages or so (as you would on dbus1), that does not exist for
-kdbus.
-
-The structure you pass to the ioctl will contain a couple of
-parameters that you need to know, to operate on the bus.
-
-There are two flags fields, one indicating features of the kdbus
-kernel side ("conn_flags"), the other one ("bus_flags") indicating
-features of the bus owner (i.e. systemd). Both flags fields are 64bit
-in width.
-
-When calling into the ioctl, you need to place your own supported
-feature bits into these fields. This tells the kernel about the
-features you support. When the ioctl returns, it will contain the
-features the kernel supports.
-
-If any of the higher 32bit are set on the two flags fields and your
-client does not know what they mean, it must disconnect. The upper
-32bit are used to indicate "incompatible" feature additions on the bus
-system, the lower 32bit indicate "compatible" feature additions. A
-client that does not support a "compatible" feature addition can go on
-communicating with the bus, however a client that does not support an
-"incompatible" feature must not proceed with the connection. When a
-client encountes such an "incompatible" feature it should immediately
-try the next bus address configured in the bus address string.
-
-The hello structure also contains another flags field "attach_flags"
-which indicates metadata that is optionally attached to all incoming
-messages. You probably want to set KDBUS_ATTACH_NAMES unconditionally
-in it. This has the effect that all well-known names of a sender are
-attached to all incoming messages. You need this information to
-implement matches that match on a message sender name correctly. Of
-course, you should only request the attachment of as little metadata
-fields as you need.
-
-The kernel will return in the "id" field your unique id. This is a
-simple numeric value. For compatibility with classic dbus1 simply
-format this as string and prefix ":1.".
-
-The kernel will also return the bloom filter size and bloom filter
-hash function number used for the signal broadcast bloom filter (see
-below).
-
-The kernel will also return the bus ID of the bus in a 128bit field.
-
-The pool size field specifies the size of the memory mapped buffer.
-After the calling the hello ioctl, you should memory map the kdbus
-fd. In this memory mapped region, the kernel will place all your incoming
-messages.
-
-SENDING MESSAGES
-
-Use the MSG_SEND ioctl to send a message to another peer. The ioctl
-takes a structure that contains a variety of fields:
-
-The flags field corresponds closely to the old dbus1 message header
-flags field, though the DONT_EXPECT_REPLY field got inverted into
-EXPECT_REPLY.
-
-The dst_id/src_id field contains the unique id of the destination and
-the sender. The sender field is overridden by the kernel usually, hence
-you shouldn't fill it in. The destination field can also take the
-special value KDBUS_DST_ID_BROADCAST for broadcast messages. For
-messages intended to a well-known name set the field to
-KDBUS_DST_ID_NAME, and attach the name in a special "items" entry to
-the message (see below).
-
-The payload field indicates the payload. For all dbus traffic it
-should carry the value 0x4442757344427573ULL. (Which encodes
-'DBusDBus').
-
-The cookie field corresponds with the "serial" field of classic
-dbus1. We simply renamed it here (and extended it to 64bit) since we
-didn't want to imply the monotonicity of the assignment the way the
-word "serial" indicates it.
-
-When sending a message that expects a reply, you need to set the
-EXPECT_REPLY flag in the message flag field. In this case you should
-also fill out the "timeout_ns" value which indicates the timeout in
-nsec for this call. If the peer does not respond in this time you will
-get a notification of a timeout. Note that this is also used for
-security purposes: a single reply messages is only allowed through the
-bus as long as the timeout has not ended. With this timeout value you
-hence "open a time window" in which the peer might respond to your
-request and the policy allows the response to go through.
-
-When sending a message that is a reply, you need to fill in the
-cookie_reply field, which is similar to the reply_serial field of
-dbus1. Note that a message cannot have EXPECT_REPLY and a reply_serial
-at the same time!
-
-This pretty much explains the ioctl header. The actual payload of the
-data is now referenced in additional items that are attached to this
-ioctl header structure at the end. When sending a message, you attach
-items of the type PAYLOAD_VEC, PAYLOAD_MEMFD, FDS, BLOOM_FILTER,
-DST_NAME to it:
-
- KDBUS_ITEM_PAYLOAD_VEC: contains a pointer + length pair for
- referencing arbitrary user memory. This is how you reference most
- of your data. It's a lot like the good old iovec structure of glibc.
-
- KDBUS_ITEM_PAYLOAD_MEMFD: for large data blocks it is preferable
- to send prepared "memfds" (see below) over. This item contains an
- fd for a memfd plus a size.
-
- KDBUS_ITEM_FDS: for sending over fds attach an item of this type with
- an array of fds.
-
- KDBUS_ITEM_BLOOM_FILTER: the calculated bloom filter of this message,
- only for undirected (broadcast) message.
-
- KDBUS_ITEM_DST_NAME: for messages that are directed to a well-known
- name (instead of a unique name), this item contains the well-known
- name field.
-
-A single message may consists of no, one or more payload items of type
-PAYLOAD_VEC or PAYLOAD_MEMFD. D-Bus protocol implementations should
-treat them as a single block that just happens to be split up into
-multiple items. Some restrictions apply however:
-
- The message header in its entirety must be contained in a single
- PAYLOAD_VEC item.
-
- You may only split your message up right in front of each GVariant
- contained in the payload, as well is immediately before framing of a
- Gvariant, as well after as any padding bytes if there are any. The
- padding bytes must be wholly contained in the preceding
- PAYLOAD_VEC/PAYLOAD_MEMFD item. You may not split up basic types
- nor arrays of fixed types. The latter is necessary to allow APIs
- to return direct pointers to linear arrays of numeric
- values. Examples: The basic types "u", "s", "t" have to be in the
- same payload item. The array of fixed types "ay", "ai" have to be
- fully in contained in the same payload item. For an array "as" or
- "a(si)" the only restriction however is to keep each string
- individually in an uninterrupted item, to keep the framing of each
- element and the array in a single uninterrupted item, however the
- various strings might end up in different items.
-
-Note again, that splitting up messages into separate items is up to the
-implementation. Also note that the kdbus kernel side might merge
-separate items if it deems this to be useful. However, the order in
-which items are contained in the message is left untouched.
-
-PAYLOAD_MEMFD items allow zero-copy data transfer (see below regarding
-the memfd concept). Note however that the overhead of mapping these
-makes them relatively expensive, and only worth the trouble for memory
-blocks > 512K (this value appears to be quite universal across
-architectures, as we tested). Thus we recommend sending PAYLOAD_VEC
-items over for small messages and restore to PAYLOAD_MEMFD items for
-messages > 512K. Since while building up the message you might not
-know yet whether it will grow beyond this boundary a good approach is
-to simply build the message unconditionally in a memfd
-object. However, when the message is sealed to be sent away check for
-the size limit. If the size of the message is < 512K, then simply send
-the data as PAYLOAD_VEC and reuse the memfd. If it is >= 512K, seal
-the memfd and send it as PAYLOAD_MEMFD, and allocate a new memfd for
-the next message.
-
-RECEIVING MESSAGES
-
-Use the MSG_RECV ioctl to read a message from kdbus. This will return
-an offset into the pool memory map, relative to its beginning.
-
-The received message structure more or less follows the structure of
-the message originally sent. However, certain changes have been
-made. In the header the src_id field will be filled in.
-
-The payload items might have gotten merged and PAYLOAD_VEC items are
-not used. Instead, you will only find PAYLOAD_OFF and PAYLOAD_MEMFD
-items. The former contain an offset and size into your memory mapped
-pool where you find the payload.
-
-If during the HELLO ioctl you asked for getting metadata attached to
-your message, you will find additional KDBUS_ITEM_CREDS,
-KDBUS_ITEM_PID_COMM, KDBUS_ITEM_TID_COMM, KDBUS_ITEM_TIMESTAMP,
-KDBUS_ITEM_EXE, KDBUS_ITEM_CMDLINE, KDBUS_ITEM_CGROUP,
-KDBUS_ITEM_CAPS, KDBUS_ITEM_SECLABEL, KDBUS_ITEM_AUDIT items that
-contain this metadata. This metadata will be gathered from the sender
-at the point in time it sends the message. This information is
-uncached, and since it is appended by the kernel, trustable. The
-KDBUS_ITEM_SECLABEL item usually contains the SELinux security label,
-if it is used.
-
-After processing the message you need to call the KDBUS_CMD_FREE
-ioctl, which releases the message from the pool, and allows the kernel
-to store another message there. Note that the memory used by the pool
-is ordinary anonymous, swappable memory that is backed by tmpfs. Hence
-there is no need to copy the message out of it quickly, instead you
-can just leave it there as long as you need it and release it via the
-FREE ioctl only after that's done.
-
-BLOOM FILTERS
-
-The kernel does not understand dbus marshaling, it will not look into
-the message payload. To allow clients to subscribe to specific subsets
-of the broadcast matches we employ bloom filters.
-
-When broadcasting messages, a bloom filter needs to be attached to the
-message in a KDBUS_ITEM_BLOOM item (and only for broadcasting
-messages!). If you don't know what bloom filters are, read up now on
-Wikipedia. In short: they are a very efficient way how to
-probabilistically check whether a certain word is contained in a
-vocabulary. It knows no false negatives, but it does know false
-positives.
-
-The parameters for the bloom filters that need to be included in
-broadcast message is communicated to userspace as part of the hello
-response structure (see above). By default it has the parameters m=512
-(bits in the filter), k=8 (nr of hash functions). Note however, that
-this is subject to change in later versions, and userspace
-implementations must be capable of handling m values between at least
-m=8 and m=2^32, and k values between at least k=1 and k=32. The
-underlying hash function is SipHash-2-4. It is used with a number of
-constant (yet originally randomly generated) 128bit hash keys, more
-specifically:
-
- b9,66,0b,f0,46,70,47,c1,88,75,c4,9c,54,b9,bd,15,
- aa,a1,54,a2,e0,71,4b,39,bf,e1,dd,2e,9f,c5,4a,3b,
- 63,fd,ae,be,cd,82,48,12,a1,6e,41,26,cb,fa,a0,c8,
- 23,be,45,29,32,d2,46,2d,82,03,52,28,fe,37,17,f5,
- 56,3b,bf,ee,5a,4f,43,39,af,aa,94,08,df,f0,fc,10,
- 31,80,c8,73,c7,ea,46,d3,aa,25,75,0f,9e,4c,09,29,
- 7d,f7,18,4b,7b,a4,44,d5,85,3c,06,e0,65,53,96,6d,
- f2,77,e9,6f,93,b5,4e,71,9a,0c,34,88,39,25,bf,35
-
-When calculating the first bit index into the bloom filter, the
-SipHash-2-4 hash value is calculated for the input data and the first
-16 bytes of the array above as hash key. Of the resulting 8 bytes of
-output, as many full bytes are taken for the bit index as necessary,
-starting from the output's first byte. For the second bit index the
-same hash value is used, continuing with the next unused output byte,
-and so on. Each time the bytes returned by the hash function are
-depleted it is recalculated with the next 16 byte hash key from the
-array above and the same input data.
-
-For each message to send across the bus we populate the bloom filter
-with all possible matchable strings. If a client then wants to
-subscribe to messages of this type, it simply tells the kernel to test
-its own calculated bit mask against the bloom filter of each message.
-
-More specifically, the following strings are added to the bloom filter
-of each message that is broadcasted:
-
- The string "interface:" suffixed by the interface name
-
- The string "member:" suffixed by the member name
-
- The string "path:" suffixed by the path name
-
- The string "path-slash-prefix:" suffixed with the path name, and
- also all prefixes of the path name (cut off at "/"), also prefixed
- with "path-slash-prefix".
-
- The string "message-type:" suffixed with the strings "signal",
- "method_call", "error" or "method_return" for the respective message
- type of the message.
-
- If the first argument of the message is a string, "arg0:" suffixed
- with the first argument.
-
- If the first argument of the message is a string, "arg0-dot-prefix"
- suffixed with the first argument, and also all prefixes of the
- argument (cut off at "."), also prefixed with "arg0-dot-prefix".
-
- If the first argument of the message is a string,
- "arg0-slash-prefix" suffixed with the first argument, and also all
- prefixes of the argument (cut off at "/"), also prefixed with
- "arg0-slash-prefix".
-
- Similar for all further arguments that are strings up to 63, for the
- arguments and their "dot" and "slash" prefixes. On the first
- argument that is not a string, addition to the bloom filter should be
- stopped however.
-
-(Note that the bloom filter does not contain sender nor receiver
-names!)
-
-When a client wants to subscribe to messages matching a certain
-expression, it should calculate the bloom mask following the same
-algorithm. The kernel will then simply test the mask against the
-attached bloom filters.
-
-Note that bloom filters are probabilistic, which means that clients
-might get messages they did not expect. Your bus protocol
-implementation must be capable of dealing with these unexpected
-messages (which it needs to anyway, given that transfers are
-relatively unrestricted on kdbus and people can send you all kinds of
-non-sense).
-
-If a client connects to a bus whose bloom filter metrics (i.e. filter
-size and number of hash functions) are outside of the range the client
-supports it must immediately disconnect and continue connection with
-the next bus address of the bus connection string.
-
-INSTALLING MATCHES
-
-To install matches for broadcast messages, use the KDBUS_CMD_ADD_MATCH
-ioctl. It takes a structure that contains an encoded match expression,
-and that is followed by one or more items, which are combined in an
-AND way. (Meaning: a message is matched exactly when all items
-attached to the original ioctl struct match).
-
-To match against other user messages add a KDBUS_ITEM_BLOOM item in
-the match (see above). Note that the bloom filter does not include
-matches to the sender names. To additionally check against sender
-names, use the KDBUS_ITEM_ID (for unique id matches) and
-KDBUS_ITEM_NAME (for well-known name matches) item types.
-
-To match against kernel generated messages (see below) you should add
-items of the same type as the kernel messages include,
-i.e. KDBUS_ITEM_NAME_ADD, KDBUS_ITEM_NAME_REMOVE,
-KDBUS_ITEM_NAME_CHANGE, KDBUS_ITEM_ID_ADD, KDBUS_ITEM_ID_REMOVE and
-fill them out. Note however, that you have some wildcards in this
-case, for example the .id field of KDBUS_ITEM_ID_ADD/KDBUS_ITEM_ID_REMOVE
-structures may be set to 0 to match against any id addition/removal.
-
-Note that dbus match strings do no map 1:1 to these ioctl() calls. In
-many cases (where the match string is "underspecified") you might need
-to issue up to six different ioctl() calls for the same match. For
-example, the empty match (which matches against all messages), would
-translate into one KDBUS_ITEM_BLOOM ioctl, one KDBUS_ITEM_NAME_ADD,
-one KDBUS_ITEM_NAME_CHANGE, one KDBUS_ITEM_NAME_REMOVE, one
-KDBUS_ITEM_ID_ADD and one KDBUS_ITEM_ID_REMOVE.
-
-When creating a match, you may attach a "cookie" value to them, which
-is used for deleting this match again. The cookie can be selected freely
-by the client. When issuing KDBUS_CMD_REMOVE_MATCH, simply pass the
-same cookie as before and all matches matching the same "cookie" value
-will be removed. This is particularly handy for the case where multiple
-ioctl()s are added for a single match strings.
-
-MEMFDS
-
-memfds may be sent across kdbus via KDBUS_ITEM_PAYLOAD_MEMFD items
-attached to messages. If this is done, the data included in the memfd
-is considered part of the payload stream of a message, and are treated
-the same way as KDBUS_ITEM_PAYLOAD_VEC by the receiving side. It is
-possible to interleave KDBUS_ITEM_PAYLOAD_MEMFD and
-KDBUS_ITEM_PAYLOAD_VEC items freely, by the reader they will be
-considered a single stream of bytes in the order these items appear in
-the message, that just happens to be split up at various places
-(regarding rules how they may be split up, see above). The kernel will
-refuse taking KDBUS_ITEM_PAYLOAD_MEMFD items that refer to memfds that
-are not sealed.
-
-Note that sealed memfds may be unsealed again if they are not mapped
-you have the only fd reference to them.
-
-Alternatively to sending memfds as KDBUS_ITEM_PAYLOAD_MEMFD items
-(where they are just a part of the payload stream of a message) you can
-also simply attach any memfd to a message using
-KDBUS_ITEM_PAYLOAD_FDS. In this case, the memfd contents is not
-considered part of the payload stream of the message, but simply fds
-like any other, that happen to be attached to the message.
-
-MESSAGES FROM THE KERNEL
-
-A couple of messages previously generated by the dbus1 bus driver are
-now generated by the kernel. Since the kernel does not understand the
-payload marshaling, they are generated by the kernel in a different
-format. This is indicated with the "payload type" field of the
-messages set to 0. Library implementations should take these messages
-and synthesize traditional driver messages for them on reception.
-
-More specifically:
-
- Instead of the NameOwnerChanged, NameLost, NameAcquired signals
- there are kernel messages containing KDBUS_ITEM_NAME_ADD,
- KDBUS_ITEM_NAME_REMOVE, KDBUS_ITEM_NAME_CHANGE, KDBUS_ITEM_ID_ADD,
- KDBUS_ITEM_ID_REMOVE items are generated (each message will contain
- exactly one of these items). Note that in libsystemd we have
- obsoleted NameLost/NameAcquired messages, since they are entirely
- redundant to NameOwnerChanged. This library will hence only
- synthesize NameOwnerChanged messages from these kernel messages,
- and never generate NameLost/NameAcquired. If your library needs to
- stay compatible to the old dbus1 userspace, you possibly might need
- to synthesize both a NameOwnerChanged and NameLost/NameAcquired
- message from the same kernel message.
-
- When a method call times out, a KDBUS_ITEM_REPLY_TIMEOUT message is
- generated. This should be synthesized into a method error reply
- message to the original call.
-
- When a method call fails because the peer terminated the connection
- before responding, a KDBUS_ITEM_REPLY_DEAD message is
- generated. Similarly, it should be synthesized into a method error
- reply message.
-
-For synthesized messages we recommend setting the cookie field to
-(uint32_t) -1 (and not (uint64_t) -1!), so that the cookie is not 0
-(which the dbus1 spec does not allow), but clearly recognizable as
-synthetic.
-
-Note that the KDBUS_ITEM_NAME_XYZ messages will actually inform you
-about all kinds of names, including activatable ones. Classic dbus1
-NameOwnerChanged messages OTOH are only generated when a name is
-really acquired on the bus and not just simply activatable. This means
-you must explicitly check for the case where an activatable name
-becomes acquired or an acquired name is lost and returns to be
-activatable.
-
-NAME REGISTRY
-
-To acquire names on the bus, use the KDBUS_CMD_NAME_ACQUIRE ioctl(). It
-takes a flags field similar to dbus1's RequestName() bus driver call,
-however the NO_QUEUE flag got inverted into a QUEUE flag instead.
-
-To release a previously acquired name use the KDBUS_CMD_NAME_RELEASE
-ioctl().
-
-To list acquired names use the KDBUS_CMD_CONN_INFO ioctl. It may be
-used to list unique names, well known names as well as activatable
-names and clients currently queuing for ownership of a well-known
-name. The ioctl will return an offset into the memory pool. After
-reading all the data you need, you need to release this via the
-KDBUS_CMD_FREE ioctl(), similar how you release a received message.
-
-CREDENTIALS
-
-kdbus can optionally attach various kinds of metadata about the sender at
-the point of time of sending ("credentials") to messages, on request
-of the receiver. This is both supported on directed and undirected
-(broadcast) messages. The metadata to attach is selected at time of
-the HELLO ioctl of the receiver via a flags field (see above). Note
-that clients must be able to handle that messages contain more
-metadata than they asked for themselves, to simplify implementation of
-broadcasting in the kernel. The receiver should not rely on this data
-to be around though, even though it will be correct if it happens to
-be attached. In order to avoid programming errors in applications, we
-recommend though not passing this data on to clients that did not
-explicitly ask for it.
-
-Credentials may also be queried for a well-known or unique name. Use
-the KDBUS_CMD_CONN_INFO for this. It will return an offset to the pool
-area again, which will contain the same credential items as messages
-have attached. Note that when issuing the ioctl, you can select a
-different set of credentials to gather, than what was originally requested
-for being attached to incoming messages.
-
-Credentials are always specific to the sender's domain that was
-current at the time of sending, and of the process that opened the
-bus connection at the time of opening it. Note that this latter data
-is cached!
-
-POLICY
-
-The kernel enforces only very limited policy on names. It will not do
-access filtering by userspace payload, and thus not by interface or
-method name.
-
-This ultimately means that most fine-grained policy enforcement needs
-to be done by the receiving process. We recommend using PolicyKit for
-any more complex checks. However, libraries should make simple static
-policy decisions regarding privileged/unprivileged method calls
-easy. We recommend doing this by enabling KDBUS_ATTACH_CAPS and
-KDBUS_ATTACH_CREDS for incoming messages, and then discerning client
-access by some capability, or if sender and receiver UIDs match.
-
-BUS ADDRESSES
-
-When connecting to kdbus use the "kernel:" protocol prefix in DBus
-address strings. The device node path is encoded in its "path="
-parameter.
-
-Client libraries should use the following connection string when
-connecting to the system bus:
-
- kernel:path=/sys/fs/kdbus/0-system/bus;unix:path=/var/run/dbus/system_bus_socket
-
-This will ensure that kdbus is preferred over the legacy AF_UNIX
-socket, but compatibility is kept. For the user bus use:
-
- kernel:path=/sys/fs/kdbus/$UID-user/bus;unix:path=$XDG_RUNTIME_DIR/bus
-
-With $UID replaced by the callers numer user ID, and $XDG_RUNTIME_DIR
-following the XDG basedir spec.
-
-Of course the $DBUS_SYSTEM_BUS_ADDRESS and $DBUS_SESSION_BUS_ADDRESS
-variables should still take precedence.
-
-DBUS SERVICE FILES
-
-Activatable services for kdbus may not use classic dbus1 service
-activation files. Instead, programs should drop in native systemd
-.service and .busname unit files, so that they are treated uniformly
-with other types of units and activation of the system.
-
-Note that this results in a major difference to classic dbus1:
-activatable bus names can be established at any time in the boot process.
-This is unlike dbus1 where activatable names are unconditionally available
-as long as dbus-daemon is running. Being able to control when
-activatable names are established is essential to allow usage of kdbus
-during early boot and in initrds, without the risk of triggering
-services too early.
-
-DISCLAIMER
-
-This all is so far just the status quo. We are putting this together, because
-we are quite confident that further API changes will be smaller, but
-to make this very clear: this is all subject to change, still!
-
-We invite you to port over your favorite dbus library to this new
-scheme, but please be prepared to make minor changes when we still
-change these interfaces!
if ((flags & KDBUS_LIST_UNIQUE) && name->id != previous_id && !(name->flags & KDBUS_HELLO_ACTIVATOR)) {
char *n;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
if (asprintf(&n, ":1.%llu", name->id) < 0) {
r = -ENOMEM;
goto fail;
}
+#pragma GCC diagnostic pop
r = strv_consume(x, n);
if (r < 0)
}
if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
if (asprintf(&c->unique_name, ":1.%llu", conn_info->id) < 0) {
r = -ENOMEM;
goto fail;
}
+#pragma GCC diagnostic pop
c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
}
}
if (mask != 0) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ bool need_pid, need_uid, need_selinux, need_separate_calls;
c = bus_creds_new();
if (!c)
return -ENOMEM;
c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
}
- if ((mask & SD_BUS_CREDS_PID) ||
- ((mask & SD_BUS_CREDS_AUGMENT) &&
- (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
- SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
- SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
- SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
- SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
- SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
- SD_BUS_CREDS_SELINUX_CONTEXT|
- SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
+ need_pid = (mask & SD_BUS_CREDS_PID) ||
+ ((mask & SD_BUS_CREDS_AUGMENT) &&
+ (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+ SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
+ SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
+ SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
+ SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
+ SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
+ SD_BUS_CREDS_SELINUX_CONTEXT|
+ SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
+ need_uid = mask & SD_BUS_CREDS_EUID;
+ need_selinux = mask & SD_BUS_CREDS_SELINUX_CONTEXT;
- uint32_t u;
+ if (need_pid + need_uid + need_selinux > 1) {
+
+ /* If we need more than one of the credentials, then use GetConnectionCredentials() */
r = sd_bus_call_method(
bus,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
- "GetConnectionUnixProcessID",
- NULL,
+ "GetConnectionCredentials",
+ &error,
&reply,
"s",
- unique ? unique : name);
- if (r < 0)
- return r;
+ unique ?: name);
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ if (r < 0) {
- pid = u;
- if (mask & SD_BUS_CREDS_PID) {
- c->pid = u;
- c->mask |= SD_BUS_CREDS_PID;
- }
+ if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
+ return r;
- reply = sd_bus_message_unref(reply);
- }
+ /* If we got an unknown method error, fall back to the invidual calls... */
+ need_separate_calls = true;
+ sd_bus_error_free(&error);
- if (mask & SD_BUS_CREDS_EUID) {
- uint32_t u;
+ } else {
+ need_separate_calls = false;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionUnixUser",
- NULL,
- &reply,
- "s",
- unique ? unique : name);
- if (r < 0)
- return r;
+ r = sd_bus_message_enter_container(reply, 'a', "{sv}");
+ if (r < 0)
+ return r;
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ for (;;) {
+ const char *m;
- c->euid = u;
- c->mask |= SD_BUS_CREDS_EUID;
+ r = sd_bus_message_enter_container(reply, 'e', "sv");
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
- reply = sd_bus_message_unref(reply);
- }
+ r = sd_bus_message_read(reply, "s", &m);
+ if (r < 0)
+ return r;
- if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- const void *p = NULL;
- size_t sz = 0;
+ if (need_uid && streq(m, "UnixUserID")) {
+ uint32_t u;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionSELinuxSecurityContext",
- &error,
- &reply,
- "s",
- unique ? unique : name);
- if (r < 0) {
- if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+ r = sd_bus_message_read(reply, "v", "u", &u);
+ if (r < 0)
+ return r;
+
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
+
+ } else if (need_pid && streq(m, "ProcessID")) {
+ uint32_t p;
+
+ r = sd_bus_message_read(reply, "v", "u", &p);
+ if (r < 0)
+ return r;
+
+ pid = p;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = p;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
+
+ } else if (need_selinux && streq(m, "LinuxSecurityLabel")) {
+ const void *p = NULL;
+ size_t sz = 0;
+
+ r = sd_bus_message_enter_container(reply, 'v', "ay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ free(c->label);
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+ } else {
+ r = sd_bus_message_skip(reply, "v");
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
return r;
- } else {
- r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+
+ if (need_pid && pid == 0)
+ return -EPROTO;
+ }
+
+ } else /* When we only need a single field, then let's use separate calls */
+ need_separate_calls = true;
+
+ if (need_separate_calls) {
+ if (need_pid) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ NULL,
+ &reply,
+ "s",
+ unique ?: name);
if (r < 0)
return r;
- c->label = strndup(p, sz);
- if (!c->label)
- return -ENOMEM;
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
- c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ pid = u;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = u;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (need_uid) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixUser",
+ NULL,
+ &reply,
+ "s",
+ unique ? unique : name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
+
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (need_selinux) {
+ const void *p = NULL;
+ size_t sz = 0;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionSELinuxSecurityContext",
+ &error,
+ &reply,
+ "s",
+ unique ? unique : name);
+ if (r < 0) {
+ if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+ return r;
+
+ /* no data is fine */
+ } else {
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ }
}
}
if (!bus->bus_client)
return -EINVAL;
+ /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not
+ * going to match. */
+ if (!bus->is_local)
+ mask &= ~SD_BUS_CREDS_AUGMENT;
+
if (streq(name, "org.freedesktop.DBus.Local"))
return -EINVAL;
+ if (streq(name, "org.freedesktop.DBus"))
+ return sd_bus_get_owner_creds(bus, mask, creds);
+
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
+ if (!bus->is_local)
+ mask &= ~SD_BUS_CREDS_AUGMENT;
+
if (bus->is_kernel)
return bus_get_owner_creds_kdbus(bus, mask, ret);
else
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
return r;
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
return r;
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
goto fail;
va_list ap;
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
if (r < 0)
return r;
goto fail;
va_start(ap, type);
- r = bus_message_append_ap(m, type, ap);
+ r = sd_bus_message_appendv(m, type, ap);
va_end(ap);
if (r < 0)
goto fail;
bool exit_on_disconnect:1;
bool exited:1;
bool exit_triggered:1;
+ bool is_local:1;
int use_memfd;
#include "user-util.h"
#include "util.h"
+#pragma GCC diagnostic ignored "-Wformat"
+
#define UNIQUE_NAME_MAX (3+DECIMAL_STR_MAX(uint64_t))
int bus_kernel_parse_unique_name(const char *s, uint64_t *id) {
return 1;
}
-int bus_message_append_ap(
+_public_ int sd_bus_message_appendv(
sd_bus_message *m,
const char *types,
va_list ap) {
unsigned stack_ptr = 0;
int r;
- assert(m);
-
- if (!types)
- return 0;
+ assert_return(m, -EINVAL);
+ assert_return(types, -EINVAL);
+ assert_return(!m->sealed, -EPERM);
+ assert_return(!m->poisoned, -ESTALE);
n_array = (unsigned) -1;
n_struct = strlen(types);
assert_return(!m->poisoned, -ESTALE);
va_start(ap, types);
- r = bus_message_append_ap(m, types, ap);
+ r = sd_bus_message_appendv(m, types, ap);
va_end(ap);
return r;
int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str);
int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv);
-int bus_message_append_ap(sd_bus_message *m, const char *types, va_list ap);
-
int bus_message_parse_fields(sd_bus_message *m);
struct bus_body_part *message_append_part(sd_bus_message *m);
/* Nothing?, let's see if we exist at all, and if not
* refuse to do anything */
r = bus_node_exists(bus, n, m->path, require_fallback);
- if (r <= 0)
+ if (r <= 0) {
+ r = bus_maybe_reply_error(m, r, &error);
goto finish;
+ }
if (bus->nodes_modified) {
r = 0;
goto finish;
if (r < 0)
return r;
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.Peer", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.Introspectable", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.Properties", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(reply, "{sa{sv}}", "org.freedesktop.DBus.ObjectManager", 0);
+ if (r < 0)
+ return r;
+
found_something = true;
}
r = get_child_nodes(bus, m->path, n, CHILDREN_RECURSIVE, &s, &error);
if (r < 0)
- return r;
+ return bus_maybe_reply_error(m, r, &error);
if (bus->nodes_modified)
return 0;
SET_FOREACH(path, s, i) {
r = object_manager_serialize_path_and_fallbacks(bus, reply, path, &error);
if (r < 0)
- return r;
+ return bus_maybe_reply_error(m, r, &error);
if (bus->nodes_modified)
return 0;
if (!*found_object) {
r = bus_node_exists(bus, n, m->path, require_fallback);
if (r < 0)
- return r;
+ return bus_maybe_reply_error(m, r, NULL);
if (bus->nodes_modified)
return 0;
if (r > 0)
b->ucred_valid = getpeercred(b->input_fd, &b->ucred) >= 0;
/* Get the SELinux context of the peer */
- if (mac_selinux_have()) {
+ if (mac_selinux_use()) {
r = getpeersec(b->input_fd, &b->label);
if (r < 0 && r != -EOPNOTSUPP)
log_debug_errno(r, "Failed to determine peer security context: %m");
+++ /dev/null
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-bus.h"
-
-#include "alloc-util.h"
-#include "busctl-introspect.h"
-#include "string-util.h"
-#include "util.h"
-#include "xml.h"
-
-#define NODE_DEPTH_MAX 16
-
-typedef struct Context {
- const XMLIntrospectOps *ops;
- void *userdata;
-
- char *interface_name;
- uint64_t interface_flags;
-
- char *member_name;
- char *member_signature;
- char *member_result;
- uint64_t member_flags;
- bool member_writable;
-
- const char *current;
- void *xml_state;
-} Context;
-
-static void context_reset_member(Context *c) {
- free(c->member_name);
- free(c->member_signature);
- free(c->member_result);
-
- c->member_name = c->member_signature = c->member_result = NULL;
- c->member_flags = 0;
- c->member_writable = false;
-}
-
-static void context_reset_interface(Context *c) {
- c->interface_name = mfree(c->interface_name);
- c->interface_flags = 0;
-
- context_reset_member(c);
-}
-
-static int parse_xml_annotation(Context *context, uint64_t *flags) {
-
- enum {
- STATE_ANNOTATION,
- STATE_NAME,
- STATE_VALUE
- } state = STATE_ANNOTATION;
-
- _cleanup_free_ char *field = NULL, *value = NULL;
-
- assert(context);
-
- for (;;) {
- _cleanup_free_ char *name = NULL;
-
- int t;
-
- t = xml_tokenize(&context->current, &name, &context->xml_state, NULL);
- if (t < 0) {
- log_error("XML parse error.");
- return t;
- }
-
- if (t == XML_END) {
- log_error("Premature end of XML data.");
- return -EBADMSG;
- }
-
- switch (state) {
-
- case STATE_ANNOTATION:
-
- if (t == XML_ATTRIBUTE_NAME) {
-
- if (streq_ptr(name, "name"))
- state = STATE_NAME;
-
- else if (streq_ptr(name, "value"))
- state = STATE_VALUE;
-
- else {
- log_error("Unexpected <annotation> attribute %s.", name);
- return -EBADMSG;
- }
-
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "annotation"))) {
-
- if (flags) {
- if (streq_ptr(field, "org.freedesktop.DBus.Deprecated")) {
-
- if (streq_ptr(value, "true"))
- *flags |= SD_BUS_VTABLE_DEPRECATED;
-
- } else if (streq_ptr(field, "org.freedesktop.DBus.Method.NoReply")) {
-
- if (streq_ptr(value, "true"))
- *flags |= SD_BUS_VTABLE_METHOD_NO_REPLY;
-
- } else if (streq_ptr(field, "org.freedesktop.DBus.Property.EmitsChangedSignal")) {
-
- if (streq_ptr(value, "const"))
- *flags = (*flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION|SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE)) | SD_BUS_VTABLE_PROPERTY_CONST;
- else if (streq_ptr(value, "invalidates"))
- *flags = (*flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_CONST)) | SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION;
- else if (streq_ptr(value, "false"))
- *flags = *flags & ~(SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE|SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION);
- }
- }
-
- return 0;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in <annotation>. (1)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free_and_replace(field, name);
-
- state = STATE_ANNOTATION;
- } else {
- log_error("Unexpected token in <annotation>. (2)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_VALUE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free_and_replace(value, name);
-
- state = STATE_ANNOTATION;
- } else {
- log_error("Unexpected token in <annotation>. (3)");
- return -EINVAL;
- }
-
- break;
-
- default:
- assert_not_reached("Bad state");
- }
- }
-}
-
-static int parse_xml_node(Context *context, const char *prefix, unsigned n_depth) {
-
- enum {
- STATE_NODE,
- STATE_NODE_NAME,
- STATE_INTERFACE,
- STATE_INTERFACE_NAME,
- STATE_METHOD,
- STATE_METHOD_NAME,
- STATE_METHOD_ARG,
- STATE_METHOD_ARG_NAME,
- STATE_METHOD_ARG_TYPE,
- STATE_METHOD_ARG_DIRECTION,
- STATE_SIGNAL,
- STATE_SIGNAL_NAME,
- STATE_SIGNAL_ARG,
- STATE_SIGNAL_ARG_NAME,
- STATE_SIGNAL_ARG_TYPE,
- STATE_SIGNAL_ARG_DIRECTION,
- STATE_PROPERTY,
- STATE_PROPERTY_NAME,
- STATE_PROPERTY_TYPE,
- STATE_PROPERTY_ACCESS,
- } state = STATE_NODE;
-
- _cleanup_free_ char *node_path = NULL, *argument_type = NULL, *argument_direction = NULL;
- const char *np = prefix;
- int r;
-
- assert(context);
- assert(prefix);
-
- if (n_depth > NODE_DEPTH_MAX) {
- log_error("<node> depth too high.");
- return -EINVAL;
- }
-
- for (;;) {
- _cleanup_free_ char *name = NULL;
- int t;
-
- t = xml_tokenize(&context->current, &name, &context->xml_state, NULL);
- if (t < 0) {
- log_error("XML parse error.");
- return t;
- }
-
- if (t == XML_END) {
- log_error("Premature end of XML data.");
- return -EBADMSG;
- }
-
- switch (state) {
-
- case STATE_NODE:
- if (t == XML_ATTRIBUTE_NAME) {
-
- if (streq_ptr(name, "name"))
- state = STATE_NODE_NAME;
- else {
- log_error("Unexpected <node> attribute %s.", name);
- return -EBADMSG;
- }
-
- } else if (t == XML_TAG_OPEN) {
-
- if (streq_ptr(name, "interface"))
- state = STATE_INTERFACE;
- else if (streq_ptr(name, "node")) {
-
- r = parse_xml_node(context, np, n_depth+1);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected <node> tag %s.", name);
- return -EBADMSG;
- }
-
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "node"))) {
-
- if (context->ops->on_path) {
- r = context->ops->on_path(node_path ? node_path : np, context->userdata);
- if (r < 0)
- return r;
- }
-
- return 0;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in <node>. (1)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_NODE_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
-
- free(node_path);
-
- if (name[0] == '/') {
- node_path = name;
- name = NULL;
- } else {
-
- if (endswith(prefix, "/"))
- node_path = strappend(prefix, name);
- else
- node_path = strjoin(prefix, "/", name);
- if (!node_path)
- return log_oom();
- }
-
- np = node_path;
- state = STATE_NODE;
- } else {
- log_error("Unexpected token in <node>. (2)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_INTERFACE:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq_ptr(name, "name"))
- state = STATE_INTERFACE_NAME;
- else {
- log_error("Unexpected <interface> attribute %s.", name);
- return -EBADMSG;
- }
-
- } else if (t == XML_TAG_OPEN) {
- if (streq_ptr(name, "method"))
- state = STATE_METHOD;
- else if (streq_ptr(name, "signal"))
- state = STATE_SIGNAL;
- else if (streq_ptr(name, "property")) {
- context->member_flags |= SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE;
- state = STATE_PROPERTY;
- } else if (streq_ptr(name, "annotation")) {
- r = parse_xml_annotation(context, &context->interface_flags);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected <interface> tag %s.", name);
- return -EINVAL;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "interface"))) {
-
- if (n_depth == 0) {
- if (context->ops->on_interface) {
- r = context->ops->on_interface(context->interface_name, context->interface_flags, context->userdata);
- if (r < 0)
- return r;
- }
-
- context_reset_interface(context);
- }
-
- state = STATE_NODE;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in <interface>. (1)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_INTERFACE_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (n_depth == 0)
- free_and_replace(context->interface_name, name);
-
- state = STATE_INTERFACE;
- } else {
- log_error("Unexpected token in <interface>. (2)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_METHOD:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq_ptr(name, "name"))
- state = STATE_METHOD_NAME;
- else {
- log_error("Unexpected <method> attribute %s", name);
- return -EBADMSG;
- }
- } else if (t == XML_TAG_OPEN) {
- if (streq_ptr(name, "arg"))
- state = STATE_METHOD_ARG;
- else if (streq_ptr(name, "annotation")) {
- r = parse_xml_annotation(context, &context->member_flags);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected <method> tag %s.", name);
- return -EINVAL;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "method"))) {
-
- if (n_depth == 0) {
- if (context->ops->on_method) {
- r = context->ops->on_method(context->interface_name, context->member_name, context->member_signature, context->member_result, context->member_flags, context->userdata);
- if (r < 0)
- return r;
- }
-
- context_reset_member(context);
- }
-
- state = STATE_INTERFACE;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in <method> (1).");
- return -EINVAL;
- }
-
- break;
-
- case STATE_METHOD_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (n_depth == 0)
- free_and_replace(context->member_name, name);
-
- state = STATE_METHOD;
- } else {
- log_error("Unexpected token in <method> (2).");
- return -EINVAL;
- }
-
- break;
-
- case STATE_METHOD_ARG:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq_ptr(name, "name"))
- state = STATE_METHOD_ARG_NAME;
- else if (streq_ptr(name, "type"))
- state = STATE_METHOD_ARG_TYPE;
- else if (streq_ptr(name, "direction"))
- state = STATE_METHOD_ARG_DIRECTION;
- else {
- log_error("Unexpected method <arg> attribute %s.", name);
- return -EBADMSG;
- }
- } else if (t == XML_TAG_OPEN) {
- if (streq_ptr(name, "annotation")) {
- r = parse_xml_annotation(context, NULL);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected method <arg> tag %s.", name);
- return -EINVAL;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
-
- if (n_depth == 0) {
-
- if (argument_type) {
- if (!argument_direction || streq(argument_direction, "in")) {
- if (!strextend(&context->member_signature, argument_type, NULL))
- return log_oom();
- } else if (streq(argument_direction, "out")) {
- if (!strextend(&context->member_result, argument_type, NULL))
- return log_oom();
- } else
- log_error("Unexpected method <arg> direction value '%s'.", argument_direction);
- }
-
- argument_type = mfree(argument_type);
- argument_direction = mfree(argument_direction);
- }
-
- state = STATE_METHOD;
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in method <arg>. (1)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_METHOD_ARG_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE)
- state = STATE_METHOD_ARG;
- else {
- log_error("Unexpected token in method <arg>. (2)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_METHOD_ARG_TYPE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free_and_replace(argument_type, name);
-
- state = STATE_METHOD_ARG;
- } else {
- log_error("Unexpected token in method <arg>. (3)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_METHOD_ARG_DIRECTION:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free_and_replace(argument_direction, name);
-
- state = STATE_METHOD_ARG;
- } else {
- log_error("Unexpected token in method <arg>. (4)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_SIGNAL:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq_ptr(name, "name"))
- state = STATE_SIGNAL_NAME;
- else {
- log_error("Unexpected <signal> attribute %s.", name);
- return -EBADMSG;
- }
- } else if (t == XML_TAG_OPEN) {
- if (streq_ptr(name, "arg"))
- state = STATE_SIGNAL_ARG;
- else if (streq_ptr(name, "annotation")) {
- r = parse_xml_annotation(context, &context->member_flags);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected <signal> tag %s.", name);
- return -EINVAL;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "signal"))) {
-
- if (n_depth == 0) {
- if (context->ops->on_signal) {
- r = context->ops->on_signal(context->interface_name, context->member_name, context->member_signature, context->member_flags, context->userdata);
- if (r < 0)
- return r;
- }
-
- context_reset_member(context);
- }
-
- state = STATE_INTERFACE;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in <signal>. (1)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_SIGNAL_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (n_depth == 0)
- free_and_replace(context->member_name, name);
-
- state = STATE_SIGNAL;
- } else {
- log_error("Unexpected token in <signal>. (2)");
- return -EINVAL;
- }
-
- break;
-
-
- case STATE_SIGNAL_ARG:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq_ptr(name, "name"))
- state = STATE_SIGNAL_ARG_NAME;
- else if (streq_ptr(name, "type"))
- state = STATE_SIGNAL_ARG_TYPE;
- else if (streq_ptr(name, "direction"))
- state = STATE_SIGNAL_ARG_DIRECTION;
- else {
- log_error("Unexpected signal <arg> attribute %s.", name);
- return -EBADMSG;
- }
- } else if (t == XML_TAG_OPEN) {
- if (streq_ptr(name, "annotation")) {
- r = parse_xml_annotation(context, NULL);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected signal <arg> tag %s.", name);
- return -EINVAL;
- }
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "arg"))) {
-
- if (argument_type) {
- if (!argument_direction || streq(argument_direction, "out")) {
- if (!strextend(&context->member_signature, argument_type, NULL))
- return log_oom();
- } else
- log_error("Unexpected signal <arg> direction value '%s'.", argument_direction);
-
- argument_type = mfree(argument_type);
- }
-
- state = STATE_SIGNAL;
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in signal <arg> (1).");
- return -EINVAL;
- }
-
- break;
-
- case STATE_SIGNAL_ARG_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE)
- state = STATE_SIGNAL_ARG;
- else {
- log_error("Unexpected token in signal <arg> (2).");
- return -EINVAL;
- }
-
- break;
-
- case STATE_SIGNAL_ARG_TYPE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free_and_replace(argument_type, name);
-
- state = STATE_SIGNAL_ARG;
- } else {
- log_error("Unexpected token in signal <arg> (3).");
- return -EINVAL;
- }
-
- break;
-
- case STATE_SIGNAL_ARG_DIRECTION:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- free_and_replace(argument_direction, name);
-
- state = STATE_SIGNAL_ARG;
- } else {
- log_error("Unexpected token in signal <arg>. (4)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_PROPERTY:
-
- if (t == XML_ATTRIBUTE_NAME) {
- if (streq_ptr(name, "name"))
- state = STATE_PROPERTY_NAME;
- else if (streq_ptr(name, "type"))
- state = STATE_PROPERTY_TYPE;
- else if (streq_ptr(name, "access"))
- state = STATE_PROPERTY_ACCESS;
- else {
- log_error("Unexpected <property> attribute %s.", name);
- return -EBADMSG;
- }
- } else if (t == XML_TAG_OPEN) {
-
- if (streq_ptr(name, "annotation")) {
- r = parse_xml_annotation(context, &context->member_flags);
- if (r < 0)
- return r;
- } else {
- log_error("Unexpected <property> tag %s.", name);
- return -EINVAL;
- }
-
- } else if (t == XML_TAG_CLOSE_EMPTY ||
- (t == XML_TAG_CLOSE && streq_ptr(name, "property"))) {
-
- if (n_depth == 0) {
- if (context->ops->on_property) {
- r = context->ops->on_property(context->interface_name, context->member_name, context->member_signature, context->member_writable, context->member_flags, context->userdata);
- if (r < 0)
- return r;
- }
-
- context_reset_member(context);
- }
-
- state = STATE_INTERFACE;
-
- } else if (t != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token in <property>. (1)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_PROPERTY_NAME:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (n_depth == 0)
- free_and_replace(context->member_name, name);
-
- state = STATE_PROPERTY;
- } else {
- log_error("Unexpected token in <property>. (2)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_PROPERTY_TYPE:
-
- if (t == XML_ATTRIBUTE_VALUE) {
- if (n_depth == 0)
- free_and_replace(context->member_signature, name);
-
- state = STATE_PROPERTY;
- } else {
- log_error("Unexpected token in <property>. (3)");
- return -EINVAL;
- }
-
- break;
-
- case STATE_PROPERTY_ACCESS:
-
- if (t == XML_ATTRIBUTE_VALUE) {
-
- if (streq(name, "readwrite") || streq(name, "write"))
- context->member_writable = true;
-
- state = STATE_PROPERTY;
- } else {
- log_error("Unexpected token in <property>. (4)");
- return -EINVAL;
- }
-
- break;
- }
- }
-}
-
-int parse_xml_introspect(const char *prefix, const char *xml, const XMLIntrospectOps *ops, void *userdata) {
- Context context = {
- .ops = ops,
- .userdata = userdata,
- .current = xml,
- };
-
- int r;
-
- assert(prefix);
- assert(xml);
- assert(ops);
-
- for (;;) {
- _cleanup_free_ char *name = NULL;
-
- r = xml_tokenize(&context.current, &name, &context.xml_state, NULL);
- if (r < 0) {
- log_error("XML parse error");
- goto finish;
- }
-
- if (r == XML_END) {
- r = 0;
- break;
- }
-
- if (r == XML_TAG_OPEN) {
-
- if (streq(name, "node")) {
- r = parse_xml_node(&context, prefix, 0);
- if (r < 0)
- goto finish;
- } else {
- log_error("Unexpected tag '%s' in introspection data.", name);
- r = -EBADMSG;
- goto finish;
- }
- } else if (r != XML_TEXT || !in_charset(name, WHITESPACE)) {
- log_error("Unexpected token.");
- r = -EBADMSG;
- goto finish;
- }
- }
-
-finish:
- context_reset_interface(&context);
-
- return r;
-}
+++ /dev/null
-#pragma once
-
-/***
- This file is part of systemd.
-
- Copyright 2014 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <stdbool.h>
-
-typedef struct XMLIntrospectOps {
- int (*on_path)(const char *path, void *userdata);
- int (*on_interface)(const char *name, uint64_t flags, void *userdata);
- int (*on_method)(const char *interface, const char *name, const char *signature, const char *result, uint64_t flags, void *userdata);
- int (*on_signal)(const char *interface, const char *name, const char *signature, uint64_t flags, void *userdata);
- int (*on_property)(const char *interface, const char *name, const char *signature, bool writable, uint64_t flags, void *userdata);
-} XMLIntrospectOps;
-
-int parse_xml_introspect(const char *prefix, const char *xml, const XMLIntrospectOps *ops, void *userdata);
+++ /dev/null
-/***
- This file is part of systemd.
-
- Copyright 2013 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <getopt.h>
-
-#include "sd-bus.h"
-
-#include "alloc-util.h"
-#include "bus-dump.h"
-#include "bus-internal.h"
-#include "bus-signature.h"
-#include "bus-type.h"
-#include "bus-util.h"
-#include "busctl-introspect.h"
-#include "escape.h"
-#include "fd-util.h"
-#include "locale-util.h"
-#include "log.h"
-#include "pager.h"
-#include "parse-util.h"
-#include "path-util.h"
-#include "set.h"
-#include "strv.h"
-#include "terminal-util.h"
-#include "user-util.h"
-#include "util.h"
-
-static bool arg_no_pager = false;
-static bool arg_legend = true;
-static char *arg_address = NULL;
-static bool arg_unique = false;
-static bool arg_acquired = false;
-static bool arg_activatable = false;
-static bool arg_show_machine = false;
-static char **arg_matches = NULL;
-static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
-static char *arg_host = NULL;
-static bool arg_user = false;
-static size_t arg_snaplen = 4096;
-static bool arg_list = false;
-static bool arg_quiet = false;
-static bool arg_verbose = false;
-static bool arg_expect_reply = true;
-static bool arg_auto_start = true;
-static bool arg_allow_interactive_authorization = true;
-static bool arg_augment_creds = true;
-static usec_t arg_timeout = 0;
-
-#define NAME_IS_ACQUIRED INT_TO_PTR(1)
-#define NAME_IS_ACTIVATABLE INT_TO_PTR(2)
-
-static int list_bus_names(sd_bus *bus, char **argv) {
- _cleanup_strv_free_ char **acquired = NULL, **activatable = NULL;
- _cleanup_free_ char **merged = NULL;
- _cleanup_hashmap_free_ Hashmap *names = NULL;
- char **i;
- int r;
- size_t max_i = 0;
- unsigned n = 0;
- void *v;
- char *k;
- Iterator iterator;
-
- assert(bus);
-
- if (!arg_unique && !arg_acquired && !arg_activatable)
- arg_unique = arg_acquired = arg_activatable = true;
-
- r = sd_bus_list_names(bus, (arg_acquired || arg_unique) ? &acquired : NULL, arg_activatable ? &activatable : NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to list names: %m");
-
- pager_open(arg_no_pager, false);
-
- names = hashmap_new(&string_hash_ops);
- if (!names)
- return log_oom();
-
- STRV_FOREACH(i, acquired) {
- max_i = MAX(max_i, strlen(*i));
-
- r = hashmap_put(names, *i, NAME_IS_ACQUIRED);
- if (r < 0)
- return log_error_errno(r, "Failed to add to hashmap: %m");
- }
-
- STRV_FOREACH(i, activatable) {
- max_i = MAX(max_i, strlen(*i));
-
- r = hashmap_put(names, *i, NAME_IS_ACTIVATABLE);
- if (r < 0 && r != -EEXIST)
- return log_error_errno(r, "Failed to add to hashmap: %m");
- }
-
- merged = new(char*, hashmap_size(names) + 1);
- HASHMAP_FOREACH_KEY(v, k, names, iterator)
- merged[n++] = k;
-
- merged[n] = NULL;
- strv_sort(merged);
-
- if (arg_legend) {
- printf("%-*s %*s %-*s %-*s %-*s %-*s %-*s %-*s",
- (int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 13, "CONNECTION", 25, "UNIT", 10, "SESSION", 19, "DESCRIPTION");
-
- if (arg_show_machine)
- puts(" MACHINE");
- else
- putchar('\n');
- }
-
- STRV_FOREACH(i, merged) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- sd_id128_t mid;
-
- if (hashmap_get(names, *i) == NAME_IS_ACTIVATABLE) {
- /* Activatable */
-
- printf("%-*s", (int) max_i, *i);
- printf(" - - - (activatable) - - ");
- if (arg_show_machine)
- puts(" -");
- else
- putchar('\n');
- continue;
-
- }
-
- if (!arg_unique && (*i)[0] == ':')
- continue;
-
- if (!arg_acquired && (*i)[0] != ':')
- continue;
-
- printf("%-*s", (int) max_i, *i);
-
- r = sd_bus_get_name_creds(
- bus, *i,
- (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) |
- SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|
- SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_SESSION|
- SD_BUS_CREDS_DESCRIPTION, &creds);
- if (r >= 0) {
- const char *unique, *session, *unit, *cn;
- pid_t pid;
- uid_t uid;
-
- r = sd_bus_creds_get_pid(creds, &pid);
- if (r >= 0) {
- const char *comm = NULL;
-
- sd_bus_creds_get_comm(creds, &comm);
-
- printf(" %10lu %-15s", (unsigned long) pid, strna(comm));
- } else
- fputs(" - - ", stdout);
-
- r = sd_bus_creds_get_euid(creds, &uid);
- if (r >= 0) {
- _cleanup_free_ char *u = NULL;
-
- u = uid_to_name(uid);
- if (!u)
- return log_oom();
-
- if (strlen(u) > 16)
- u[16] = 0;
-
- printf(" %-16s", u);
- } else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_unique_name(creds, &unique);
- if (r >= 0)
- printf(" %-13s", unique);
- else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_unit(creds, &unit);
- if (r >= 0) {
- _cleanup_free_ char *e;
-
- e = ellipsize(unit, 25, 100);
- if (!e)
- return log_oom();
-
- printf(" %-25s", e);
- } else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_session(creds, &session);
- if (r >= 0)
- printf(" %-10s", session);
- else
- fputs(" - ", stdout);
-
- r = sd_bus_creds_get_description(creds, &cn);
- if (r >= 0)
- printf(" %-19s", cn);
- else
- fputs(" - ", stdout);
-
- } else
- printf(" - - - - - - - ");
-
- if (arg_show_machine) {
- r = sd_bus_get_name_machine_id(bus, *i, &mid);
- if (r >= 0) {
- char m[SD_ID128_STRING_MAX];
- printf(" %s\n", sd_id128_to_string(mid, m));
- } else
- puts(" -");
- } else
- putchar('\n');
- }
-
- return 0;
-}
-
-static void print_subtree(const char *prefix, const char *path, char **l) {
- const char *vertical, *space;
- char **n;
-
- /* We assume the list is sorted. Let's first skip over the
- * entry we are looking at. */
- for (;;) {
- if (!*l)
- return;
-
- if (!streq(*l, path))
- break;
-
- l++;
- }
-
- vertical = strjoina(prefix, special_glyph(TREE_VERTICAL));
- space = strjoina(prefix, special_glyph(TREE_SPACE));
-
- for (;;) {
- bool has_more = false;
-
- if (!*l || !path_startswith(*l, path))
- break;
-
- n = l + 1;
- for (;;) {
- if (!*n || !path_startswith(*n, path))
- break;
-
- if (!path_startswith(*n, *l)) {
- has_more = true;
- break;
- }
-
- n++;
- }
-
- printf("%s%s%s\n", prefix, special_glyph(has_more ? TREE_BRANCH : TREE_RIGHT), *l);
-
- print_subtree(has_more ? vertical : space, *l, l);
- l = n;
- }
-}
-
-static void print_tree(const char *prefix, char **l) {
-
- pager_open(arg_no_pager, false);
-
- prefix = strempty(prefix);
-
- if (arg_list) {
- char **i;
-
- STRV_FOREACH(i, l)
- printf("%s%s\n", prefix, *i);
- return;
- }
-
- if (strv_isempty(l)) {
- printf("No objects discovered.\n");
- return;
- }
-
- if (streq(l[0], "/") && !l[1]) {
- printf("Only root object discovered.\n");
- return;
- }
-
- print_subtree(prefix, "/", l);
-}
-
-static int on_path(const char *path, void *userdata) {
- Set *paths = userdata;
- int r;
-
- assert(paths);
-
- r = set_put_strdup(paths, path);
- if (r < 0)
- return log_oom();
-
- return 0;
-}
-
-static int find_nodes(sd_bus *bus, const char *service, const char *path, Set *paths, bool many) {
- static const XMLIntrospectOps ops = {
- .on_path = on_path,
- };
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- const char *xml;
- int r;
-
- r = sd_bus_call_method(bus, service, path, "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- if (r < 0) {
- if (many)
- printf("Failed to introspect object %s of service %s: %s\n", path, service, bus_error_message(&error, r));
- else
- log_error("Failed to introspect object %s of service %s: %s", path, service, bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_read(reply, "s", &xml);
- if (r < 0)
- return bus_log_parse_error(r);
-
- return parse_xml_introspect(path, xml, &ops, paths);
-}
-
-static int tree_one(sd_bus *bus, const char *service, const char *prefix, bool many) {
- _cleanup_set_free_free_ Set *paths = NULL, *done = NULL, *failed = NULL;
- _cleanup_free_ char **l = NULL;
- char *m;
- int r;
-
- paths = set_new(&string_hash_ops);
- if (!paths)
- return log_oom();
-
- done = set_new(&string_hash_ops);
- if (!done)
- return log_oom();
-
- failed = set_new(&string_hash_ops);
- if (!failed)
- return log_oom();
-
- m = strdup("/");
- if (!m)
- return log_oom();
-
- r = set_put(paths, m);
- if (r < 0) {
- free(m);
- return log_oom();
- }
-
- for (;;) {
- _cleanup_free_ char *p = NULL;
- int q;
-
- p = set_steal_first(paths);
- if (!p)
- break;
-
- if (set_contains(done, p) ||
- set_contains(failed, p))
- continue;
-
- q = find_nodes(bus, service, p, paths, many);
- if (q < 0) {
- if (r >= 0)
- r = q;
-
- q = set_put(failed, p);
- } else
- q = set_put(done, p);
-
- if (q < 0)
- return log_oom();
-
- assert(q != 0);
- p = NULL;
- }
-
- pager_open(arg_no_pager, false);
-
- l = set_get_strv(done);
- if (!l)
- return log_oom();
-
- strv_sort(l);
- print_tree(prefix, l);
-
- fflush(stdout);
-
- return r;
-}
-
-static int tree(sd_bus *bus, char **argv) {
- char **i;
- int r = 0;
-
- if (!arg_unique && !arg_acquired)
- arg_acquired = true;
-
- if (strv_length(argv) <= 1) {
- _cleanup_strv_free_ char **names = NULL;
- bool not_first = false;
-
- r = sd_bus_list_names(bus, &names, NULL);
- if (r < 0)
- return log_error_errno(r, "Failed to get name list: %m");
-
- pager_open(arg_no_pager, false);
-
- STRV_FOREACH(i, names) {
- int q;
-
- if (!arg_unique && (*i)[0] == ':')
- continue;
-
- if (!arg_acquired && (*i)[0] == ':')
- continue;
-
- if (not_first)
- printf("\n");
-
- printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
-
- q = tree_one(bus, *i, NULL, true);
- if (q < 0 && r >= 0)
- r = q;
-
- not_first = true;
- }
- } else {
- STRV_FOREACH(i, argv+1) {
- int q;
-
- if (i > argv+1)
- printf("\n");
-
- if (argv[2]) {
- pager_open(arg_no_pager, false);
- printf("Service %s%s%s:\n", ansi_highlight(), *i, ansi_normal());
- }
-
- q = tree_one(bus, *i, NULL, !!argv[2]);
- if (q < 0 && r >= 0)
- r = q;
- }
- }
-
- return r;
-}
-
-static int format_cmdline(sd_bus_message *m, FILE *f, bool needs_space) {
- int r;
-
- for (;;) {
- const char *contents = NULL;
- char type;
- union {
- uint8_t u8;
- uint16_t u16;
- int16_t s16;
- uint32_t u32;
- int32_t s32;
- uint64_t u64;
- int64_t s64;
- double d64;
- const char *string;
- int i;
- } basic;
-
- r = sd_bus_message_peek_type(m, &type, &contents);
- if (r < 0)
- return r;
- if (r == 0)
- return needs_space;
-
- if (bus_type_is_container(type) > 0) {
-
- r = sd_bus_message_enter_container(m, type, contents);
- if (r < 0)
- return r;
-
- if (type == SD_BUS_TYPE_ARRAY) {
- unsigned n = 0;
-
- /* count array entries */
- for (;;) {
-
- r = sd_bus_message_skip(m, contents);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- n++;
- }
-
- r = sd_bus_message_rewind(m, false);
- if (r < 0)
- return r;
-
- if (needs_space)
- fputc(' ', f);
-
- fprintf(f, "%u", n);
- needs_space = true;
-
- } else if (type == SD_BUS_TYPE_VARIANT) {
-
- if (needs_space)
- fputc(' ', f);
-
- fprintf(f, "%s", contents);
- needs_space = true;
- }
-
- r = format_cmdline(m, f, needs_space);
- if (r < 0)
- return r;
-
- needs_space = r > 0;
-
- r = sd_bus_message_exit_container(m);
- if (r < 0)
- return r;
-
- continue;
- }
-
- r = sd_bus_message_read_basic(m, type, &basic);
- if (r < 0)
- return r;
-
- if (needs_space)
- fputc(' ', f);
-
- switch (type) {
- case SD_BUS_TYPE_BYTE:
- fprintf(f, "%u", basic.u8);
- break;
-
- case SD_BUS_TYPE_BOOLEAN:
- fputs(true_false(basic.i), f);
- break;
-
- case SD_BUS_TYPE_INT16:
- fprintf(f, "%i", basic.s16);
- break;
-
- case SD_BUS_TYPE_UINT16:
- fprintf(f, "%u", basic.u16);
- break;
-
- case SD_BUS_TYPE_INT32:
- fprintf(f, "%i", basic.s32);
- break;
-
- case SD_BUS_TYPE_UINT32:
- fprintf(f, "%u", basic.u32);
- break;
-
- case SD_BUS_TYPE_INT64:
- fprintf(f, "%" PRIi64, basic.s64);
- break;
-
- case SD_BUS_TYPE_UINT64:
- fprintf(f, "%" PRIu64, basic.u64);
- break;
-
- case SD_BUS_TYPE_DOUBLE:
- fprintf(f, "%g", basic.d64);
- break;
-
- case SD_BUS_TYPE_STRING:
- case SD_BUS_TYPE_OBJECT_PATH:
- case SD_BUS_TYPE_SIGNATURE: {
- _cleanup_free_ char *b = NULL;
-
- b = cescape(basic.string);
- if (!b)
- return -ENOMEM;
-
- fprintf(f, "\"%s\"", b);
- break;
- }
-
- case SD_BUS_TYPE_UNIX_FD:
- fprintf(f, "%i", basic.i);
- break;
-
- default:
- assert_not_reached("Unknown basic type.");
- }
-
- needs_space = true;
- }
-}
-
-typedef struct Member {
- const char *type;
- char *interface;
- char *name;
- char *signature;
- char *result;
- char *value;
- bool writable;
- uint64_t flags;
-} Member;
-
-static void member_hash_func(const void *p, struct siphash *state) {
- const Member *m = p;
- uint64_t arity = 1;
-
- assert(m);
- assert(m->type);
-
- string_hash_func(m->type, state);
-
- arity += !!m->name + !!m->interface;
-
- uint64_hash_func(&arity, state);
-
- if (m->name)
- string_hash_func(m->name, state);
-
- if (m->interface)
- string_hash_func(m->interface, state);
-}
-
-static int member_compare_func(const void *a, const void *b) {
- const Member *x = a, *y = b;
- int d;
-
- assert(x);
- assert(y);
- assert(x->type);
- assert(y->type);
-
- d = strcmp_ptr(x->interface, y->interface);
- if (d != 0)
- return d;
-
- d = strcmp(x->type, y->type);
- if (d != 0)
- return d;
-
- return strcmp_ptr(x->name, y->name);
-}
-
-static int member_compare_funcp(const void *a, const void *b) {
- const Member *const * x = (const Member *const *) a, * const *y = (const Member *const *) b;
-
- return member_compare_func(*x, *y);
-}
-
-static void member_free(Member *m) {
- if (!m)
- return;
-
- free(m->interface);
- free(m->name);
- free(m->signature);
- free(m->result);
- free(m->value);
- free(m);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Member*, member_free);
-
-static void member_set_free(Set *s) {
- Member *m;
-
- while ((m = set_steal_first(s)))
- member_free(m);
-
- set_free(s);
-}
-
-DEFINE_TRIVIAL_CLEANUP_FUNC(Set*, member_set_free);
-
-static int on_interface(const char *interface, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(members);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "interface";
- m->flags = flags;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate interface");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static int on_method(const char *interface, const char *name, const char *signature, const char *result, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(name);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "method";
- m->flags = flags;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->name, name);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->signature, signature);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->result, result);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate method");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static int on_signal(const char *interface, const char *name, const char *signature, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(name);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "signal";
- m->flags = flags;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->name, name);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->signature, signature);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate signal");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static int on_property(const char *interface, const char *name, const char *signature, bool writable, uint64_t flags, void *userdata) {
- _cleanup_(member_freep) Member *m;
- Set *members = userdata;
- int r;
-
- assert(interface);
- assert(name);
-
- m = new0(Member, 1);
- if (!m)
- return log_oom();
-
- m->type = "property";
- m->flags = flags;
- m->writable = writable;
-
- r = free_and_strdup(&m->interface, interface);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->name, name);
- if (r < 0)
- return log_oom();
-
- r = free_and_strdup(&m->signature, signature);
- if (r < 0)
- return log_oom();
-
- r = set_put(members, m);
- if (r <= 0) {
- log_error("Duplicate property");
- return -EINVAL;
- }
-
- m = NULL;
- return 0;
-}
-
-static const char *strdash(const char *x) {
- return isempty(x) ? "-" : x;
-}
-
-static int introspect(sd_bus *bus, char **argv) {
- static const struct hash_ops member_hash_ops = {
- .hash = member_hash_func,
- .compare = member_compare_func,
- };
-
- static const XMLIntrospectOps ops = {
- .on_interface = on_interface,
- .on_method = on_method,
- .on_signal = on_signal,
- .on_property = on_property,
- };
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(member_set_freep) Set *members = NULL;
- Iterator i;
- Member *m;
- const char *xml;
- int r;
- unsigned name_width, type_width, signature_width, result_width;
- Member **sorted = NULL;
- unsigned k = 0, j, n_args;
-
- n_args = strv_length(argv);
- if (n_args < 3) {
- log_error("Requires service and object path argument.");
- return -EINVAL;
- }
-
- if (n_args > 4) {
- log_error("Too many arguments.");
- return -EINVAL;
- }
-
- members = set_new(&member_hash_ops);
- if (!members)
- return log_oom();
-
- r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Introspectable", "Introspect", &error, &reply, "");
- if (r < 0) {
- log_error("Failed to introspect object %s of service %s: %s", argv[2], argv[1], bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_read(reply, "s", &xml);
- if (r < 0)
- return bus_log_parse_error(r);
-
- /* First, get list of all properties */
- r = parse_xml_introspect(argv[2], xml, &ops, members);
- if (r < 0)
- return r;
-
- /* Second, find the current values for them */
- SET_FOREACH(m, members, i) {
-
- if (!streq(m->type, "property"))
- continue;
-
- if (m->value)
- continue;
-
- if (argv[3] && !streq(argv[3], m->interface))
- continue;
-
- r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "GetAll", &error, &reply, "s", m->interface);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_enter_container(reply, 'a', "{sv}");
- if (r < 0)
- return bus_log_parse_error(r);
-
- for (;;) {
- Member *z;
- _cleanup_free_ char *buf = NULL;
- _cleanup_fclose_ FILE *mf = NULL;
- size_t sz = 0;
- const char *name;
-
- r = sd_bus_message_enter_container(reply, 'e', "sv");
- if (r < 0)
- return bus_log_parse_error(r);
-
- if (r == 0)
- break;
-
- r = sd_bus_message_read(reply, "s", &name);
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_enter_container(reply, 'v', NULL);
- if (r < 0)
- return bus_log_parse_error(r);
-
- mf = open_memstream(&buf, &sz);
- if (!mf)
- return log_oom();
-
- r = format_cmdline(reply, mf, false);
- if (r < 0)
- return bus_log_parse_error(r);
-
- fclose(mf);
- mf = NULL;
-
- z = set_get(members, &((Member) {
- .type = "property",
- .interface = m->interface,
- .name = (char*) name }));
- if (z) {
- free(z->value);
- z->value = buf;
- buf = NULL;
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
- }
-
- pager_open(arg_no_pager, false);
-
- name_width = strlen("NAME");
- type_width = strlen("TYPE");
- signature_width = strlen("SIGNATURE");
- result_width = strlen("RESULT/VALUE");
-
- sorted = newa(Member*, set_size(members));
-
- SET_FOREACH(m, members, i) {
-
- if (argv[3] && !streq(argv[3], m->interface))
- continue;
-
- if (m->interface)
- name_width = MAX(name_width, strlen(m->interface));
- if (m->name)
- name_width = MAX(name_width, strlen(m->name) + 1);
- if (m->type)
- type_width = MAX(type_width, strlen(m->type));
- if (m->signature)
- signature_width = MAX(signature_width, strlen(m->signature));
- if (m->result)
- result_width = MAX(result_width, strlen(m->result));
- if (m->value)
- result_width = MAX(result_width, strlen(m->value));
-
- sorted[k++] = m;
- }
-
- if (result_width > 40)
- result_width = 40;
-
- qsort(sorted, k, sizeof(Member*), member_compare_funcp);
-
- if (arg_legend) {
- printf("%-*s %-*s %-*s %-*s %s\n",
- (int) name_width, "NAME",
- (int) type_width, "TYPE",
- (int) signature_width, "SIGNATURE",
- (int) result_width, "RESULT/VALUE",
- "FLAGS");
- }
-
- for (j = 0; j < k; j++) {
- _cleanup_free_ char *ellipsized = NULL;
- const char *rv;
- bool is_interface;
-
- m = sorted[j];
-
- if (argv[3] && !streq(argv[3], m->interface))
- continue;
-
- is_interface = streq(m->type, "interface");
-
- if (argv[3] && is_interface)
- continue;
-
- if (m->value) {
- ellipsized = ellipsize(m->value, result_width, 100);
- if (!ellipsized)
- return log_oom();
-
- rv = ellipsized;
- } else
- rv = strdash(m->result);
-
- printf("%s%s%-*s%s %-*s %-*s %-*s%s%s%s%s%s%s\n",
- is_interface ? ansi_highlight() : "",
- is_interface ? "" : ".",
- - !is_interface + (int) name_width, strdash(streq_ptr(m->type, "interface") ? m->interface : m->name),
- is_interface ? ansi_normal() : "",
- (int) type_width, strdash(m->type),
- (int) signature_width, strdash(m->signature),
- (int) result_width, rv,
- (m->flags & SD_BUS_VTABLE_DEPRECATED) ? " deprecated" : (m->flags || m->writable ? "" : " -"),
- (m->flags & SD_BUS_VTABLE_METHOD_NO_REPLY) ? " no-reply" : "",
- (m->flags & SD_BUS_VTABLE_PROPERTY_CONST) ? " const" : "",
- (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE) ? " emits-change" : "",
- (m->flags & SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION) ? " emits-invalidation" : "",
- m->writable ? " writable" : "");
- }
-
- return 0;
-}
-
-static int message_dump(sd_bus_message *m, FILE *f) {
- return bus_message_dump(m, f, BUS_MESSAGE_DUMP_WITH_HEADER);
-}
-
-static int message_pcap(sd_bus_message *m, FILE *f) {
- return bus_message_pcap_frame(m, arg_snaplen, f);
-}
-
-static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FILE *f)) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char **i;
- uint32_t flags = 0;
- int r;
-
- /* upgrade connection; it's not used for anything else after this call */
- r = sd_bus_message_new_method_call(bus, &message, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus.Monitoring", "BecomeMonitor");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(message, 'a', "s");
- if (r < 0)
- return bus_log_create_error(r);
-
- STRV_FOREACH(i, argv+1) {
- _cleanup_free_ char *m = NULL;
-
- if (!service_name_is_valid(*i)) {
- log_error("Invalid service name '%s'", *i);
- return -EINVAL;
- }
-
- m = strjoin("sender='", *i, "'");
- if (!m)
- return log_oom();
-
- r = sd_bus_message_append_basic(message, 's', m);
- if (r < 0)
- return bus_log_create_error(r);
-
- free(m);
- m = strjoin("destination='", *i, "'");
- if (!m)
- return log_oom();
-
- r = sd_bus_message_append_basic(message, 's', m);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- STRV_FOREACH(i, arg_matches) {
- r = sd_bus_message_append_basic(message, 's', *i);
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- r = sd_bus_message_close_container(message);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append_basic(message, 'u', &flags);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_call(bus, message, arg_timeout, &error, NULL);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- log_info("Monitoring bus message stream.");
-
- for (;;) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
-
- r = sd_bus_process(bus, &m);
- if (r < 0)
- return log_error_errno(r, "Failed to process bus: %m");
-
- if (m) {
- dump(m, stdout);
- fflush(stdout);
-
- if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) {
- log_info("Connection terminated, exiting.");
- return 0;
- }
-
- continue;
- }
-
- if (r > 0)
- continue;
-
- r = sd_bus_wait(bus, (uint64_t) -1);
- if (r < 0)
- return log_error_errno(r, "Failed to wait for bus: %m");
- }
-}
-
-static int capture(sd_bus *bus, char *argv[]) {
- int r;
-
- if (isatty(fileno(stdout)) > 0) {
- log_error("Refusing to write message data to console, please redirect output to a file.");
- return -EINVAL;
- }
-
- bus_pcap_header(arg_snaplen, stdout);
-
- r = monitor(bus, argv, message_pcap);
- if (r < 0)
- return r;
-
- if (ferror(stdout)) {
- log_error("Couldn't write capture file.");
- return -EIO;
- }
-
- return r;
-}
-
-static int status(sd_bus *bus, char *argv[]) {
- _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- pid_t pid;
- int r;
-
- assert(bus);
-
- if (strv_length(argv) > 2) {
- log_error("Expects no or one argument.");
- return -EINVAL;
- }
-
- if (argv[1]) {
- r = parse_pid(argv[1], &pid);
- if (r < 0)
- r = sd_bus_get_name_creds(
- bus,
- argv[1],
- (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
- &creds);
- else
- r = sd_bus_creds_new_from_pid(
- &creds,
- pid,
- _SD_BUS_CREDS_ALL);
- } else {
- const char *scope, *address;
- sd_id128_t bus_id;
-
- r = sd_bus_get_address(bus, &address);
- if (r >= 0)
- printf("BusAddress=%s%s%s\n", ansi_highlight(), address, ansi_normal());
-
- r = sd_bus_get_scope(bus, &scope);
- if (r >= 0)
- printf("BusScope=%s%s%s\n", ansi_highlight(), scope, ansi_normal());
-
- r = sd_bus_get_bus_id(bus, &bus_id);
- if (r >= 0)
- printf("BusID=%s" SD_ID128_FORMAT_STR "%s\n", ansi_highlight(), SD_ID128_FORMAT_VAL(bus_id), ansi_normal());
-
- r = sd_bus_get_owner_creds(
- bus,
- (arg_augment_creds ? SD_BUS_CREDS_AUGMENT : 0) | _SD_BUS_CREDS_ALL,
- &creds);
- }
-
- if (r < 0)
- return log_error_errno(r, "Failed to get credentials: %m");
-
- bus_creds_dump(creds, NULL, false);
- return 0;
-}
-
-static int message_append_cmdline(sd_bus_message *m, const char *signature, char ***x) {
- char **p;
- int r;
-
- assert(m);
- assert(signature);
- assert(x);
-
- p = *x;
-
- for (;;) {
- const char *v;
- char t;
-
- t = *signature;
- v = *p;
-
- if (t == 0)
- break;
- if (!v) {
- log_error("Too few parameters for signature.");
- return -EINVAL;
- }
-
- signature++;
- p++;
-
- switch (t) {
-
- case SD_BUS_TYPE_BOOLEAN:
-
- r = parse_boolean(v);
- if (r < 0) {
- log_error("Failed to parse as boolean: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &r);
- break;
-
- case SD_BUS_TYPE_BYTE: {
- uint8_t z;
-
- r = safe_atou8(v, &z);
- if (r < 0) {
- log_error("Failed to parse as byte (unsigned 8bit integer): %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_INT16: {
- int16_t z;
-
- r = safe_atoi16(v, &z);
- if (r < 0) {
- log_error("Failed to parse as signed 16bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_UINT16: {
- uint16_t z;
-
- r = safe_atou16(v, &z);
- if (r < 0) {
- log_error("Failed to parse as unsigned 16bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_INT32: {
- int32_t z;
-
- r = safe_atoi32(v, &z);
- if (r < 0) {
- log_error("Failed to parse as signed 32bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_UINT32: {
- uint32_t z;
-
- r = safe_atou32(v, &z);
- if (r < 0) {
- log_error("Failed to parse as unsigned 32bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_INT64: {
- int64_t z;
-
- r = safe_atoi64(v, &z);
- if (r < 0) {
- log_error("Failed to parse as signed 64bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_UINT64: {
- uint64_t z;
-
- r = safe_atou64(v, &z);
- if (r < 0) {
- log_error("Failed to parse as unsigned 64bit integer: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
-
- case SD_BUS_TYPE_DOUBLE: {
- double z;
-
- r = safe_atod(v, &z);
- if (r < 0) {
- log_error("Failed to parse as double precision floating point: %s", v);
- return r;
- }
-
- r = sd_bus_message_append_basic(m, t, &z);
- break;
- }
-
- case SD_BUS_TYPE_STRING:
- case SD_BUS_TYPE_OBJECT_PATH:
- case SD_BUS_TYPE_SIGNATURE:
-
- r = sd_bus_message_append_basic(m, t, v);
- break;
-
- case SD_BUS_TYPE_ARRAY: {
- uint32_t n;
- size_t k;
-
- r = safe_atou32(v, &n);
- if (r < 0) {
- log_error("Failed to parse number of array entries: %s", v);
- return r;
- }
-
- r = signature_element_length(signature, &k);
- if (r < 0) {
- log_error("Invalid array signature.");
- return r;
- }
-
- {
- unsigned i;
- char s[k + 1];
- memcpy(s, signature, k);
- s[k] = 0;
-
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
- if (r < 0)
- return bus_log_create_error(r);
-
- for (i = 0; i < n; i++) {
- r = message_append_cmdline(m, s, &p);
- if (r < 0)
- return r;
- }
- }
-
- signature += k;
-
- r = sd_bus_message_close_container(m);
- break;
- }
-
- case SD_BUS_TYPE_VARIANT:
- r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, v);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = message_append_cmdline(m, v, &p);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(m);
- break;
-
- case SD_BUS_TYPE_STRUCT_BEGIN:
- case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
- size_t k;
-
- signature--;
- p--;
-
- r = signature_element_length(signature, &k);
- if (r < 0) {
- log_error("Invalid struct/dict entry signature.");
- return r;
- }
-
- {
- char s[k-1];
- memcpy(s, signature + 1, k - 2);
- s[k - 2] = 0;
-
- r = sd_bus_message_open_container(m, t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = message_append_cmdline(m, s, &p);
- if (r < 0)
- return r;
- }
-
- signature += k;
-
- r = sd_bus_message_close_container(m);
- break;
- }
-
- case SD_BUS_TYPE_UNIX_FD:
- log_error("UNIX file descriptor not supported as type.");
- return -EINVAL;
-
- default:
- log_error("Unknown signature type %c.", t);
- return -EINVAL;
- }
-
- if (r < 0)
- return bus_log_create_error(r);
- }
-
- *x = p;
- return 0;
-}
-
-static int call(sd_bus *bus, char *argv[]) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
- int r;
-
- assert(bus);
-
- if (strv_length(argv) < 5) {
- log_error("Expects at least four arguments.");
- return -EINVAL;
- }
-
- r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], argv[3], argv[4]);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_set_expect_reply(m, arg_expect_reply);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_set_auto_start(m, arg_auto_start);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_set_allow_interactive_authorization(m, arg_allow_interactive_authorization);
- if (r < 0)
- return bus_log_create_error(r);
-
- if (!isempty(argv[5])) {
- char **p;
-
- p = argv+6;
-
- r = message_append_cmdline(m, argv[5], &p);
- if (r < 0)
- return r;
-
- if (*p) {
- log_error("Too many parameters for signature.");
- return -EINVAL;
- }
- }
-
- if (!arg_expect_reply) {
- r = sd_bus_send(bus, m, NULL);
- if (r < 0) {
- log_error("Failed to send message.");
- return r;
- }
-
- return 0;
- }
-
- r = sd_bus_call(bus, m, arg_timeout, &error, &reply);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_is_empty(reply);
- if (r < 0)
- return bus_log_parse_error(r);
-
- if (r == 0 && !arg_quiet) {
-
- if (arg_verbose) {
- pager_open(arg_no_pager, false);
-
- r = bus_message_dump(reply, stdout, 0);
- if (r < 0)
- return r;
- } else {
-
- fputs(sd_bus_message_get_signature(reply, true), stdout);
- fputc(' ', stdout);
-
- r = format_cmdline(reply, stdout, false);
- if (r < 0)
- return bus_log_parse_error(r);
-
- fputc('\n', stdout);
- }
- }
-
- return 0;
-}
-
-static int get_property(sd_bus *bus, char *argv[]) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- unsigned n;
- char **i;
- int r;
-
- assert(bus);
-
- n = strv_length(argv);
- if (n < 5) {
- log_error("Expects at least four arguments.");
- return -EINVAL;
- }
-
- STRV_FOREACH(i, argv + 4) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- const char *contents = NULL;
- char type;
-
- r = sd_bus_call_method(bus, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Get", &error, &reply, "ss", argv[3], *i);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- r = sd_bus_message_peek_type(reply, &type, &contents);
- if (r < 0)
- return bus_log_parse_error(r);
-
- r = sd_bus_message_enter_container(reply, 'v', contents);
- if (r < 0)
- return bus_log_parse_error(r);
-
- if (arg_verbose) {
- pager_open(arg_no_pager, false);
-
- r = bus_message_dump(reply, stdout, BUS_MESSAGE_DUMP_SUBTREE_ONLY);
- if (r < 0)
- return r;
- } else {
- fputs(contents, stdout);
- fputc(' ', stdout);
-
- r = format_cmdline(reply, stdout, false);
- if (r < 0)
- return bus_log_parse_error(r);
-
- fputc('\n', stdout);
- }
-
- r = sd_bus_message_exit_container(reply);
- if (r < 0)
- return bus_log_parse_error(r);
- }
-
- return 0;
-}
-
-static int set_property(sd_bus *bus, char *argv[]) {
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- unsigned n;
- char **p;
- int r;
-
- assert(bus);
-
- n = strv_length(argv);
- if (n < 6) {
- log_error("Expects at least five arguments.");
- return -EINVAL;
- }
-
- r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], "org.freedesktop.DBus.Properties", "Set");
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "ss", argv[3], argv[4]);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_open_container(m, 'v', argv[5]);
- if (r < 0)
- return bus_log_create_error(r);
-
- p = argv+6;
- r = message_append_cmdline(m, argv[5], &p);
- if (r < 0)
- return r;
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return bus_log_create_error(r);
-
- if (*p) {
- log_error("Too many parameters for signature.");
- return -EINVAL;
- }
-
- r = sd_bus_call(bus, m, arg_timeout, &error, NULL);
- if (r < 0) {
- log_error("%s", bus_error_message(&error, r));
- return r;
- }
-
- return 0;
-}
-
-static int help(void) {
- printf("%s [OPTIONS...] {COMMAND} ...\n\n"
- "Introspect the bus.\n\n"
- " -h --help Show this help\n"
- " --version Show package version\n"
- " --no-pager Do not pipe output into a pager\n"
- " --no-legend Do not show the headers and footers\n"
- " --system Connect to system bus\n"
- " --user Connect to user bus\n"
- " -H --host=[USER@]HOST Operate on remote host\n"
- " -M --machine=CONTAINER Operate on local container\n"
- " --address=ADDRESS Connect to bus specified by address\n"
- " --show-machine Show machine ID column in list\n"
- " --unique Only show unique names\n"
- " --acquired Only show acquired names\n"
- " --activatable Only show activatable names\n"
- " --match=MATCH Only show matching messages\n"
- " --size=SIZE Maximum length of captured packet\n"
- " --list Don't show tree, but simple object path list\n"
- " --quiet Don't show method call reply\n"
- " --verbose Show result values in long format\n"
- " --expect-reply=BOOL Expect a method call reply\n"
- " --auto-start=BOOL Auto-start destination service\n"
- " --allow-interactive-authorization=BOOL\n"
- " Allow interactive authorization for operation\n"
- " --timeout=SECS Maximum time to wait for method call completion\n"
- " --augment-creds=BOOL Extend credential data with data read from /proc/$PID\n\n"
- "Commands:\n"
- " list List bus names\n"
- " status [SERVICE] Show bus service, process or bus owner credentials\n"
- " monitor [SERVICE...] Show bus traffic\n"
- " capture [SERVICE...] Capture bus traffic as pcap\n"
- " tree [SERVICE...] Show object tree of service\n"
- " introspect SERVICE OBJECT [INTERFACE]\n"
- " call SERVICE OBJECT INTERFACE METHOD [SIGNATURE [ARGUMENT...]]\n"
- " Call a method\n"
- " get-property SERVICE OBJECT INTERFACE PROPERTY...\n"
- " Get property value\n"
- " set-property SERVICE OBJECT INTERFACE PROPERTY SIGNATURE ARGUMENT...\n"
- " Set property value\n"
- " help Show this help\n"
- , program_invocation_short_name);
-
- return 0;
-}
-
-static int parse_argv(int argc, char *argv[]) {
-
- enum {
- ARG_VERSION = 0x100,
- ARG_NO_PAGER,
- ARG_NO_LEGEND,
- ARG_SYSTEM,
- ARG_USER,
- ARG_ADDRESS,
- ARG_MATCH,
- ARG_SHOW_MACHINE,
- ARG_UNIQUE,
- ARG_ACQUIRED,
- ARG_ACTIVATABLE,
- ARG_SIZE,
- ARG_LIST,
- ARG_VERBOSE,
- ARG_EXPECT_REPLY,
- ARG_AUTO_START,
- ARG_ALLOW_INTERACTIVE_AUTHORIZATION,
- ARG_TIMEOUT,
- ARG_AUGMENT_CREDS,
- };
-
- static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
- { "system", no_argument, NULL, ARG_SYSTEM },
- { "user", no_argument, NULL, ARG_USER },
- { "address", required_argument, NULL, ARG_ADDRESS },
- { "show-machine", no_argument, NULL, ARG_SHOW_MACHINE },
- { "unique", no_argument, NULL, ARG_UNIQUE },
- { "acquired", no_argument, NULL, ARG_ACQUIRED },
- { "activatable", no_argument, NULL, ARG_ACTIVATABLE },
- { "match", required_argument, NULL, ARG_MATCH },
- { "host", required_argument, NULL, 'H' },
- { "machine", required_argument, NULL, 'M' },
- { "size", required_argument, NULL, ARG_SIZE },
- { "list", no_argument, NULL, ARG_LIST },
- { "quiet", no_argument, NULL, 'q' },
- { "verbose", no_argument, NULL, ARG_VERBOSE },
- { "expect-reply", required_argument, NULL, ARG_EXPECT_REPLY },
- { "auto-start", required_argument, NULL, ARG_AUTO_START },
- { "allow-interactive-authorization", required_argument, NULL, ARG_ALLOW_INTERACTIVE_AUTHORIZATION },
- { "timeout", required_argument, NULL, ARG_TIMEOUT },
- { "augment-creds",required_argument, NULL, ARG_AUGMENT_CREDS},
- {},
- };
-
- int c, r;
-
- assert(argc >= 0);
- assert(argv);
-
- while ((c = getopt_long(argc, argv, "hH:M:q", options, NULL)) >= 0)
-
- switch (c) {
-
- case 'h':
- return help();
-
- case ARG_VERSION:
- return version();
-
- case ARG_NO_PAGER:
- arg_no_pager = true;
- break;
-
- case ARG_NO_LEGEND:
- arg_legend = false;
- break;
-
- case ARG_USER:
- arg_user = true;
- break;
-
- case ARG_SYSTEM:
- arg_user = false;
- break;
-
- case ARG_ADDRESS:
- arg_address = optarg;
- break;
-
- case ARG_SHOW_MACHINE:
- arg_show_machine = true;
- break;
-
- case ARG_UNIQUE:
- arg_unique = true;
- break;
-
- case ARG_ACQUIRED:
- arg_acquired = true;
- break;
-
- case ARG_ACTIVATABLE:
- arg_activatable = true;
- break;
-
- case ARG_MATCH:
- if (strv_extend(&arg_matches, optarg) < 0)
- return log_oom();
- break;
-
- case ARG_SIZE: {
- uint64_t sz;
-
- r = parse_size(optarg, 1024, &sz);
- if (r < 0) {
- log_error("Failed to parse size: %s", optarg);
- return r;
- }
-
- if ((uint64_t) (size_t) sz != sz) {
- log_error("Size out of range.");
- return -E2BIG;
- }
-
- arg_snaplen = (size_t) sz;
- break;
- }
-
- case ARG_LIST:
- arg_list = true;
- break;
-
- case 'H':
- arg_transport = BUS_TRANSPORT_REMOTE;
- arg_host = optarg;
- break;
-
- case 'M':
- arg_transport = BUS_TRANSPORT_MACHINE;
- arg_host = optarg;
- break;
-
- case 'q':
- arg_quiet = true;
- break;
-
- case ARG_VERBOSE:
- arg_verbose = true;
- break;
-
- case ARG_EXPECT_REPLY:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --expect-reply= parameter.");
- return r;
- }
-
- arg_expect_reply = !!r;
- break;
-
-
- case ARG_AUTO_START:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --auto-start= parameter.");
- return r;
- }
-
- arg_auto_start = !!r;
- break;
-
-
- case ARG_ALLOW_INTERACTIVE_AUTHORIZATION:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --allow-interactive-authorization= parameter.");
- return r;
- }
-
- arg_allow_interactive_authorization = !!r;
- break;
-
- case ARG_TIMEOUT:
- r = parse_sec(optarg, &arg_timeout);
- if (r < 0) {
- log_error("Failed to parse --timeout= parameter.");
- return r;
- }
-
- break;
-
- case ARG_AUGMENT_CREDS:
- r = parse_boolean(optarg);
- if (r < 0) {
- log_error("Failed to parse --augment-creds= parameter.");
- return r;
- }
-
- arg_augment_creds = !!r;
- break;
-
- case '?':
- return -EINVAL;
-
- default:
- assert_not_reached("Unhandled option");
- }
-
- return 1;
-}
-
-static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
- assert(bus);
-
- if (optind >= argc ||
- streq(argv[optind], "list"))
- return list_bus_names(bus, argv + optind);
-
- if (streq(argv[optind], "monitor"))
- return monitor(bus, argv + optind, message_dump);
-
- if (streq(argv[optind], "capture"))
- return capture(bus, argv + optind);
-
- if (streq(argv[optind], "status"))
- return status(bus, argv + optind);
-
- if (streq(argv[optind], "tree"))
- return tree(bus, argv + optind);
-
- if (streq(argv[optind], "introspect"))
- return introspect(bus, argv + optind);
-
- if (streq(argv[optind], "call"))
- return call(bus, argv + optind);
-
- if (streq(argv[optind], "get-property"))
- return get_property(bus, argv + optind);
-
- if (streq(argv[optind], "set-property"))
- return set_property(bus, argv + optind);
-
- if (streq(argv[optind], "help"))
- return help();
-
- log_error("Unknown command '%s'", argv[optind]);
- return -EINVAL;
-}
-
-int main(int argc, char *argv[]) {
- sd_bus *bus = NULL;
- int r;
-
- log_parse_environment();
- log_open();
-
- r = parse_argv(argc, argv);
- if (r <= 0)
- goto finish;
-
- r = sd_bus_new(&bus);
- if (r < 0) {
- log_error_errno(r, "Failed to allocate bus: %m");
- goto finish;
- }
-
- if (STRPTR_IN_SET(argv[optind], "monitor", "capture")) {
-
- r = sd_bus_set_monitor(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to set monitor mode: %m");
- goto finish;
- }
-
- r = sd_bus_negotiate_creds(bus, true, _SD_BUS_CREDS_ALL);
- if (r < 0) {
- log_error_errno(r, "Failed to enable credentials: %m");
- goto finish;
- }
-
- r = sd_bus_negotiate_timestamp(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to enable timestamps: %m");
- goto finish;
- }
-
- r = sd_bus_negotiate_fds(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to enable fds: %m");
- goto finish;
- }
- }
-
- r = sd_bus_set_bus_client(bus, true);
- if (r < 0) {
- log_error_errno(r, "Failed to set bus client: %m");
- goto finish;
- }
-
- if (arg_address)
- r = sd_bus_set_address(bus, arg_address);
- else {
- switch (arg_transport) {
-
- case BUS_TRANSPORT_LOCAL:
- if (arg_user) {
- bus->is_user = true;
- r = bus_set_address_user(bus);
- } else {
- bus->is_system = true;
- r = bus_set_address_system(bus);
- }
- break;
-
- case BUS_TRANSPORT_REMOTE:
- r = bus_set_address_system_remote(bus, arg_host);
- break;
-
- case BUS_TRANSPORT_MACHINE:
- r = bus_set_address_system_machine(bus, arg_host);
- break;
-
- default:
- assert_not_reached("Hmm, unknown transport type.");
- }
- }
- if (r < 0) {
- log_error_errno(r, "Failed to set address: %m");
- goto finish;
- }
-
- r = sd_bus_start(bus);
- if (r < 0) {
- log_error_errno(r, "Failed to connect to bus: %m");
- goto finish;
- }
-
- r = busctl_main(bus, argc, argv);
-
-finish:
- sd_bus_flush_close_unref(bus);
- pager_close();
-
- strv_free(arg_matches);
-
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
}
+ b->is_local = true;
+
return 0;
}
freeaddrinfo(result);
+ b->is_local = false;
+
return 0;
}
b->exec_path = path;
b->exec_argv = argv;
+
+ b->is_local = false;
+
return 0;
fail:
b->kernel = path;
path = NULL;
+ b->is_local = true;
+
return 0;
}
b->sockaddr.un.sun_family = AF_UNIX;
strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
+ b->is_local = false;
return 0;
}
if (r < 0)
return r;
+ b->is_local = false;
+
return 0;
}
/* We don't know whether the bus is trusted or not, so better
* be safe, and authenticate everything */
b->trusted = false;
+ b->is_local = false;
b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
b->trusted = false;
b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
+ b->is_local = true;
r = sd_bus_start(b);
if (r < 0)
/* We don't do any per-method access control on the user
* bus. */
b->trusted = true;
+ b->is_local = true;
r = sd_bus_start(b);
if (r < 0)
bus->bus_client = true;
bus->trusted = false;
bus->is_system = true;
+ bus->is_local = false;
r = sd_bus_start(bus);
if (r < 0)
bus->bus_client = true;
bus->trusted = false;
bus->is_system = true;
+ bus->is_local = false;
r = sd_bus_start(bus);
if (r < 0)
void *p;
int r, q;
- zero(c);
-
c.automatic_integer_property = 4711;
assert_se(c.automatic_string_property = strdup("dudeldu"));
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-bus.h>
+#include "sd-bus.h"
#include "macro.h"
--- /dev/null
+test-bus-vtable.c
\ No newline at end of file
--- /dev/null
+#include <stdbool.h>
+#include <stddef.h>
+
+/* We use system assert.h here, because we don't want to keep macro.h and log.h C++ compatible */
+#undef NDEBUG
+#include <assert.h>
+#include <errno.h>
+
+#include "sd-bus-vtable.h"
+
+#define DEFAULT_BUS_PATH "unix:path=/run/dbus/system_bus_socket"
+
+struct context {
+ bool quit;
+ char *something;
+ char *automatic_string_property;
+ uint32_t automatic_integer_property;
+};
+
+static int handler(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static int value_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static int get_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static int set_handler(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error) {
+ return 1;
+}
+
+static const sd_bus_vtable vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("AlterSomething", "s", "s", handler, 0),
+ SD_BUS_METHOD("Exit", "", "", handler, 0),
+ SD_BUS_METHOD_WITH_OFFSET("AlterSomething2", "s", "s", handler, 200, 0),
+ SD_BUS_METHOD_WITH_OFFSET("Exit2", "", "", handler, 200, 0),
+ SD_BUS_PROPERTY("Value", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("Value2", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+ SD_BUS_PROPERTY("Value3", "s", value_handler, 10, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("Value4", "s", value_handler, 10, 0),
+ SD_BUS_PROPERTY("AnExplicitProperty", "s", NULL, offsetof(struct context, something),
+ SD_BUS_VTABLE_PROPERTY_EXPLICIT|SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+ SD_BUS_WRITABLE_PROPERTY("Something", "s", get_handler, set_handler, 0, 0),
+ SD_BUS_WRITABLE_PROPERTY("AutomaticStringProperty", "s", NULL, NULL,
+ offsetof(struct context, automatic_string_property), 0),
+ SD_BUS_WRITABLE_PROPERTY("AutomaticIntegerProperty", "u", NULL, NULL,
+ offsetof(struct context, automatic_integer_property), 0),
+ SD_BUS_METHOD("NoOperation", NULL, NULL, NULL, 0),
+ SD_BUS_SIGNAL("DummySignal", "b", 0),
+ SD_BUS_SIGNAL("DummySignal2", "so", 0),
+ SD_BUS_VTABLE_END
+};
+
+static void test_vtable(void) {
+ sd_bus *bus = NULL;
+ struct context c = {};
+ int r;
+
+ assert(sd_bus_new(&bus) >= 0);
+
+ assert(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.testVtable", vtable, &c) >= 0);
+ assert(sd_bus_add_object_vtable(bus, NULL, "/foo", "org.freedesktop.systemd.testVtable2", vtable, &c) >= 0);
+
+ assert(sd_bus_set_address(bus, DEFAULT_BUS_PATH) >= 0);
+ r = sd_bus_start(bus);
+ assert(r == 0 || /* success */
+ r == -ENOENT /* dbus is inactive */ );
+
+ sd_bus_unref(bus);
+}
+
+int main(int argc, char **argv) {
+ test_vtable();
+
+ return 0;
+}
if (!dir) {
if (errno == ENOENT)
return 0;
- else {
- log_error("sd-device-enumerator: could not open tags directory %s: %m", path);
- return -errno;
- }
+ else
+ return log_error_errno(errno, "sd-device-enumerator: could not open tags directory %s: %m", path);
}
/* TODO: filter away subsystems? */
int r = 0;
dir = opendir(path);
- if (!dir) {
- log_debug("sd-device-enumerate: could not open parent directory %s: %m", path);
- return -errno;
- }
+ if (!dir)
+ return log_debug_errno(errno, "sd-device-enumerate: could not open parent directory %s: %m", path);
FOREACH_DIRENT_ALL(dent, dir, return -errno) {
_cleanup_free_ char *child = NULL;
r = sd_device_get_property_value(device, "INTERFACE", &interface);
if (r >= 0) {
- r = device_add_property_internal(device, "INTERFACE", name);
+ /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
+ r = device_add_property_internal(device, "INTERFACE_OLD", interface);
if (r < 0)
return r;
- /* like DEVPATH_OLD, INTERFACE_OLD is not saved to the db, but only stays around for the current event */
- r = device_add_property_internal(device, "INTERFACE_OLD", interface);
+ r = device_add_property_internal(device, "INTERFACE", name);
if (r < 0)
return r;
} else if (r != -ENOENT)
/* this is not a valid device */
return -ENODEV;
- log_debug("sd-device: %s does not have an uevent file: %m", syspath);
- return -errno;
+ return log_debug_errno(errno, "sd-device: %s does not have an uevent file: %m", syspath);
}
} else {
/* everything else just needs to be a directory */
if (access(syspath, F_OK) >= 0)
return sd_device_new_from_syspath(ret, syspath);
+ syspath = strjoina("/sys/firmware/", subsystem, "/", sysname);
+ if (access(syspath, F_OK) >= 0)
+ return sd_device_new_from_syspath(ret, syspath);
+
return -ENODEV;
}
r = device_add_sysattr_value(device, sysattr, value);
if (r < 0)
return r;
+ value = NULL;
return -ENXIO;
}
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/wait.h>
+
#include "sd-event.h"
#include "fd-util.h"
assert_return(ret, -EINVAL);
- r = dev_urandom(&t, sizeof(t));
+ r = acquire_random_bytes(&t, sizeof t, true);
if (r < 0)
return r;
*/
_public_ int sd_pid_get_session(pid_t pid, char **session) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(session, -EINVAL);
- return cg_pid_get_session(pid, session);
+ r = cg_pid_get_session(pid, session);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_unit(pid_t pid, char **unit) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
- return cg_pid_get_unit(pid, unit);
+ r = cg_pid_get_unit(pid, unit);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_user_unit(pid_t pid, char **unit) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(unit, -EINVAL);
- return cg_pid_get_user_unit(pid, unit);
+ r = cg_pid_get_user_unit(pid, unit);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_machine_name(pid_t pid, char **name) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(name, -EINVAL);
- return cg_pid_get_machine_name(pid, name);
+ r = cg_pid_get_machine_name(pid, name);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_slice(pid_t pid, char **slice) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(slice, -EINVAL);
- return cg_pid_get_slice(pid, slice);
+ r = cg_pid_get_slice(pid, slice);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_user_slice(pid_t pid, char **slice) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(slice, -EINVAL);
- return cg_pid_get_user_slice(pid, slice);
+ r = cg_pid_get_user_slice(pid, slice);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
+ int r;
assert_return(pid >= 0, -EINVAL);
assert_return(uid, -EINVAL);
- return cg_pid_get_owner_uid(pid, uid);
+ r = cg_pid_get_owner_uid(pid, uid);
+ return IN_SET(r, -ENXIO, -ENOMEDIUM) ? -ENODATA : r;
}
_public_ int sd_pid_get_cgroup(pid_t pid, char **cgroup) {
return -ENOMEM;
}
- if (r < 0) {
+ else if (r < 0) {
free(s);
return r;
}
r = parse_env_file(p, NEWLINE,
"SESSIONS", &s,
- "ACTIVE_SESSIONS", &t,
+ "UIDS", &t,
NULL);
if (r == -ENOENT)
return -ENXIO;
r = parse_uid(k, b + i);
if (r < 0)
- continue;
+ return r;
i++;
}
}
_public_ int sd_get_seats(char ***seats) {
- return get_files_in_directory("/run/systemd/seats/", seats);
+ int r;
+
+ r = get_files_in_directory("/run/systemd/seats/", seats);
+ if (r == -ENOENT) {
+ if (seats)
+ *seats = NULL;
+ return 0;
+ }
+ return r;
}
_public_ int sd_get_sessions(char ***sessions) {
- return get_files_in_directory("/run/systemd/sessions/", sessions);
+ int r;
+
+ r = get_files_in_directory("/run/systemd/sessions/", sessions);
+ if (r == -ENOENT) {
+ if (sessions)
+ *sessions = NULL;
+ return 0;
+ }
+ return r;
}
_public_ int sd_get_uids(uid_t **users) {
_cleanup_free_ uid_t *l = NULL;
d = opendir("/run/systemd/users/");
- if (!d)
+ if (!d) {
+ if (errno == ENOENT) {
+ if (users)
+ *users = NULL;
+ return 0;
+ }
return -errno;
+ }
FOREACH_DIRENT_ALL(de, d, return -errno) {
int k;
}
_public_ int sd_get_machine_names(char ***machines) {
- char **l = NULL, **a, **b;
+ _cleanup_strv_free_ char **l = NULL;
+ char **a, **b;
int r;
- assert_return(machines, -EINVAL);
-
r = get_files_in_directory("/run/systemd/machines/", &l);
+ if (r == -ENOENT) {
+ if (machines)
+ *machines = NULL;
+ return 0;
+ }
if (r < 0)
return r;
r = 0;
/* Filter out the unit: symlinks */
- for (a = l, b = l; *a; a++) {
+ for (a = b = l; *a; a++) {
if (startswith(*a, "unit:") || !machine_name_is_valid(*a))
free(*a);
else {
*b = NULL;
}
- *machines = l;
+ if (machines) {
+ *machines = l;
+ l = NULL;
+ }
return r;
}
#include "alloc-util.h"
#include "fd-util.h"
#include "format-util.h"
+#include "log.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
+static char* format_uids(char **buf, uid_t* uids, int count) {
+ int pos = 0, k, inc;
+ size_t size = (DECIMAL_STR_MAX(uid_t) + 1) * count + 1;
+
+ assert_se(*buf = malloc(size));
+
+ for (k = 0; k < count; k++) {
+ sprintf(*buf + pos, "%s"UID_FMT"%n", k > 0 ? " " : "", uids[k], &inc);
+ pos += inc;
+ }
+
+ assert_se(pos < (ssize_t)size);
+ (*buf)[pos] = '\0';
+
+ return *buf;
+}
+
static void test_login(void) {
_cleanup_close_pair_ int pair[2] = { -1, -1 };
- _cleanup_free_ char *pp = NULL, *qq = NULL;
+ _cleanup_free_ char *pp = NULL, *qq = NULL,
+ *display_session = NULL, *cgroup = NULL,
+ *display = NULL, *remote_user = NULL, *remote_host = NULL,
+ *type = NULL, *class = NULL, *state = NULL, *state2 = NULL,
+ *seat = NULL, *session = NULL,
+ *unit = NULL, *user_unit = NULL, *slice = NULL;
int r, k;
uid_t u, u2;
- char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session, *cgroup;
- char *session;
- char *state;
- char *session2;
- char *t;
- char **seats, **sessions, **machines;
- uid_t *uids;
- unsigned n;
- struct pollfd pollfd;
- sd_login_monitor *m = NULL;
+ char *t, **seats, **sessions;
- assert_se(sd_pid_get_session(0, &session) == 0);
- printf("session = %s\n", session);
-
- assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
- printf("user = "UID_FMT"\n", u2);
+ r = sd_pid_get_unit(0, &unit);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_pid_get_unit(0, …) → \"%s\"", strna(unit));
- assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
- printf("cgroup = %s\n", cgroup);
- free(cgroup);
+ r = sd_pid_get_user_unit(0, &user_unit);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_pid_get_user_unit(0, …) → \"%s\"", strna(user_unit));
- display_session = NULL;
- r = sd_uid_get_display(u2, &display_session);
+ r = sd_pid_get_slice(0, &slice);
assert_se(r >= 0 || r == -ENODATA);
- printf("user's display session = %s\n", strna(display_session));
- free(display_session);
+ log_info("sd_pid_get_slice(0, …) → \"%s\"", strna(slice));
- assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
- sd_peer_get_session(pair[0], &pp);
- sd_peer_get_session(pair[1], &qq);
- assert_se(streq_ptr(pp, qq));
+ r = sd_pid_get_session(0, &session);
+ if (r < 0) {
+ log_warning_errno(r, "sd_pid_get_session(0, …): %m");
+ if (r == -ENODATA)
+ log_info("Seems we are not running in a session, skipping some tests.");
+ } else {
+ log_info("sd_pid_get_session(0, …) → \"%s\"", session);
- r = sd_uid_get_sessions(u2, false, &sessions);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(sessions));
- assert_se(t = strv_join(sessions, ", "));
- strv_free(sessions);
- printf("sessions = %s\n", t);
- free(t);
+ assert_se(sd_pid_get_owner_uid(0, &u2) == 0);
+ log_info("sd_pid_get_owner_uid(0, …) → "UID_FMT, u2);
- assert_se(r == sd_uid_get_sessions(u2, false, NULL));
+ assert_se(sd_pid_get_cgroup(0, &cgroup) == 0);
+ log_info("sd_pid_get_cgroup(0, …) → \"%s\"", cgroup);
- r = sd_uid_get_seats(u2, false, &seats);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(seats));
- assert_se(t = strv_join(seats, ", "));
- strv_free(seats);
- printf("seats = %s\n", t);
- free(t);
+ r = sd_uid_get_display(u2, &display_session);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_uid_get_display("UID_FMT", …) → \"%s\"",
+ u2, strnull(display_session));
- assert_se(r == sd_uid_get_seats(u2, false, NULL));
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0);
+ sd_peer_get_session(pair[0], &pp);
+ sd_peer_get_session(pair[1], &qq);
+ assert_se(streq_ptr(pp, qq));
- r = sd_session_is_active(session);
- assert_se(r >= 0);
- printf("active = %s\n", yes_no(r));
+ r = sd_uid_get_sessions(u2, false, &sessions);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+ log_info("sd_uid_get_sessions("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+ free(t);
- r = sd_session_is_remote(session);
- assert_se(r >= 0);
- printf("remote = %s\n", yes_no(r));
+ assert_se(r == sd_uid_get_sessions(u2, false, NULL));
- r = sd_session_get_state(session, &state);
- assert_se(r >= 0);
- printf("state = %s\n", state);
- free(state);
+ r = sd_uid_get_seats(u2, false, &seats);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(seats));
+ assert_se(t = strv_join(seats, " "));
+ strv_free(seats);
+ log_info("sd_uid_get_seats("UID_FMT", …) → [%i] \"%s\"", u2, r, t);
+ free(t);
- assert_se(sd_session_get_uid(session, &u) >= 0);
- printf("uid = "UID_FMT"\n", u);
- assert_se(u == u2);
+ assert_se(r == sd_uid_get_seats(u2, false, NULL));
+ }
- assert_se(sd_session_get_type(session, &type) >= 0);
- printf("type = %s\n", type);
- free(type);
+ if (session) {
+ r = sd_session_is_active(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
- assert_se(sd_session_get_class(session, &class) >= 0);
- printf("class = %s\n", class);
- free(class);
+ r = sd_session_is_remote(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
- display = NULL;
- r = sd_session_get_display(session, &display);
- assert_se(r >= 0 || r == -ENODATA);
- printf("display = %s\n", strna(display));
- free(display);
+ r = sd_session_get_state(session, &state);
+ assert_se(r >= 0);
+ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
- remote_user = NULL;
- r = sd_session_get_remote_user(session, &remote_user);
- assert_se(r >= 0 || r == -ENODATA);
- printf("remote_user = %s\n", strna(remote_user));
- free(remote_user);
+ assert_se(sd_session_get_uid(session, &u) >= 0);
+ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
+ assert_se(u == u2);
- remote_host = NULL;
- r = sd_session_get_remote_host(session, &remote_host);
- assert_se(r >= 0 || r == -ENODATA);
- printf("remote_host = %s\n", strna(remote_host));
- free(remote_host);
+ assert_se(sd_session_get_type(session, &type) >= 0);
+ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
- assert_se(sd_session_get_seat(session, &seat) >= 0);
- printf("seat = %s\n", seat);
+ assert_se(sd_session_get_class(session, &class) >= 0);
+ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
- r = sd_seat_can_multi_session(seat);
- assert_se(r >= 0);
- printf("can do multi session = %s\n", yes_no(r));
+ r = sd_session_get_display(session, &display);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
- r = sd_seat_can_tty(seat);
- assert_se(r >= 0);
- printf("can do tty = %s\n", yes_no(r));
+ r = sd_session_get_remote_user(session, &remote_user);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
+ session, strna(remote_user));
- r = sd_seat_can_graphical(seat);
- assert_se(r >= 0);
- printf("can do graphical = %s\n", yes_no(r));
+ r = sd_session_get_remote_host(session, &remote_host);
+ assert_se(r >= 0 || r == -ENODATA);
+ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
+ session, strna(remote_host));
- assert_se(sd_uid_get_state(u, &state) >= 0);
- printf("state = %s\n", state);
+ r = sd_session_get_seat(session, &seat);
+ if (r >= 0) {
+ assert_se(seat);
- assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, seat);
- k = sd_uid_is_on_seat(u, 1, seat);
- assert_se(k >= 0);
- assert_se(!!r == !!r);
+ r = sd_seat_can_multi_session(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
- assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
- printf("session2 = %s\n", session2);
- printf("uid2 = "UID_FMT"\n", u2);
+ r = sd_seat_can_tty(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
- r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
- assert_se(r >= 0);
- printf("n_sessions = %i\n", r);
- assert_se(r == (int) strv_length(sessions));
- assert_se(t = strv_join(sessions, ", "));
- strv_free(sessions);
- printf("sessions = %s\n", t);
- free(t);
- printf("uids =");
- for (k = 0; k < (int) n; k++)
- printf(" "UID_FMT, uids[k]);
- printf("\n");
- free(uids);
+ r = sd_seat_can_graphical(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
+ } else {
+ log_info_errno(r, "sd_session_get_display(\"%s\"): %m", session);
+ assert_se(r == -ENODATA);
+ }
- assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+ assert_se(sd_uid_get_state(u, &state2) >= 0);
+ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
+ }
+
+ if (seat) {
+ _cleanup_free_ char *session2 = NULL, *buf = NULL;
+ _cleanup_free_ uid_t *uids = NULL;
+ unsigned n;
+
+ assert_se(sd_uid_is_on_seat(u, 0, seat) > 0);
+
+ k = sd_uid_is_on_seat(u, 1, seat);
+ assert_se(k >= 0);
+ assert_se(!!k == !!r);
- free(session);
- free(state);
- free(session2);
- free(seat);
+ assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0);
+ log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT, seat, session2, u2);
+
+ r = sd_seat_get_sessions(seat, &sessions, &uids, &n);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(sessions));
+ assert_se(t = strv_join(sessions, " "));
+ strv_free(sessions);
+ log_info("sd_seat_get_sessions(\"%s\", …) → %i, \"%s\", [%i] {%s}",
+ seat, r, t, n, format_uids(&buf, uids, n));
+ free(t);
+
+ assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r);
+ }
r = sd_get_seats(&seats);
assert_se(r >= 0);
assert_se(r == (int) strv_length(seats));
assert_se(t = strv_join(seats, ", "));
strv_free(seats);
- printf("n_seats = %i\n", r);
- printf("seats = %s\n", t);
- free(t);
+ log_info("sd_get_seats(…) → [%i] \"%s\"", r, t);
+ t = mfree(t);
assert_se(sd_get_seats(NULL) == r);
r = sd_seat_get_active(NULL, &t, NULL);
- assert_se(r >= 0);
- printf("active session on current seat = %s\n", t);
+ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s", strnull(t));
free(t);
r = sd_get_sessions(&sessions);
assert_se(r == (int) strv_length(sessions));
assert_se(t = strv_join(sessions, ", "));
strv_free(sessions);
- printf("n_sessions = %i\n", r);
- printf("sessions = %s\n", t);
+ log_info("sd_get_sessions(…) → [%i] \"%s\"", r, t);
free(t);
assert_se(sd_get_sessions(NULL) == r);
- r = sd_get_uids(&uids);
- assert_se(r >= 0);
+ {
+ _cleanup_free_ uid_t *uids = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ r = sd_get_uids(&uids);
+ assert_se(r >= 0);
+ log_info("sd_get_uids(…) → [%i] {%s}", r, format_uids(&buf, uids, r));
- printf("uids =");
- for (k = 0; k < r; k++)
- printf(" "UID_FMT, uids[k]);
- printf("\n");
- free(uids);
+ assert_se(sd_get_uids(NULL) == r);
+ }
- printf("n_uids = %i\n", r);
- assert_se(sd_get_uids(NULL) == r);
+ {
+ _cleanup_strv_free_ char **machines = NULL;
+ _cleanup_free_ char *buf = NULL;
- r = sd_get_machine_names(&machines);
- assert_se(r >= 0);
- assert_se(r == (int) strv_length(machines));
- assert_se(t = strv_join(machines, ", "));
- strv_free(machines);
- printf("n_machines = %i\n", r);
- printf("machines = %s\n", t);
- free(t);
+ r = sd_get_machine_names(&machines);
+ assert_se(r >= 0);
+ assert_se(r == (int) strv_length(machines));
+ assert_se(buf = strv_join(machines, " "));
+ log_info("sd_get_machines(…) → [%i] \"%s\"", r, buf);
+
+ assert_se(sd_get_machine_names(NULL) == r);
+ }
+}
+
+static void test_monitor(void) {
+ sd_login_monitor *m = NULL;
+ unsigned n;
+ int r;
r = sd_login_monitor_new("session", &m);
assert_se(r >= 0);
for (n = 0; n < 5; n++) {
+ struct pollfd pollfd = {};
usec_t timeout, nw;
- zero(pollfd);
assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0);
assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0);
log_parse_environment();
log_open();
+ log_info("/* Information printed is from the live system */");
+
test_login();
+ if (streq_ptr(argv[1], "-m"))
+ test_monitor();
+
return 0;
}
assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
m->hdr->nlmsg_type == RTM_GETADDR ||
m->hdr->nlmsg_type == RTM_GETROUTE ||
- m->hdr->nlmsg_type == RTM_GETNEIGH,
+ m->hdr->nlmsg_type == RTM_GETNEIGH ||
+ m->hdr->nlmsg_type == RTM_GETADDRLABEL ,
-EINVAL);
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
#include <linux/veth.h>
#include <linux/if_bridge.h>
#include <linux/if_addr.h>
+#include <linux/if_addrlabel.h>
#include <linux/if.h>
#include <linux/ip.h>
#include <linux/if_link.h>
[IFLA_VXLAN_REMCSUM_RX] = { .type = NETLINK_TYPE_U8 },
[IFLA_VXLAN_GBP] = { .type = NETLINK_TYPE_FLAG },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NETLINK_TYPE_FLAG },
+ [IFLA_VXLAN_COLLECT_METADATA] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_VXLAN_LABEL] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_VXLAN_GPE] = { .type = NETLINK_TYPE_FLAG },
};
static const NLType rtnl_bond_arp_target_types[] = {
[IFLA_VRF_TABLE] = { .type = NETLINK_TYPE_U32 },
};
+static const NLType rtnl_link_info_data_geneve_types[] = {
+ [IFLA_GENEVE_ID] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_GENEVE_TTL] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_TOS] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_PORT] = { .type = NETLINK_TYPE_U16 },
+ [IFLA_GENEVE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR },
+ [IFLA_GENEVE_REMOTE6] = { .type = NETLINK_TYPE_IN_ADDR },
+ [IFLA_GENEVE_UDP_CSUM] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NETLINK_TYPE_U8 },
+ [IFLA_GENEVE_LABEL] = { .type = NETLINK_TYPE_U32 },
+};
+
/* these strings must match the .kind entries in the kernel */
static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_BOND] = "bond",
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
[NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
[NL_UNION_LINK_INFO_DATA_VCAN] = "vcan",
+ [NL_UNION_LINK_INFO_DATA_GENEVE] = "geneve",
};
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
.types = rtnl_link_info_data_ip6tnl_types },
[NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
.types = rtnl_link_info_data_vrf_types },
+ [NL_UNION_LINK_INFO_DATA_GENEVE] = { .count = ELEMENTSOF(rtnl_link_info_data_geneve_types),
+ .types = rtnl_link_info_data_geneve_types },
};
static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
.types = rtnl_neigh_types,
};
+static const NLType rtnl_addrlabel_types[] = {
+ [IFAL_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR, .size = sizeof(struct in6_addr) },
+ [IFAL_LABEL] = { .type = NETLINK_TYPE_U32 },
+};
+
+static const NLTypeSystem rtnl_addrlabel_type_system = {
+ .count = ELEMENTSOF(rtnl_addrlabel_types),
+ .types = rtnl_addrlabel_types,
+};
+
static const NLType rtnl_types[] = {
- [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
- [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
- [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
- [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
- [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
- [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
- [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
- [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
+ [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
+ [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
+ [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+ [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+ [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
+ [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) },
+ [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) },
+ [RTM_NEWADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
+ [RTM_DELADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
+ [RTM_GETADDRLABEL] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_addrlabel_type_system, .size = sizeof(struct ifaddrlblmsg) },
};
const NLTypeSystem type_system_root = {
NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL,
NL_UNION_LINK_INFO_DATA_VRF,
NL_UNION_LINK_INFO_DATA_VCAN,
+ NL_UNION_LINK_INFO_DATA_GENEVE,
_NL_UNION_LINK_INFO_DATA_MAX,
_NL_UNION_LINK_INFO_DATA_INVALID = -1
} NLUnionLinkInfoData;
return 0;
}
-bool rtnl_message_type_is_neigh(uint16_t type) {
- switch (type) {
- case RTM_NEWNEIGH:
- case RTM_GETNEIGH:
- case RTM_DELNEIGH:
- return true;
- default:
- return false;
- }
-}
-
-bool rtnl_message_type_is_route(uint16_t type) {
- switch (type) {
- case RTM_NEWROUTE:
- case RTM_GETROUTE:
- case RTM_DELROUTE:
- return true;
- default:
- return false;
- }
-}
-
-bool rtnl_message_type_is_link(uint16_t type) {
- switch (type) {
- case RTM_NEWLINK:
- case RTM_SETLINK:
- case RTM_GETLINK:
- case RTM_DELLINK:
- return true;
- default:
- return false;
- }
-}
-
-bool rtnl_message_type_is_addr(uint16_t type) {
- switch (type) {
- case RTM_NEWADDR:
- case RTM_GETADDR:
- case RTM_DELADDR:
- return true;
- default:
- return false;
- }
-}
-
int rtnl_log_parse_error(int r) {
return log_error_errno(r, "Failed to parse netlink message: %m");
}
uint32_t rtnl_message_get_serial(sd_netlink_message *m);
void rtnl_message_seal(sd_netlink_message *m);
-bool rtnl_message_type_is_link(uint16_t type);
-bool rtnl_message_type_is_addr(uint16_t type);
-bool rtnl_message_type_is_route(uint16_t type);
-bool rtnl_message_type_is_neigh(uint16_t type);
+static inline bool rtnl_message_type_is_neigh(uint16_t type) {
+ return IN_SET(type, RTM_NEWNEIGH, RTM_GETNEIGH, RTM_DELNEIGH);
+}
+
+static inline bool rtnl_message_type_is_route(uint16_t type) {
+ return IN_SET(type, RTM_NEWROUTE, RTM_GETROUTE, RTM_DELROUTE);
+}
+
+static inline bool rtnl_message_type_is_link(uint16_t type) {
+ return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
+}
+
+static inline bool rtnl_message_type_is_addr(uint16_t type) {
+ return IN_SET(type, RTM_NEWADDR, RTM_GETADDR, RTM_DELADDR);
+}
+
+static inline bool rtnl_message_type_is_addrlabel(uint16_t type) {
+ return IN_SET(type, RTM_NEWADDRLABEL, RTM_DELADDRLABEL, RTM_GETADDRLABEL);
+}
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, unsigned mtu);
***/
#include <netinet/in.h>
+#include <linux/if_addrlabel.h>
#include <stdbool.h>
#include <unistd.h>
return -EOPNOTSUPP;
}
+
+int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family) {
+ struct ifaddrlblmsg *addrlabel;
+ int r;
+
+ assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ r = message_new(rtnl, ret, nlmsg_type);
+ if (r < 0)
+ return r;
+
+ if (nlmsg_type == RTM_NEWADDRLABEL)
+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
+
+ addrlabel = NLMSG_DATA((*ret)->hdr);
+
+ addrlabel->ifal_family = ifal_family;
+ addrlabel->ifal_index = ifindex;
+
+ return 0;
+}
+
+int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
+ struct ifaddrlblmsg *addrlabel;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
+
+ addrlabel = NLMSG_DATA(m->hdr);
+
+ if (prefixlen > 128)
+ return -ERANGE;
+
+ addrlabel->ifal_prefixlen = prefixlen;
+
+ return 0;
+}
+
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
+ struct ifaddrlblmsg *addrlabel;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
+
+ addrlabel = NLMSG_DATA(m->hdr);
+
+ *prefixlen = addrlabel->ifal_prefixlen;
+
+ return 0;
+}
udev_device = udev_device_new_from_nulstr(udev_monitor->udev, &buf.raw[bufpos], buflen - bufpos);
if (!udev_device) {
- log_debug("could not create device: %m");
+ log_debug_errno(errno, "could not create device: %m");
return NULL;
}
}
udev->refcount = 1;
- f = fopen("/etc/udev/udev.conf", "re");
- if (f != NULL) {
- char line[UTIL_LINE_SIZE];
- unsigned line_nr = 0;
-
- while (fgets(line, sizeof(line), f)) {
- size_t len;
- char *key;
- char *val;
-
- line_nr++;
-
- /* find key */
- key = line;
- while (isspace(key[0]))
- key++;
-
- /* comment or empty line */
- if (key[0] == '#' || key[0] == '\0')
- continue;
-
- /* split key/value */
- val = strchr(key, '=');
- if (val == NULL) {
- log_debug("/etc/udev/udev.conf:%u: missing assignment, skipping line.", line_nr);
- continue;
- }
- val[0] = '\0';
- val++;
-
- /* find value */
- while (isspace(val[0]))
- val++;
-
- /* terminate key */
- len = strlen(key);
- if (len == 0)
- continue;
- while (isspace(key[len-1]))
- len--;
- key[len] = '\0';
-
- /* terminate value */
- len = strlen(val);
- if (len == 0)
- continue;
- while (isspace(val[len-1]))
- len--;
- val[len] = '\0';
-
- if (len == 0)
- continue;
-
- /* unquote */
- if (val[0] == '"' || val[0] == '\'') {
- if (len == 1 || val[len-1] != val[0]) {
- log_debug("/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.", line_nr);
- continue;
- }
- val[len-1] = '\0';
- val++;
- }
-
- if (streq(key, "udev_log")) {
- int prio;
-
- prio = util_log_priority(val);
- if (prio < 0)
- log_debug("/etc/udev/udev.conf:%u: invalid log level '%s', ignoring.", line_nr, val);
- else
- log_set_max_level(prio);
- continue;
- }
- }
- }
-
return udev;
}
Name: libudev
Description: Library to access udev device information
-Version: @VERSION@
+Version: @PACKAGE_VERSION@
Libs: -L${libdir} -ludev
Cflags: -I${includedir}
--- /dev/null
+libudev_sources = files('''
+ libudev-private.h
+ libudev-device-internal.h
+ libudev.c
+ libudev-list.c
+ libudev-util.c
+ libudev-device.c
+ libudev-device-private.c
+ libudev-enumerate.c
+ libudev-monitor.c
+ libudev-queue.c
+ libudev-hwdb.c
+'''.split())
+
+############################################################
+
+libudev_sym = 'libudev.sym'
+libudev_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libudev_sym)
+libudev = shared_library(
+ 'udev',
+ libudev_sources,
+ version : '1.6.6',
+ include_directories : includes,
+ link_args : ['-shared',
+ '-Wl,--version-script=' + libudev_sym_path],
+ link_with : [libbasic,
+ libsystemd_internal],
+ dependencies : [threads],
+ link_depends : libudev_sym,
+ install : true,
+ install_dir : rootlibdir)
+
+install_headers('libudev.h')
+libudev_h_path = '@0@/libudev.h'.format(meson.current_source_dir())
+
+libudev_pc = configure_file(
+ input : 'libudev.pc.in',
+ output : 'libudev.pc',
+ configuration : substs)
+install_data(libudev_pc,
+ install_dir : pkgconfiglibdir)
fchmod(fileno(f), 0644);
- fputs("# Read and parsed by systemd-localed. It's probably wise not to edit this file\n"
- "# manually too freely.\n"
+ fputs("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n"
+ "# probably wise not to edit this file manually. Use localectl(1) to\n"
+ "# instruct systemd-localed to update it.\n"
"Section \"InputClass\"\n"
" Identifier \"system-keyboard\"\n"
" MatchIsKeyboard \"on\"\n", f);
const char *fmt;
fmt = strjoina("libxkbcommon: ", format);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
log_internalv(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, fmt, args);
+#pragma GCC diagnostic pop
}
#define LOAD_SYMBOL(symbol, dl, name) \
--- /dev/null
+systemd_localed_sources = files('''
+ localed.c
+ keymap-util.c
+ keymap-util.h
+'''.split())
+
+localectl_sources = files('localectl.c')
+
+if conf.get('ENABLE_LOCALED', false)
+ install_data('org.freedesktop.locale1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.locale1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.locale1.policy',
+ input : 'org.freedesktop.locale1.policy.in',
+ output : 'org.freedesktop.locale1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
+
+# If you know a way that allows the same variables to be used
+# in sources list and concatenated to a string for test_env,
+# let me know.
+kbd_model_map = join_paths(meson.current_source_dir(), 'kbd-model-map')
+language_fallback_map = join_paths(meson.current_source_dir(), 'language-fallback-map')
+
+if conf.get('ENABLE_LOCALED', false)
+ install_data('kbd-model-map',
+ 'language-fallback-map',
+ install_dir : pkgdatadir)
+endif
+
+tests += [
+ [['src/locale/test-keymap-util.c',
+ 'src/locale/keymap-util.c',
+ 'src/locale/keymap-util.h'],
+ [libshared],
+ [libdl]],
+]
ACTION=="remove", GOTO="power_switch_end"
-SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="twl4030_pwrbutton", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="tps65217_pwr_but", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="* WMI hotkeys", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", \
- SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", ATTRS{keys}=="*,116|116,*|116|*,116,*", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_SWITCH}=="1", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_KEY}=="1", TAG+="power-switch"
LABEL="power_switch_end"
bool properties, new_line = false;
sd_bus *bus = userdata;
int r, i;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_free_ char *path = NULL;
assert(bus);
assert(argv);
pager_open(arg_no_pager, false);
if (argc <= 1) {
- /* If not argument is specified inspect the manager
- * itself */
+ const char *session, *p = "/org/freedesktop/login1/session/self";
+
if (properties)
+ /* If no argument is specified inspect the manager itself */
return show_properties(bus, "/org/freedesktop/login1", &new_line);
/* And in the pretty case, show data of the calling session */
- return print_session_status_info(bus, "/org/freedesktop/login1/session/self", &new_line);
+ session = getenv("XDG_SESSION_ID");
+ if (session) {
+ r = get_session_path(bus, session, &error, &path);
+ if (r < 0) {
+ log_error("Failed to get session path: %s", bus_error_message(&error, r));
+ return r;
+ }
+ p = path;
+ }
+
+ return print_session_status_info(bus, p, &new_line);
}
for (i = 1; i < argc; i++) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_free_ char *path = NULL;
-
- r = get_session_path(bus, argv[1], &error, &path);
+ r = get_session_path(bus, argv[i], &error, &path);
if (r < 0) {
log_error("Failed to get session path: %s", bus_error_message(&error, r));
return r;
polkit_agent_open_if_enabled();
if (argc < 2) {
- /* No argument? Let's convert this into the empty
- * session name, which the calls will then resolve to
- * the caller's session. */
+ /* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty
+ * session name, in which case logind will try to guess our session. */
short_argv[0] = argv[0];
- short_argv[1] = (char*) "";
+ short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
short_argv[2] = NULL;
argv = short_argv;
b = streq(argv[0], "enable-linger");
if (argc < 2) {
+ /* No argument? Let's either use $XDG_SESSION_ID (if specified), or an empty
+ * session name, in which case logind will try to guess our session. */
+
short_argv[0] = argv[0];
- short_argv[1] = (char*) "";
+ short_argv[1] = getenv("XDG_SESSION_ID") ?: (char*) "";
short_argv[2] = NULL;
argv = short_argv;
argc = 2;
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
" -n --lines=INTEGER Number of journal entries to show\n"
- " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, json-pretty, json-sse, cat)\n\n"
+ " -o --output=STRING Change journal output mode (short, short-precise,\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix, verbose, export,\n"
+ " json, json-pretty, json-sse, cat)\n"
"Session Commands:\n"
" list-sessions List sessions\n"
" session-status [ID...] Show session status\n"
#include "string-util.h"
#include "util.h"
+#define CONST_MAX4(a, b, c, d) CONST_MAX(CONST_MAX(a, b), CONST_MAX(c, d))
+
+#define ULONG_BITS (sizeof(unsigned long)*8)
+
+static bool bitset_get(const unsigned long *bits, unsigned i) {
+ return (bits[i / ULONG_BITS] >> (i % ULONG_BITS)) & 1UL;
+}
+
+static void bitset_put(unsigned long *bits, unsigned i) {
+ bits[i / ULONG_BITS] |= (unsigned long) 1 << (i % ULONG_BITS);
+}
+
Button* button_new(Manager *m, const char *name) {
Button *b;
return 0;
}
+static int button_suitable(Button *b) {
+ unsigned long types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1];
+
+ assert(b);
+ assert(b->fd);
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_SYN, sizeof(types)), types) < 0)
+ return -errno;
+
+ if (bitset_get(types, EV_KEY)) {
+ unsigned long keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1];
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0)
+ return -errno;
+
+ if (bitset_get(keys, KEY_POWER) ||
+ bitset_get(keys, KEY_POWER2) ||
+ bitset_get(keys, KEY_SLEEP) ||
+ bitset_get(keys, KEY_SUSPEND))
+ return true;
+ }
+
+ if (bitset_get(types, EV_SW)) {
+ unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1];
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_SW, sizeof(switches)), switches) < 0)
+ return -errno;
+
+ if (bitset_get(switches, SW_LID) ||
+ bitset_get(switches, SW_DOCK))
+ return true;
+ }
+
+ return false;
+}
+
+static int button_set_mask(Button *b) {
+ unsigned long
+ types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {},
+ keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1] = {},
+ switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
+ struct input_mask mask;
+
+ assert(b);
+ assert(b->fd >= 0);
+
+ bitset_put(types, EV_KEY);
+ bitset_put(types, EV_SW);
+
+ mask = (struct input_mask) {
+ .type = EV_SYN,
+ .codes_size = sizeof(types),
+ .codes_ptr = PTR_TO_UINT64(types),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ /* Log only at debug level if the kernel doesn't do EVIOCSMASK yet */
+ return log_full_errno(IN_SET(errno, ENOTTY, EOPNOTSUPP, EINVAL) ? LOG_DEBUG : LOG_WARNING,
+ errno, "Failed to set EV_SYN event mask on /dev/input/%s: %m", b->name);
+
+ bitset_put(keys, KEY_POWER);
+ bitset_put(keys, KEY_POWER2);
+ bitset_put(keys, KEY_SLEEP);
+ bitset_put(keys, KEY_SUSPEND);
+
+ mask = (struct input_mask) {
+ .type = EV_KEY,
+ .codes_size = sizeof(keys),
+ .codes_ptr = PTR_TO_UINT64(keys),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ return log_warning_errno(errno, "Failed to set EV_KEY event mask on /dev/input/%s: %m", b->name);
+
+ bitset_put(switches, SW_LID);
+ bitset_put(switches, SW_DOCK);
+
+ mask = (struct input_mask) {
+ .type = EV_SW,
+ .codes_size = sizeof(switches),
+ .codes_ptr = PTR_TO_UINT64(switches),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ return log_warning_errno(errno, "Failed to set EV_SW event mask on /dev/input/%s: %m", b->name);
+
+ return 0;
+}
+
int button_open(Button *b) {
char *p, name[256];
int r;
b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (b->fd < 0)
- return log_warning_errno(errno, "Failed to open %s: %m", b->name);
+ return log_warning_errno(errno, "Failed to open %s: %m", p);
+
+ r = button_suitable(b);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to determine whether input device is relevant to us: %m");
+ if (r == 0) {
+ log_debug("Device %s does not expose keys or switches relevant to us, ignoring.", p);
+ return -EADDRNOTAVAIL;
+ }
if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
r = log_error_errno(errno, "Failed to get input name: %m");
goto fail;
}
+ (void) button_set_mask(b);
+
r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
if (r < 0) {
log_error_errno(r, "Failed to add button event: %m");
}
int button_check_switches(Button *b) {
- uint8_t switches[SW_MAX/8+1] = {};
+ unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
assert(b);
if (b->fd < 0)
if (ioctl(b->fd, EVIOCGSW(sizeof(switches)), switches) < 0)
return -errno;
- b->lid_closed = (switches[SW_LID/8] >> (SW_LID % 8)) & 1;
- b->docked = (switches[SW_DOCK/8] >> (SW_DOCK % 8)) & 1;
+ b->lid_closed = bitset_get(switches, SW_LID);
+ b->docked = bitset_get(switches, SW_DOCK);
if (b->lid_closed)
button_install_check_event_source(b);
sn = "seat0";
button_set_seat(b, sn);
- button_open(b);
+
+ r = button_open(b);
+ if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
+ * opening the device?) let's close the button again. */
+ button_free(b);
}
return 0;
return r;
r = sd_bus_creds_get_session(creds, &name);
+ if (r == -ENXIO)
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SESSION_FOR_PID,
+ "Caller does not belong to any known session");
if (r < 0)
return r;
}
assert(m);
HASHMAP_FOREACH(i, m->inhibitors, j)
- if (i->mode == mm)
+ if (i->mode == mm && i->started)
what |= i->what;
return what;
assert(w > 0 && w < _INHIBIT_WHAT_MAX);
HASHMAP_FOREACH(i, m->inhibitors, j) {
+ if (!i->started)
+ continue;
+
if (!(i->what & w))
continue;
if (uid != 0 && (force || uid != s->user->uid))
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Only owner of session may take control");
- r = session_set_controller(s, sd_bus_message_get_sender(message), force);
+ r = session_set_controller(s, sd_bus_message_get_sender(message), force, true);
if (r < 0)
return r;
* equivalent). */
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_IS_TAKEN, "Device already taken");
- r = session_device_new(s, dev, &sd);
+ r = session_device_new(s, dev, true, &sd);
if (r < 0)
return r;
+ r = session_device_save(sd);
+ if (r < 0)
+ goto error;
+
r = sd_bus_reply_method_return(message, "hb", sd->fd, !sd->active);
if (r < 0)
- session_device_free(sd);
+ goto error;
+
+ session_save(s);
+ return 0;
+error:
+ session_device_free(sd);
return r;
}
return sd_bus_error_setf(error, BUS_ERROR_DEVICE_NOT_TAKEN, "Device not taken");
session_device_free(sd);
+ session_save(s);
+
return sd_bus_reply_method_return(message, NULL);
}
#include "fd-util.h"
#include "logind-session-device.h"
#include "missing.h"
+#include "parse-util.h"
+#include "sd-daemon.h"
#include "util.h"
enum SessionDeviceNotifications {
r = session_device_open(sd, true);
if (r < 0)
return r;
- close_nointr(sd->fd);
+ /* For evdev devices, the file descriptor might be left
+ * uninitialized. This might happen while resuming into a
+ * session and logind has been restarted right before. */
+ safe_close(sd->fd);
sd->fd = r;
break;
case DEVICE_TYPE_UNKNOWN:
return r;
}
-int session_device_new(Session *s, dev_t dev, SessionDevice **out) {
+int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **out) {
SessionDevice *sd;
int r;
goto error;
}
- /* Open the device for the first time. We need a valid fd to pass back
- * to the caller. If the session is not active, this _might_ immediately
- * revoke access and thus invalidate the fd. But this is still needed
- * to pass a valid fd back. */
- sd->active = session_is_active(s);
- r = session_device_open(sd, sd->active);
- if (r < 0) {
- /* EINVAL _may_ mean a master is active; retry inactive */
- if (sd->active && r == -EINVAL) {
- sd->active = false;
- r = session_device_open(sd, false);
+ if (open_device) {
+ /* Open the device for the first time. We need a valid fd to pass back
+ * to the caller. If the session is not active, this _might_ immediately
+ * revoke access and thus invalidate the fd. But this is still needed
+ * to pass a valid fd back. */
+ sd->active = session_is_active(s);
+ r = session_device_open(sd, sd->active);
+ if (r < 0) {
+ /* EINVAL _may_ mean a master is active; retry inactive */
+ if (sd->active && r == -EINVAL) {
+ sd->active = false;
+ r = session_device_open(sd, false);
+ }
+ if (r < 0)
+ goto error;
}
- if (r < 0)
- goto error;
+ sd->fd = r;
}
- sd->fd = r;
LIST_PREPEND(sd_by_device, sd->device->session_devices, sd);
void session_device_resume_all(Session *s) {
SessionDevice *sd;
Iterator i;
- int r;
assert(s);
HASHMAP_FOREACH(sd, s->devices, i) {
if (!sd->active) {
- r = session_device_start(sd);
- if (!r)
- session_device_notify(sd, SESSION_DEVICE_RESUME);
+ if (session_device_start(sd) < 0)
+ continue;
+ if (session_device_save(sd) < 0)
+ continue;
+ session_device_notify(sd, SESSION_DEVICE_RESUME);
}
}
}
return num_pending;
}
+
+int session_device_save(SessionDevice *sd) {
+ _cleanup_free_ char *state = NULL;
+ int r;
+
+ assert(sd);
+
+ /* Store device fd in PID1. It will send it back to us on
+ * restart so revocation will continue to work. To make things
+ * simple, send fds for all type of devices even if they don't
+ * support the revocation mechanism so we don't have to handle
+ * them differently later.
+ *
+ * Note: for device supporting revocation, PID1 will drop a
+ * stored fd automatically if the corresponding device is
+ * revoked. */
+ r = asprintf(&state, "FDSTORE=1\n"
+ "FDNAME=session-%s", sd->session->id);
+ if (r < 0)
+ return -ENOMEM;
+
+ return sd_pid_notify_with_fds(0, false, state, &sd->fd, 1);
+}
+
+void session_device_attach_fd(SessionDevice *sd, int fd, bool active) {
+ assert(fd > 0);
+ assert(sd);
+ assert(sd->fd < 0);
+ assert(!sd->active);
+
+ sd->fd = fd;
+ sd->active = active;
+}
LIST_FIELDS(struct SessionDevice, sd_by_device);
};
-int session_device_new(Session *s, dev_t dev, SessionDevice **out);
+int session_device_new(Session *s, dev_t dev, bool open_device, SessionDevice **out);
void session_device_free(SessionDevice *sd);
void session_device_complete_pause(SessionDevice *sd);
void session_device_resume_all(Session *s);
void session_device_pause_all(Session *s);
unsigned int session_device_try_pause_all(Session *s);
+
+int session_device_save(SessionDevice *sd);
+void session_device_attach_fd(SessionDevice *sd, int fd, bool active);
LIST_PREPEND(sessions_by_user, u->sessions, s);
}
+static void session_save_devices(Session *s, FILE *f) {
+ SessionDevice *sd;
+ Iterator i;
+
+ if (!hashmap_isempty(s->devices)) {
+ fprintf(f, "DEVICES=");
+ HASHMAP_FOREACH(sd, s->devices, i)
+ fprintf(f, "%u:%u ", major(sd->dev), minor(sd->dev));
+ fprintf(f, "\n");
+ }
+}
+
int session_save(Session *s) {
_cleanup_free_ char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
s->timestamp.realtime,
s->timestamp.monotonic);
- if (s->controller)
+ if (s->controller) {
fprintf(f, "CONTROLLER=%s\n", s->controller);
+ session_save_devices(s, f);
+ }
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
}
+static int session_load_devices(Session *s, const char *devices) {
+ const char *p;
+ int r = 0;
+
+ assert(s);
+
+ for (p = devices;;) {
+ _cleanup_free_ char *word = NULL;
+ SessionDevice *sd;
+ dev_t dev;
+ int k;
+
+ k = extract_first_word(&p, &word, NULL, 0);
+ if (k == 0)
+ break;
+ if (k < 0) {
+ r = k;
+ break;
+ }
+
+ k = parse_dev(word, &dev);
+ if (k < 0) {
+ r = k;
+ continue;
+ }
+
+ /* The file descriptors for loaded devices will be reattached later. */
+ k = session_device_new(s, dev, false, &sd);
+ if (k < 0)
+ r = k;
+ }
+
+ if (r < 0)
+ log_error_errno(r, "Loading session devices for session %s failed: %m", s->id);
+
+ return r;
+}
int session_load(Session *s) {
_cleanup_free_ char *remote = NULL,
*uid = NULL,
*realtime = NULL,
*monotonic = NULL,
- *controller = NULL;
+ *controller = NULL,
+ *active = NULL,
+ *devices = NULL;
int k, r;
"REALTIME", &realtime,
"MONOTONIC", &monotonic,
"CONTROLLER", &controller,
+ "ACTIVE", &active,
+ "DEVICES", &devices,
NULL);
if (r < 0)
if (monotonic)
timestamp_deserialize(monotonic, &s->timestamp.monotonic);
+ if (active) {
+ k = parse_boolean(active);
+ if (k >= 0)
+ s->was_active = k;
+ }
+
if (controller) {
- if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0)
- session_set_controller(s, controller, false);
- else
+ if (bus_name_has_owner(s->manager->bus, controller, NULL) > 0) {
+ session_set_controller(s, controller, false, false);
+ session_load_devices(s, devices);
+ } else
session_restore_vt(s);
}
return 0;
}
-int session_set_controller(Session *s, const char *sender, bool force) {
+int session_set_controller(Session *s, const char *sender, bool force, bool prepare) {
_cleanup_free_ char *name = NULL;
int r;
* Note that we reset the VT on ReleaseControl() and if the controller
* exits.
* If logind crashes/restarts, we restore the controller during restart
- * or reset the VT in case it crashed/exited, too. */
- r = session_prepare_vt(s);
- if (r < 0) {
- s->track = sd_bus_track_unref(s->track);
- return r;
+ * (without preparing the VT since the controller has probably overridden
+ * VT state by now) or reset the VT in case it crashed/exited, too. */
+ if (prepare) {
+ r = session_prepare_vt(s);
+ if (r < 0) {
+ s->track = sd_bus_track_unref(s->track);
+ return r;
+ }
}
session_release_controller(s, true);
bool started:1;
bool stopping:1;
+ bool was_active:1;
+
sd_bus_message *create_message;
sd_event_source *timer_event_source;
void session_leave_vt(Session *s);
bool session_is_controller(Session *s, const char *sender);
-int session_set_controller(Session *s, const char *sender, bool force);
+int session_set_controller(Session *s, const char *sender, bool force, bool prepare);
void session_drop_controller(Session *s);
int bus_session_method_activate(sd_bus_message *message, void *userdata, sd_bus_error *error);
return r;
}
+static int manager_attach_fds(Manager *m) {
+ _cleanup_strv_free_ char **fdnames = NULL;
+ int n, i, fd;
+
+ /* Upon restart, PID1 will send us back all fds of session devices
+ * that we previously opened. Each file descriptor is associated
+ * with a given session. The session ids are passed through FDNAMES. */
+
+ n = sd_listen_fds_with_names(true, &fdnames);
+ if (n <= 0)
+ return n;
+
+ for (i = 0; i < n; i++) {
+ struct stat st;
+ SessionDevice *sd;
+ Session *s;
+ char *id;
+
+ fd = SD_LISTEN_FDS_START + i;
+
+ id = startswith(fdnames[i], "session-");
+ if (!id)
+ continue;
+
+ s = hashmap_get(m->sessions, id);
+ if (!s) {
+ /* If the session doesn't exist anymore, the associated session
+ * device attached to this fd doesn't either. Let's simply close
+ * this fd. */
+ log_debug("Failed to attach fd for unknown session: %s", id);
+ close_nointr(fd);
+ continue;
+ }
+
+ if (fstat(fd, &st) < 0) {
+ /* The device is allowed to go away at a random point, in which
+ * case fstat failing is expected. */
+ log_debug_errno(errno, "Failed to stat device fd for session %s: %m", id);
+ close_nointr(fd);
+ continue;
+ }
+
+ sd = hashmap_get(s->devices, &st.st_rdev);
+ if (!sd) {
+ /* Weird we got an fd for a session device which wasn't
+ * recorded in the session state file... */
+ log_warning("Got fd for missing session device [%u:%u] in session %s",
+ major(st.st_rdev), minor(st.st_rdev), s->id);
+ close_nointr(fd);
+ continue;
+ }
+
+ log_debug("Attaching fd to session device [%u:%u] for session %s",
+ major(st.st_rdev), minor(st.st_rdev), s->id);
+
+ session_device_attach_fd(sd, fd, s->was_active);
+ }
+
+ return 0;
+}
+
static int manager_enumerate_sessions(Manager *m) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
- int r = 0;
+ int r = 0, k;
assert(m);
FOREACH_DIRENT(de, d, return -errno) {
struct Session *s;
- int k;
if (!dirent_is_file(de))
continue;
k = manager_add_session(m, de->d_name, &s);
if (k < 0) {
log_error_errno(k, "Failed to add session by file name %s: %m", de->d_name);
-
r = k;
continue;
}
r = k;
}
+ /* We might be restarted and PID1 could have sent us back the
+ * session device fds we previously saved. */
+ k = manager_attach_fds(m);
+ if (k < 0)
+ log_warning_errno(k, "Failed to reattach session device fds: %m");
+
return r;
}
assert(m);
return config_parse_many_nulstr(PKGSYSCONFDIR "/logind.conf",
- CONF_PATHS_NULSTR("systemd/logind.conf.d"),
- "Login\0",
- config_item_perf_lookup, logind_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/logind.conf.d"),
+ "Login\0",
+ config_item_perf_lookup, logind_gperf_lookup,
+ false, m);
}
static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
--- /dev/null
+systemd_logind_sources = files('''
+ logind.c
+ logind.h
+'''.split())
+
+logind_gperf_c = custom_target(
+ 'logind_gperf.c',
+ input : 'logind-gperf.gperf',
+ output : 'logind-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_logind_sources += [logind_gperf_c]
+
+
+liblogind_core_sources = files('''
+ logind-core.c
+ logind-device.c
+ logind-device.h
+ logind-button.c
+ logind-button.h
+ logind-action.c
+ logind-action.h
+ logind-seat.c
+ logind-seat.h
+ logind-session.c
+ logind-session.h
+ logind-session-device.c
+ logind-session-device.h
+ logind-user.c
+ logind-user.h
+ logind-inhibit.c
+ logind-inhibit.h
+ logind-dbus.c
+ logind-session-dbus.c
+ logind-seat-dbus.c
+ logind-user-dbus.c
+ logind-utmp.c
+ logind-acl.h
+'''.split())
+
+logind_acl_c = files('logind-acl.c')
+if conf.get('HAVE_ACL', false)
+ liblogind_core_sources += logind_acl_c
+endif
+
+liblogind_core = static_library(
+ 'logind-core',
+ liblogind_core_sources,
+ include_directories : includes,
+ dependencies : [libacl])
+
+loginctl_sources = files('''
+ loginctl.c
+ sysfs-show.h
+ sysfs-show.c
+'''.split())
+
+if conf.get('ENABLE_LOGIND', false)
+ logind_conf = configure_file(
+ input : 'logind.conf.in',
+ output : 'logind.conf',
+ configuration : substs)
+ install_data(logind_conf,
+ install_dir : pkgsysconfdir)
+
+ pam_systemd_sym = 'src/login/pam_systemd.sym'
+ pam_systemd_c = files('pam_systemd.c')
+
+ install_data('org.freedesktop.login1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.login1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.login1.policy',
+ input : 'org.freedesktop.login1.policy.in',
+ output : 'org.freedesktop.login1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+
+ install_data('70-power-switch.rules',
+ '70-uaccess.rules',
+ install_dir : udevrulesdir)
+
+ foreach file : ['71-seat.rules',
+ '73-seat-late.rules']
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : udevrulesdir)
+ endforeach
+
+ custom_target(
+ 'systemd-user',
+ input : 'systemd-user.m4',
+ output: 'systemd-user',
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : pamconfdir != 'no',
+ install_dir : pamconfdir)
+endif
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/file.h>
#include <sys/mount.h>
#include "alloc-util.h"
printf("No machines.\n");
}
+ r = 0;
out:
clean_machine_info(machines, n_machines);
return r;
" --mkdir Create directory before bind mounting, if missing\n"
" -n --lines=INTEGER Number of journal entries to show\n"
" --max-addresses=INTEGER Number of internet addresses to show at most\n"
- " -o --output=STRING Change journal output mode (short,\n"
- " short-monotonic, verbose, export, json,\n"
- " json-pretty, json-sse, cat)\n"
+ " -o --output=STRING Change journal output mode (short, short-precise,\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix, verbose, export,\n"
+ " json, json-pretty, json-sse, cat)\n"
" --verify=MODE Verification mode for downloaded images (no,\n"
" checksum, signature)\n"
" --force Download image even if already exists\n\n"
--- /dev/null
+systemd_machined_sources = files('''
+ machined.c
+ machined.h
+'''.split())
+
+libmachine_core_sources = files('''
+ machine.c
+ machine.h
+ machined-dbus.c
+ machine-dbus.c
+ machine-dbus.h
+ image-dbus.c
+ image-dbus.h
+ operation.c
+ operation.h
+'''.split())
+
+libmachine_core = static_library(
+ 'machine-core',
+ libmachine_core_sources,
+ include_directories : includes,
+ dependencies : [threads])
+
+if conf.get('ENABLE_MACHINED', false)
+ install_data('org.freedesktop.machine1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.machine1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.machine1.policy',
+ input : 'org.freedesktop.machine1.policy.in',
+ output : 'org.freedesktop.machine1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
+
+tests += [
+ [['src/machine/test-machine-tables.c'],
+ [libmachine_core,
+ libshared],
+ [threads],
+ 'ENABLE_MACHINED'],
+]
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sys/wait.h>
+
#include "alloc-util.h"
#include "fd-util.h"
#include "operation.h"
#include "bus-error.h"
#include "bus-unit-util.h"
#include "bus-util.h"
+#include "dirent-util.h"
#include "escape.h"
+#include "fd-util.h"
+#include "fileio.h"
#include "fstab-util.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
#include "spawn-polkit-agent.h"
+#include "stat-util.h"
#include "strv.h"
#include "udev-util.h"
#include "unit-name.h"
}
static void help(void) {
- printf("%s [OPTIONS...] WHAT [WHERE]\n\n"
+ printf("systemd-mount [OPTIONS...] WHAT [WHERE]\n"
+ "systemd-mount [OPTIONS...] --list\n"
+ "%s [OPTIONS...] %sWHAT|WHERE...\n\n"
"Establish a mount or auto-mount point transiently.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" Set automount unit property\n"
" --bind-device Bind automount unit to device\n"
" --list List mountable block devices\n"
- " -u --umount Unmount mount points\n"
- , program_invocation_short_name);
+ " -u --umount Unmount mount points\n",
+ program_invocation_short_name,
+ streq(program_invocation_short_name, "systemd-umount") ? "" : "--umount ");
}
static int parse_argv(int argc, char *argv[]) {
log_error("Listing devices only supported locally.");
return -EOPNOTSUPP;
}
+ } else if (arg_action == ACTION_UMOUNT) {
+ if (optind >= argc) {
+ log_error("At least one argument required.");
+ return -EINVAL;
+ }
+
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ int i;
+
+ for (i = optind; i < argc; i++)
+ if (!path_is_absolute(argv[i]) ) {
+ log_error("Only absolute path is supported: %s", argv[i]);
+ return -EINVAL;
+ }
+ }
} else {
if (optind >= argc) {
log_error("At least one argument required.");
return -EINVAL;
}
- arg_mount_what = fstab_node_to_udev_node(argv[optind]);
- if (!arg_mount_what)
- return log_oom();
+ if (arg_transport == BUS_TRANSPORT_LOCAL) {
+ _cleanup_free_ char *u = NULL, *p = NULL;
- if (argc > optind+1) {
- r = path_make_absolute_cwd(argv[optind+1], &arg_mount_where);
+ u = fstab_node_to_udev_node(argv[optind]);
+ if (!u)
+ return log_oom();
+
+ r = path_make_absolute_cwd(u, &p);
if (r < 0)
return log_error_errno(r, "Failed to make path absolute: %m");
+
+ arg_mount_what = canonicalize_file_name(p);
+ if (!arg_mount_what)
+ return log_error_errno(errno, "Failed to canonicalize path: %m");
+
+ } else {
+ arg_mount_what = strdup(argv[optind+1]);
+ if (!arg_mount_what)
+ return log_oom();
+
+ path_kill_slashes(arg_mount_what);
+
+ if (!path_is_absolute(arg_mount_what)) {
+ log_error("Only absolute path is supported: %s", arg_mount_what);
+ return -EINVAL;
+ }
+ }
+
+ if (argc > optind+1) {
+ if (arg_transport == BUS_TRANSPORT_LOCAL) {
+ _cleanup_free_ char *p = NULL;
+
+ r = path_make_absolute_cwd(argv[optind+1], &p);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make path absolute: %m");
+
+ arg_mount_where = canonicalize_file_name(p);
+ if (!arg_mount_where)
+ return log_error_errno(errno, "Failed to canonicalize path: %m");
+
+ } else {
+ arg_mount_where = strdup(argv[optind+1]);
+ if (!arg_mount_where)
+ return log_oom();
+
+ path_kill_slashes(arg_mount_where);
+
+ if (!path_is_absolute(arg_mount_where)) {
+ log_error("Only absolute path is supported: %s", arg_mount_where);
+ return -EINVAL;
+ }
+ }
} else
arg_discover = true;
return 0;
}
+static int find_mount_points(const char *what, char ***list) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ size_t bufsize = 0, n = 0;
+
+ assert(what);
+ assert(list);
+
+ /* Returns all mount points obtained from /proc/self/mountinfo in *list,
+ * and the number of mount points as return value. */
+
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
+ return log_error_errno(errno, "Can't open /proc/self/mountinfo: %m");
+
+ for (;;) {
+ _cleanup_free_ char *path = NULL, *where = NULL, *dev = NULL;
+ int r;
+
+ r = fscanf(proc_self_mountinfo,
+ "%*s " /* (1) mount id */
+ "%*s " /* (2) parent id */
+ "%*s " /* (3) major:minor */
+ "%*s " /* (4) root */
+ "%ms " /* (5) mount point */
+ "%*s" /* (6) mount options */
+ "%*[^-]" /* (7) optional fields */
+ "- " /* (8) separator */
+ "%*s " /* (9) file system type */
+ "%ms" /* (10) mount source */
+ "%*s" /* (11) mount options 2 */
+ "%*[^\n]", /* some rubbish at the end */
+ &path, &dev);
+ if (r != 2) {
+ if (r == EOF)
+ break;
+
+ continue;
+ }
+
+ if (!streq(what, dev))
+ continue;
+
+ r = cunescape(path, UNESCAPE_RELAX, &where);
+ if (r < 0)
+ continue;
+
+ /* one extra slot is needed for the terminating NULL */
+ if (!GREEDY_REALLOC(l, bufsize, n + 2))
+ return log_oom();
+
+ l[n++] = where;
+ where = NULL;
+ }
+
+ if (!GREEDY_REALLOC(l, bufsize, n + 1))
+ return log_oom();
+
+ l[n] = NULL;
+ *list = l;
+ l = NULL; /* avoid freeing */
+
+ return n;
+}
+
+static int find_loop_device(const char *backing_file, char **loop_dev) {
+ _cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
+ _cleanup_free_ char *l = NULL;
+
+ assert(backing_file);
+ assert(loop_dev);
+
+ d = opendir("/sys/devices/virtual/block");
+ if (!d)
+ return -errno;
+
+ FOREACH_DIRENT(de, d, return -errno) {
+ _cleanup_free_ char *sys = NULL, *fname = NULL;
+ int r;
+
+ dirent_ensure_type(d, de);
+
+ if (de->d_type != DT_DIR)
+ continue;
+
+ if (!startswith(de->d_name, "loop"))
+ continue;
+
+ sys = strjoin("/sys/devices/virtual/block/", de->d_name, "/loop/backing_file");
+ if (!sys)
+ return -ENOMEM;
+
+ r = read_one_line_file(sys, &fname);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to read %s, ignoring: %m", sys);
+ continue;
+ }
+
+ if (files_same(fname, backing_file, 0) <= 0)
+ continue;
+
+ l = strjoin("/dev/", de->d_name);
+ if (!l)
+ return -ENOMEM;
+
+ break;
+ }
+
+ if (!l)
+ return -ENXIO;
+
+ *loop_dev = l;
+ l = NULL; /* avoid freeing */
+
+ return 0;
+}
+
static int stop_mount(
sd_bus *bus,
- char **argv,
+ const char *where,
const char *suffix) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
return log_error_errno(r, "Could not watch jobs: %m");
}
- r = unit_name_from_path(arg_mount_where, suffix, &mount_unit);
+ r = unit_name_from_path(where, suffix, &mount_unit);
if (r < 0)
- return log_error_errno(r, "Failed to make mount unit name: %m");
+ return log_error_errno(r, "Failed to make mount unit name from path %s: %m", where);
r = sd_bus_message_new_method_call(
bus,
if (!arg_quiet)
log_info("Stopped unit %s%s%s for mount point: %s%s%s",
ansi_highlight(), mount_unit, ansi_normal(),
- ansi_highlight(), arg_mount_where, ansi_normal());
+ ansi_highlight(), where, ansi_normal());
return 0;
}
static int stop_mounts(
sd_bus *bus,
- char **argv) {
+ const char *where) {
int r;
- r = stop_mount(bus, argv + optind, ".mount");
+ if (path_equal(where, "/")) {
+ log_error("Refusing to operate on root directory: %s", where);
+ return -EINVAL;
+ }
+
+ if (!path_is_safe(where)) {
+ log_error("Path contains unsafe components: %s", where);
+ return -EINVAL;
+ }
+
+ r = stop_mount(bus, where, ".mount");
if (r < 0)
return r;
- r = stop_mount(bus, argv + optind, ".automount");
+ r = stop_mount(bus, where, ".automount");
if (r < 0)
return r;
return 0;
}
+static int umount_by_device(sd_bus *bus, const char *what) {
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ _cleanup_strv_free_ char **list = NULL;
+ struct stat st;
+ const char *v;
+ char **l;
+ int r, r2 = 0;
+
+ assert(what);
+
+ if (stat(what, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", what);
+
+ if (!S_ISBLK(st.st_mode)) {
+ log_error("Not a block device: %s", what);
+ return -ENOTBLK;
+ }
+
+ udev = udev_new();
+ if (!udev)
+ return log_oom();
+
+ d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!d)
+ return log_oom();
+
+ v = udev_device_get_property_value(d, "ID_FS_USAGE");
+ if (!streq_ptr(v, "filesystem")) {
+ log_error("%s does not contain a known file system.", what);
+ return -EINVAL;
+ }
+
+ v = udev_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE");
+ if (!isempty(v))
+ r2 = stop_mounts(bus, v);
+
+ r = find_mount_points(what, &list);
+ if (r < 0)
+ return r;
+
+ for (l = list; *l; l++) {
+ r = stop_mounts(bus, *l);
+ if (r < 0)
+ r2 = r;
+ }
+
+ return r2;
+}
+
+static int umount_loop(sd_bus *bus, const char *backing_file) {
+ _cleanup_free_ char *loop_dev = NULL;
+ int r;
+
+ assert(backing_file);
+
+ r = find_loop_device(backing_file, &loop_dev);
+ if (r < 0)
+ return log_error_errno(r, r == -ENXIO ? "File %s is not mounted." : "Can't get loop device for %s: %m", backing_file);
+
+ return umount_by_device(bus, loop_dev);
+}
+
+static int action_umount(
+ sd_bus *bus,
+ int argc,
+ char **argv) {
+
+ int i, r, r2 = 0;
+
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ for (i = optind; i < argc; i++) {
+ _cleanup_free_ char *p = NULL;
+
+ p = strdup(argv[i]);
+ if (!p)
+ return log_oom();
+
+ path_kill_slashes(p);
+
+ r = stop_mounts(bus, p);
+ if (r < 0)
+ r2 = r;
+ }
+ return r2;
+ }
+
+ for (i = optind; i < argc; i++) {
+ _cleanup_free_ char *u = NULL, *a = NULL, *p = NULL;
+ struct stat st;
+
+ u = fstab_node_to_udev_node(argv[i]);
+ if (!u)
+ return log_oom();
+
+ r = path_make_absolute_cwd(u, &a);
+ if (r < 0) {
+ r2 = log_error_errno(r, "Failed to make path absolute: %m");
+ continue;
+ }
+
+ p = canonicalize_file_name(a);
+
+ if (stat(p, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", p);
+
+ if (S_ISBLK(st.st_mode))
+ r = umount_by_device(bus, p);
+ else if (S_ISREG(st.st_mode))
+ r = umount_loop(bus, p);
+ else if (S_ISDIR(st.st_mode))
+ r = stop_mounts(bus, p);
+ else {
+ log_error("Invalid file type: %s", p);
+ r = -EINVAL;
+ }
+
+ if (r < 0)
+ r2 = r;
+ }
+
+ return r2;
+}
+
static int acquire_mount_type(struct udev_device *d) {
const char *v;
}
escaped = xescape(name, "\\");
+ if (!escaped)
+ return log_oom();
if (!filename_is_valid(escaped))
return 0;
return 1;
}
+static int acquire_mount_where_for_loop_dev(const char *loop_dev) {
+ _cleanup_strv_free_ char **list = NULL;
+ int r;
+
+ if (arg_mount_where)
+ return 0;
+
+ r = find_mount_points(loop_dev, &list);
+ if (r < 0)
+ return r;
+ else if (r == 0) {
+ log_error("Can't find mount point of %s. It is expected that %s is already mounted on a place.", loop_dev, loop_dev);
+ return -EINVAL;
+ } else if (r >= 2) {
+ log_error("%s is mounted on %d places. It is expected that %s is mounted on a place.", loop_dev, r, loop_dev);
+ return -EINVAL;
+ }
+
+ arg_mount_where = strdup(list[0]);
+ if (!arg_mount_where)
+ return log_oom();
+
+ log_debug("Discovered where=%s", arg_mount_where);
+ return 1;
+}
+
static int acquire_description(struct udev_device *d) {
const char *model, *label;
return 1;
}
-static int discover_device(void) {
+static int discover_loop_backing_file(void) {
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
_cleanup_udev_unref_ struct udev *udev = NULL;
+ _cleanup_free_ char *loop_dev = NULL;
struct stat st;
const char *v;
int r;
- if (!arg_discover)
+ r = find_loop_device(arg_mount_what, &loop_dev);
+ if (r < 0 && r != -ENXIO)
+ return log_error_errno(errno, "Can't get loop device for %s: %m", arg_mount_what);
+
+ if (r == -ENXIO) {
+ _cleanup_free_ char *escaped = NULL;
+
+ if (arg_mount_where)
+ return 0;
+
+ escaped = xescape(basename(arg_mount_what), "\\");
+ if (!escaped)
+ return log_oom();
+ if (!filename_is_valid(escaped)) {
+ log_error("Escaped name %s is not a valid filename.", escaped);
+ return -EINVAL;
+ }
+
+ arg_mount_where = strjoin("/run/media/system/", escaped);
+ if (!arg_mount_where)
+ return log_oom();
+
+ log_debug("Discovered where=%s", arg_mount_where);
return 0;
+ }
+
+ if (stat(loop_dev, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", loop_dev);
- if (!is_device_path(arg_mount_what)) {
- log_error("Discovery only supported for block devices, don't know what to do.");
+ if (!S_ISBLK(st.st_mode)) {
+ log_error("Invalid file type: %s", loop_dev);
return -EINVAL;
}
+ udev = udev_new();
+ if (!udev)
+ return log_oom();
+
+ d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!d)
+ return log_oom();
+
+ v = udev_device_get_property_value(d, "ID_FS_USAGE");
+ if (!streq_ptr(v, "filesystem")) {
+ log_error("%s does not contain a known file system.", arg_mount_what);
+ return -EINVAL;
+ }
+
+ r = acquire_mount_type(d);
+ if (r < 0)
+ return r;
+
+ r = acquire_mount_options(d);
+ if (r < 0)
+ return r;
+
+ r = acquire_mount_where_for_loop_dev(loop_dev);
+ if (r < 0)
+ return r;
+
+ r = acquire_description(d);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+static int discover_device(void) {
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ struct stat st;
+ const char *v;
+ int r;
+
if (stat(arg_mount_what, &st) < 0)
return log_error_errno(errno, "Can't stat %s: %m", arg_mount_what);
+ if (S_ISREG(st.st_mode))
+ return discover_loop_backing_file();
+
if (!S_ISBLK(st.st_mode)) {
- log_error("Path %s is not a block device, don't know what to do.", arg_mount_what);
- return -ENOTBLK;
+ log_error("Invalid file type: %s", arg_mount_what);
+ return -EINVAL;
}
udev = udev_new();
v = udev_device_get_property_value(d, "ID_FS_USAGE");
if (!streq_ptr(v, "filesystem")) {
- log_error("%s does not contain a file system.", arg_mount_what);
+ log_error("%s does not contain a known file system.", arg_mount_what);
return -EINVAL;
}
goto finish;
}
- r = discover_device();
- if (r < 0)
+ r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to create bus connection: %m");
+ goto finish;
+ }
+
+ if (arg_action == ACTION_UMOUNT) {
+ r = action_umount(bus, argc, argv);
+ goto finish;
+ }
+
+ if (!path_is_safe(arg_mount_what)) {
+ log_error("Path contains unsafe components: %s", arg_mount_what);
+ r = -EINVAL;
goto finish;
+ }
+
+ if (arg_discover) {
+ r = discover_device();
+ if (r < 0)
+ goto finish;
+ }
+
if (!arg_mount_where) {
log_error("Can't figure out where to mount %s.", arg_mount_what);
r = -EINVAL;
goto finish;
}
- path_kill_slashes(arg_mount_where);
-
if (path_equal(arg_mount_where, "/")) {
log_error("Refusing to operate on root directory.");
r = -EINVAL;
}
if (!path_is_safe(arg_mount_where)) {
- log_error("Path is contains unsafe components.");
+ log_error("Path contains unsafe components: %s", arg_mount_where);
r = -EINVAL;
goto finish;
}
}
}
- r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
- if (r < 0) {
- log_error_errno(r, "Failed to create bus connection: %m");
- goto finish;
- }
-
switch (arg_action) {
case ACTION_MOUNT:
r = start_transient_automount(bus, argv + optind);
break;
- case ACTION_UMOUNT:
- r = stop_mounts(bus, argv + optind);
- break;
-
default:
assert_not_reached("Unexpected action.");
}
--- /dev/null
+sources = files('''
+ netdev/bond.c
+ netdev/bond.h
+ netdev/bridge.c
+ netdev/bridge.h
+ netdev/dummy.c
+ netdev/dummy.h
+ netdev/ipvlan.c
+ netdev/ipvlan.h
+ netdev/macvlan.c
+ netdev/macvlan.h
+ netdev/netdev.c
+ netdev/netdev.h
+ netdev/tunnel.c
+ netdev/tunnel.h
+ netdev/tuntap.c
+ netdev/tuntap.h
+ netdev/vcan.c
+ netdev/vcan.h
+ netdev/veth.c
+ netdev/veth.h
+ netdev/vlan.c
+ netdev/vlan.h
+ netdev/vrf.c
+ netdev/vrf.h
+ netdev/vxlan.c
+ netdev/vxlan.h
+ netdev/geneve.c
+ netdev/geneve.h
+ networkd-address-label.c
+ networkd-address-label.h
+ networkd-address-pool.c
+ networkd-address-pool.h
+ networkd-address.c
+ networkd-address.h
+ networkd-brvlan.c
+ networkd-brvlan.h
+ networkd-conf.c
+ networkd-conf.h
+ networkd-dhcp4.c
+ networkd-dhcp6.c
+ networkd-fdb.c
+ networkd-fdb.h
+ networkd-ipv4ll.c
+ networkd-ipv6-proxy-ndp.c
+ networkd-ipv6-proxy-ndp.h
+ networkd-link-bus.c
+ networkd-link.c
+ networkd-link.h
+ networkd-lldp-tx.c
+ networkd-lldp-tx.h
+ networkd-manager-bus.c
+ networkd-manager.c
+ networkd-manager.h
+ networkd-ndisc.c
+ networkd-ndisc.h
+ networkd-radv.c
+ networkd-radv.h
+ networkd-network-bus.c
+ networkd-network.c
+ networkd-network.h
+ networkd-route.c
+ networkd-route.h
+ networkd-util.c
+ networkd-util.h
+'''.split())
+
+systemd_networkd_sources = files('networkd.c')
+
+systemd_networkd_wait_online_sources = files('''
+ wait-online/link.c
+ wait-online/link.h
+ wait-online/manager.c
+ wait-online/manager.h
+ wait-online/wait-online.c
+'''.split()) + network_internal_h
+
+networkctl_sources = files('networkctl.c')
+
+network_include_dir = include_directories('.')
+
+if conf.get('ENABLE_NETWORKD', false)
+ networkd_gperf_c = custom_target(
+ 'networkd-gperf.c',
+ input : 'networkd-gperf.gperf',
+ output : 'networkd-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+ networkd_network_gperf_c = custom_target(
+ 'networkd-network-gperf.c',
+ input : 'networkd-network-gperf.gperf',
+ output : 'networkd-network-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+ netdev_gperf_c = custom_target(
+ 'netdev-gperf.c',
+ input : 'netdev/netdev-gperf.gperf',
+ output : 'netdev-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+ libnetworkd_core = static_library(
+ 'networkd-core',
+ sources,
+ network_internal_h,
+ networkd_gperf_c,
+ networkd_network_gperf_c,
+ netdev_gperf_c,
+ include_directories : includes,
+ link_with : [libshared])
+
+ install_data('org.freedesktop.network1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.network1.service',
+ install_dir : dbussystemservicedir)
+ if install_polkit
+ install_data('systemd-networkd.rules',
+ install_dir : polkitrulesdir)
+ endif
+ if install_polkit_pkla
+ install_data('systemd-networkd.pkla',
+ install_dir : polkitpkladir)
+ endif
+
+ tests += [
+ [['src/network/test-networkd-conf.c'],
+ [libnetworkd_core,
+ libsystemd_network,
+ libudev],
+ []],
+
+ [['src/network/test-network.c'],
+ [libnetworkd_core,
+ libudev_internal,
+ libsystemd_network,
+ libshared],
+ [threads]],
+
+ [['src/network/test-network-tables.c',
+ 'src/network/test-network-tables.c',
+ test_tables_h],
+ [libnetworkd_core,
+ libudev_internal,
+ libudev_core,
+ libsystemd_network,
+ libshared],
+ [threads],
+ '', '', [],
+ [network_include_dir] + libudev_core_includes],
+ ]
+endif
#include "netlink-util.h"
#include "netdev/bridge.h"
#include "networkd-manager.h"
+#include "vlan-util.h"
/* callback for brige netdev's parameter set */
static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_PRIORITY attribute: %m");
}
- if (b->default_pvid > 0) {
+ if (b->default_pvid != VLANID_INVALID) {
r = sd_netlink_message_append_u16(req, IFLA_BR_VLAN_DEFAULT_PVID, b->default_pvid);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_DEFAULT_PVID attribute: %m");
b->mcast_snooping = -1;
b->vlan_filtering = -1;
b->stp = -1;
+ b->default_pvid = VLANID_INVALID;
b->forward_delay = USEC_INFINITY;
}
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Susant Sahani
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+
+#include "alloc-util.h"
+#include "conf-parser.h"
+#include "extract-word.h"
+#include "geneve.h"
+#include "parse-util.h"
+#include "sd-netlink.h"
+#include "string-util.h"
+#include "strv.h"
+#include "missing.h"
+#include "networkd-manager.h"
+
+#define GENEVE_FLOW_LABEL_MAX_MASK 0xFFFFFU
+#define DEFAULT_GENEVE_DESTINATION_PORT 6081
+
+/* callback for geneve netdev's created without a backing Link */
+static int geneve_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ _cleanup_netdev_unref_ NetDev *netdev = userdata;
+ int r;
+
+ assert(netdev->state != _NETDEV_STATE_INVALID);
+
+ r = sd_netlink_message_get_errno(m);
+ if (r == -EEXIST)
+ log_netdev_info(netdev, "Geneve netdev exists, using existing without changing its parameters");
+ else if (r < 0) {
+ log_netdev_warning_errno(netdev, r, "Geneve netdev could not be created: %m");
+ netdev_drop(netdev);
+
+ return 1;
+ }
+
+ log_netdev_debug(netdev, "Geneve created");
+
+ return 1;
+}
+
+static int netdev_geneve_create(NetDev *netdev) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
+ Geneve *v;
+ int r;
+
+ assert(netdev);
+
+ v = GENEVE(netdev);
+
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not allocate RTM_NEWLINK message: %m");
+
+ r = sd_netlink_message_append_string(m, IFLA_IFNAME, netdev->ifname);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_IFNAME, attribute: %m");
+
+ if (netdev->mac) {
+ r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
+ }
+
+ if (netdev->mtu) {
+ r = sd_netlink_message_append_u32(m, IFLA_MTU, netdev->mtu);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_MTU attribute: %m");
+ }
+
+ r = sd_netlink_message_open_container(m, IFLA_LINKINFO);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+ r = sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, netdev_kind_to_string(netdev->kind));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ if (v->id <= GENEVE_VID_MAX) {
+ r = sd_netlink_message_append_u32(m, IFLA_GENEVE_ID, v->id);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_ID attribute: %m");
+ }
+
+ if (!in_addr_is_null(v->remote_family, &v->remote)) {
+
+ if (v->remote_family == AF_INET)
+ r = sd_netlink_message_append_in_addr(m, IFLA_GENEVE_REMOTE, &v->remote.in);
+ else
+ r = sd_netlink_message_append_in6_addr(m, IFLA_GENEVE_REMOTE6, &v->remote.in6);
+
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_GROUP attribute: %m");
+
+ }
+
+ if (v->ttl) {
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_TTL, v->ttl);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_TTL attribute: %m");
+ }
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_TOS, v->tos);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_TOS attribute: %m");
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_CSUM, v->udpcsum);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_CSUM attribute: %m");
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, v->udp6zerocsumtx);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_ZERO_CSUM6_TX attribute: %m");
+
+ r = sd_netlink_message_append_u8(m, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, v->udp6zerocsumrx);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_UDP_ZERO_CSUM6_RX attribute: %m");
+
+ if (v->dest_port != DEFAULT_GENEVE_DESTINATION_PORT) {
+ r = sd_netlink_message_append_u16(m, IFLA_GENEVE_PORT, htobe16(v->dest_port));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_PORT attribute: %m");
+ }
+
+ if (v->flow_label > 0) {
+ r = sd_netlink_message_append_u32(m, IFLA_GENEVE_LABEL, htobe32(v->flow_label));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_LABEL attribute: %m");
+ }
+
+ r = sd_netlink_message_close_container(m);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
+
+ r = sd_netlink_message_close_container(m);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
+
+ r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, netdev, 0, NULL);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
+
+ netdev_ref(netdev);
+
+ netdev->state = NETDEV_STATE_CREATING;
+
+ log_netdev_debug(netdev, "Creating");
+
+
+ return r;
+}
+
+int config_parse_geneve_vni(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) {
+ Geneve *v = userdata;
+ uint32_t f;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou32(rvalue, &f);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Geneve VNI '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f > GENEVE_VID_MAX){
+ log_syntax(unit, LOG_ERR, filename, line, r, "Geneve VNI out is of range '%s'.", rvalue);
+ return 0;
+ }
+
+ v->id = f;
+
+ return 0;
+}
+
+int config_parse_geneve_address(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) {
+ Geneve *v = userdata;
+ union in_addr_union *addr = data, buffer;
+ int r, f;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = in_addr_from_string_auto(rvalue, &f, &buffer);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "geneve '%s' address is invalid, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ r = in_addr_is_multicast(f, &buffer);
+ if (r > 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "geneve invalid multicast '%s' address, ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ v->remote_family = f;
+ *addr = buffer;
+
+ return 0;
+}
+
+int config_parse_geneve_flow_label(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) {
+ Geneve *v = userdata;
+ uint32_t f;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = safe_atou32(rvalue, &f);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Geneve flow label '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f & ~GENEVE_FLOW_LABEL_MAX_MASK) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Geneve flow label '%s' not valid. Flow label range should be [0-1048575].", rvalue);
+ return 0;
+ }
+
+ v->flow_label = f;
+
+ return 0;
+}
+
+static int netdev_geneve_verify(NetDev *netdev, const char *filename) {
+ Geneve *v = GENEVE(netdev);
+
+ assert(netdev);
+ assert(v);
+ assert(filename);
+
+ if (v->ttl == 0) {
+ log_warning("Invalid Geneve TTL value '0' configured in '%s'. Ignoring", filename);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void geneve_init(NetDev *netdev) {
+ Geneve *v;
+
+ assert(netdev);
+
+ v = GENEVE(netdev);
+
+ assert(v);
+
+ v->id = GENEVE_VID_MAX + 1;
+ v->dest_port = DEFAULT_GENEVE_DESTINATION_PORT;
+ v->udpcsum = false;
+ v->udp6zerocsumtx = false;
+ v->udp6zerocsumrx = false;
+}
+
+const NetDevVTable geneve_vtable = {
+ .object_size = sizeof(Geneve),
+ .init = geneve_init,
+ .sections = "Match\0NetDev\0GENEVE\0",
+ .create = netdev_geneve_create,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
+ .config_verify = netdev_geneve_verify,
+};
--- /dev/null
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Susant Sahani
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+typedef struct Geneve Geneve;
+
+#include "in-addr-util.h"
+#include "netdev.h"
+#include "networkd-link.h"
+#include "networkd-network.h"
+
+#define GENEVE_VID_MAX (1u << 24) - 1
+
+struct Geneve {
+ NetDev meta;
+
+ uint32_t id;
+ uint32_t flow_label;
+
+ int remote_family;
+
+ uint8_t tos;
+ uint8_t ttl;
+
+ uint16_t dest_port;
+
+ bool udpcsum;
+ bool udp6zerocsumtx;
+ bool udp6zerocsumrx;
+
+ union in_addr_union remote;
+};
+
+DEFINE_NETDEV_CAST(GENEVE, Geneve);
+extern const NetDevVTable geneve_vtable;
+
+int config_parse_geneve_vni(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);
+
+int config_parse_geneve_address(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);
+
+int config_parse_geneve_flow_label(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);
#include "network-internal.h"
#include "netdev/bond.h"
#include "netdev/bridge.h"
+#include "netdev/geneve.h"
#include "netdev/ipvlan.h"
#include "netdev/macvlan.h"
#include "netdev/tunnel.h"
NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
VLAN.Id, config_parse_vlanid, 0, offsetof(VLan, id)
+VLAN.GVRP, config_parse_tristate, 0, offsetof(VLan, gvrp)
+VLAN.MVRP, config_parse_tristate, 0, offsetof(VLan, mvrp)
+VLAN.LooseBinding, config_parse_tristate, 0, offsetof(VLan, loose_binding)
+VLAN.ReorderHeader, config_parse_tristate, 0, offsetof(VLan, reorder_hdr)
MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
MACVTAP.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
IPVLAN.Mode, config_parse_ipvlan_mode, 0, offsetof(IPVlan, mode)
VXLAN.GroupPolicyExtension, config_parse_bool, 0, offsetof(VxLan, group_policy)
VXLAN.MaximumFDBEntries, config_parse_unsigned, 0, offsetof(VxLan, max_fdb)
VXLAN.PortRange, config_parse_port_range, 0, 0
-VXLAN.DestinationPort, config_parse_destination_port, 0, offsetof(VxLan, dest_port)
+VXLAN.DestinationPort, config_parse_ip_port, 0, offsetof(VxLan, dest_port)
+VXLAN.FlowLabel, config_parse_flow_label, 0, 0
+GENEVE.Id, config_parse_geneve_vni, 0, offsetof(Geneve, id)
+GENEVE.Remote, config_parse_geneve_address, 0, offsetof(Geneve, remote)
+GENEVE.TOS, config_parse_uint8, 0, offsetof(Geneve, tos)
+GENEVE.TTL, config_parse_uint8, 0, offsetof(Geneve, ttl)
+GENEVE.UDPChecksum, config_parse_bool, 0, offsetof(Geneve, udpcsum)
+GENEVE.UDP6ZeroCheckSumRx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumrx)
+GENEVE.UDP6ZeroCheckSumTx, config_parse_bool, 0, offsetof(Geneve, udp6zerocsumtx)
+GENEVE.DestinationPort, config_parse_ip_port, 0, offsetof(Geneve, dest_port)
+GENEVE.FlowLabel, config_parse_geneve_flow_label, 0, 0
Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
Bridge.AgeingTimeSec, config_parse_sec, 0, offsetof(Bridge, ageing_time)
Bridge.ForwardDelaySec, config_parse_sec, 0, offsetof(Bridge, forward_delay)
Bridge.Priority, config_parse_uint16, 0, offsetof(Bridge, priority)
-Bridge.DefaultPVID, config_parse_vlanid, 0, offsetof(Bridge, default_pvid)
+Bridge.DefaultPVID, config_parse_default_port_vlanid, 0, offsetof(Bridge, default_pvid)
Bridge.MulticastQuerier, config_parse_tristate, 0, offsetof(Bridge, mcast_querier)
Bridge.MulticastSnooping, config_parse_tristate, 0, offsetof(Bridge, mcast_snooping)
Bridge.VLANFiltering, config_parse_tristate, 0, offsetof(Bridge, vlan_filtering)
#include "network-internal.h"
#include "netdev/netdev.h"
#include "networkd-manager.h"
+#include "networkd-link.h"
#include "siphash24.h"
#include "stat-util.h"
#include "string-table.h"
#include "netdev/bridge.h"
#include "netdev/bond.h"
+#include "netdev/geneve.h"
#include "netdev/vlan.h"
#include "netdev/macvlan.h"
#include "netdev/ipvlan.h"
[NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
[NETDEV_KIND_VRF] = &vrf_vtable,
[NETDEV_KIND_VCAN] = &vcan_vtable,
+ [NETDEV_KIND_GENEVE] = &geneve_vtable,
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_IP6TNL] = "ip6tnl",
[NETDEV_KIND_VRF] = "vrf",
[NETDEV_KIND_VCAN] = "vcan",
+ [NETDEV_KIND_GENEVE] = "geneve",
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
assert(link);
assert(callback);
+ if (link->flags & IFF_UP) {
+ log_netdev_debug(netdev, "Link '%s' was up when attempting to enslave it. Bringing link down.", link->ifname);
+ r = link_down(link);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not bring link down: %m");
+ }
+
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not allocate RTM_SETLINK message: %m");
NETDEV_KIND_TAP,
NETDEV_KIND_VRF,
NETDEV_KIND_VCAN,
+ NETDEV_KIND_GENEVE,
_NETDEV_KIND_MAX,
_NETDEV_KIND_INVALID = -1
} NetDevKind;
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <linux/if_vlan.h>
#include <net/if.h>
#include "netdev/vlan.h"
#include "vlan-util.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
+ struct ifla_vlan_flags flags = {};
VLan *v;
int r;
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_ID attribute: %m");
+ if (v->gvrp != -1) {
+ flags.mask |= VLAN_FLAG_GVRP;
+ SET_FLAG(flags.flags, VLAN_FLAG_GVRP, v->gvrp);
+ }
+
+ if (v->mvrp != -1) {
+ flags.mask |= VLAN_FLAG_MVRP;
+ SET_FLAG(flags.flags, VLAN_FLAG_MVRP, v->mvrp);
+ }
+
+ if (v->reorder_hdr != -1) {
+ flags.mask |= VLAN_FLAG_REORDER_HDR;
+ SET_FLAG(flags.flags, VLAN_FLAG_REORDER_HDR, v->reorder_hdr);
+ }
+
+ if (v->loose_binding != -1) {
+ flags.mask |= VLAN_FLAG_LOOSE_BINDING;
+ SET_FLAG(flags.flags, VLAN_FLAG_LOOSE_BINDING, v->loose_binding);
+ }
+
+ r = sd_netlink_message_append_data(req, IFLA_VLAN_FLAGS, &flags, sizeof(struct ifla_vlan_flags));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_FLAGS attribute: %m");
+
return 0;
}
assert(v);
v->id = VLANID_INVALID;
+ v->gvrp = -1;
+ v->mvrp = -1;
+ v->loose_binding = -1;
+ v->reorder_hdr = -1;
}
const NetDevVTable vlan_vtable = {
NetDev meta;
uint16_t id;
+
+ int gvrp;
+ int mvrp;
+ int loose_binding;
+ int reorder_hdr;
};
DEFINE_NETDEV_CAST(VLAN, VLan);
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_PORT_RANGE attribute: %m");
}
+ r = sd_netlink_message_append_u32(m, IFLA_VXLAN_LABEL, htobe32(v->flow_label));
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_LABEL attribute: %m");
+
if (v->group_policy) {
r = sd_netlink_message_append_flag(m, IFLA_VXLAN_GBP);
if (r < 0)
return 0;
}
-int config_parse_destination_port(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) {
+int config_parse_flow_label(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) {
VxLan *v = userdata;
- uint16_t port;
+ unsigned f;
int r;
assert(filename);
assert(rvalue);
assert(data);
- r = parse_ip_port(rvalue, &port);
+ r = safe_atou(rvalue, &f);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN destination port '%s'.", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VXLAN flow label '%s'.", rvalue);
+ return 0;
+ }
+
+ if (f & ~VXLAN_FLOW_LABEL_MAX_MASK) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "VXLAN flow label '%s' not valid. Flow label range should be [0-1048575].", rvalue);
return 0;
}
- v->dest_port = port;
+ v->flow_label = f;
return 0;
}
#include "netdev/netdev.h"
#define VXLAN_VID_MAX (1u << 24) - 1
+#define VXLAN_FLOW_LABEL_MAX_MASK 0xFFFFFU
struct VxLan {
NetDev meta;
unsigned tos;
unsigned ttl;
unsigned max_fdb;
+ unsigned flow_label;
uint16_t dest_port;
void *data,
void *userdata);
-int config_parse_destination_port(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);
+int config_parse_flow_label(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);
***/
#include <getopt.h>
+#include <linux/if_addrlabel.h>
#include <net/if.h>
#include <stdbool.h>
#include "hwdb-util.h"
#include "local-addresses.h"
#include "locale-util.h"
+#include "macro.h"
#include "netlink-util.h"
#include "pager.h"
#include "parse-util.h"
return 0;
}
+static int dump_address_labels(sd_netlink *rtnl) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
+ sd_netlink_message *m;
+ int r;
+
+ assert(rtnl);
+
+ r = sd_rtnl_message_new_addrlabel(rtnl, &req, RTM_GETADDRLABEL, 0, AF_INET6);
+ if (r < 0)
+ return log_error_errno(r, "Could not allocate RTM_GETADDRLABEL message: %m");
+
+ r = sd_netlink_message_request_dump(req, true);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(rtnl, req, 0, &reply);
+ if (r < 0)
+ return r;
+
+ printf("%10s/%s %30s\n", "Prefix", "Prefixlen", "Label");
+
+ for (m = reply; m; m = sd_netlink_message_next(m)) {
+ _cleanup_free_ char *pretty = NULL;
+ union in_addr_union prefix = {};
+ uint8_t prefixlen;
+ uint32_t label;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0) {
+ log_error_errno(r, "got error: %m");
+ continue;
+ }
+
+ r = sd_netlink_message_read_u32(m, IFAL_LABEL, &label);
+ if (r < 0 && r != -ENODATA) {
+ log_error_errno(r, "Could not read IFAL_LABEL, ignoring: %m");
+ continue;
+ }
+
+ r = sd_netlink_message_read_in6_addr(m, IFAL_ADDRESS, &prefix.in6);
+ if (r < 0)
+ continue;
+
+ r = in_addr_to_string(AF_INET6, &prefix, &pretty);
+ if (r < 0)
+ continue;
+
+ r = sd_rtnl_message_addrlabel_get_prefixlen(m, &prefixlen);
+ if (r < 0)
+ continue;
+
+ printf("%10s/%-5u %30u\n", pretty, prefixlen, label);
+ }
+
+ return 0;
+}
+
+static int list_address_labels(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ int r;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ dump_address_labels(rtnl);
+
+ return 0;
+}
+
static int open_lldp_neighbors(int ifindex, FILE **ret) {
_cleanup_free_ char *p = NULL;
FILE *f;
" list [LINK...] List links\n"
" status [LINK...] Show link status\n"
" lldp [LINK...] Show LLDP neighbors\n"
+ " label Show current address label entries in the kernel\n"
, program_invocation_short_name);
}
{ "list", VERB_ANY, VERB_ANY, VERB_DEFAULT, list_links },
{ "status", VERB_ANY, VERB_ANY, 0, link_status },
{ "lldp", VERB_ANY, VERB_ANY, 0, link_lldp_status },
+ { "label", VERB_ANY, VERB_ANY, 0, list_address_labels},
{}
};
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Susant Sahani
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <net/if.h>
+#include <linux/if_addrlabel.h>
+
+#include "alloc-util.h"
+#include "conf-parser.h"
+#include "networkd-address-label.h"
+#include "netlink-util.h"
+#include "networkd-manager.h"
+#include "parse-util.h"
+#include "socket-util.h"
+
+int address_label_new(AddressLabel **ret) {
+ _cleanup_address_label_free_ AddressLabel *addrlabel = NULL;
+
+ addrlabel = new0(AddressLabel, 1);
+ if (!addrlabel)
+ return -ENOMEM;
+
+ *ret = addrlabel;
+ addrlabel = NULL;
+
+ return 0;
+}
+
+void address_label_free(AddressLabel *label) {
+ if (!label)
+ return;
+
+ if (label->network) {
+ LIST_REMOVE(labels, label->network->address_labels, label);
+ assert(label->network->n_address_labels > 0);
+ label->network->n_address_labels--;
+
+ if (label->section) {
+ hashmap_remove(label->network->address_labels_by_section, label->section);
+ network_config_section_free(label->section);
+ }
+ }
+
+ free(label);
+}
+
+static int address_label_new_static(Network *network, const char *filename, unsigned section_line, AddressLabel **ret) {
+ _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
+ _cleanup_address_label_free_ AddressLabel *label = NULL;
+ int r;
+
+ assert(network);
+ assert(ret);
+ assert(!!filename == (section_line > 0));
+
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ label = hashmap_get(network->address_labels_by_section, n);
+ if (label) {
+ *ret = label;
+ label = NULL;
+
+ return 0;
+ }
+
+ r = address_label_new(&label);
+ if (r < 0)
+ return r;
+
+ label->section = n;
+ n = NULL;
+
+ r = hashmap_put(network->address_labels_by_section, label->section, label);
+ if (r < 0)
+ return r;
+
+ label->network = network;
+ LIST_APPEND(labels, network->address_labels, label);
+ network->n_address_labels++;
+
+ *ret = label;
+ label = NULL;
+
+ return 0;
+}
+
+int address_label_configure(
+ AddressLabel *label,
+ Link *link,
+ sd_netlink_message_handler_t callback,
+ bool update) {
+
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(label);
+ assert(link);
+ assert(link->ifindex > 0);
+ assert(link->manager);
+ assert(link->manager->rtnl);
+
+ r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL,
+ link->ifindex, AF_INET6);
+ if (r < 0)
+ return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m");
+
+ r = sd_rtnl_message_addrlabel_set_prefixlen(req, label->prefixlen);
+ if (r < 0)
+ return log_error_errno(r, "Could not set prefixlen: %m");
+
+ r = sd_netlink_message_append_u32(req, IFAL_LABEL, label->label);
+ if (r < 0)
+ return log_error_errno(r, "Could not append IFAL_LABEL attribute: %m");
+
+ r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr.in6);
+ if (r < 0)
+ return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m");
+
+ r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Could not send rtnetlink message: %m");
+
+ link_ref(link);
+
+ return 0;
+}
+
+int config_parse_address_label_prefix(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_address_label_free_ AddressLabel *n = NULL;
+ Network *network = userdata;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = address_label_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = in_addr_prefix_from_string(rvalue, AF_INET6, &n->in_addr, &n->prefixlen);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Address label is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ n = NULL;
+
+ return 0;
+}
+
+int config_parse_address_label(
+ 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_address_label_free_ AddressLabel *n = NULL;
+ Network *network = userdata;
+ uint32_t k;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = address_label_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address label, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ if (k == 0xffffffffUL) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Adress label is invalid, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ n->label = k;
+ n = NULL;
+
+ return 0;
+}
--- /dev/null
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Susant Sahani
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "in-addr-util.h"
+
+typedef struct AddressLabel AddressLabel;
+
+#include "networkd-link.h"
+#include "networkd-network.h"
+
+typedef struct Network Network;
+typedef struct Link Link;
+typedef struct NetworkConfigSection NetworkConfigSection;
+
+struct AddressLabel {
+ Network *network;
+ Link *link;
+ NetworkConfigSection *section;
+
+ unsigned char prefixlen;
+ uint32_t label;
+
+ union in_addr_union in_addr;
+
+ LIST_FIELDS(AddressLabel, labels);
+};
+
+int address_label_new(AddressLabel **ret);
+void address_label_free(AddressLabel *label);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(AddressLabel*, address_label_free);
+#define _cleanup_address_label_free_ _cleanup_(address_label_freep)
+
+int address_label_configure(AddressLabel *address, Link *link, sd_netlink_message_handler_t callback, bool update);
+
+int config_parse_address_label(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);
+int config_parse_address_label_prefix(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);
return !(a->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED));
}
+
+int config_parse_router_preference(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (streq(rvalue, "high"))
+ network->router_preference = SD_NDISC_PREFERENCE_HIGH;
+ else if (STR_IN_SET(rvalue, "medium", "normal", "default"))
+ network->router_preference = SD_NDISC_PREFERENCE_MEDIUM;
+ else if (streq(rvalue, "low"))
+ network->router_preference = SD_NDISC_PREFERENCE_LOW;
+ else
+ log_syntax(unit, LOG_ERR, filename, line, -EINVAL, "Router preference '%s' is invalid, ignoring assignment: %m", rvalue);
+
+ return 0;
+}
+
+void prefix_free(Prefix *prefix) {
+ if (!prefix)
+ return;
+
+ if (prefix->network) {
+ LIST_REMOVE(prefixes, prefix->network->static_prefixes, prefix);
+ assert(prefix->network->n_static_prefixes > 0);
+ prefix->network->n_static_prefixes--;
+
+ if (prefix->section)
+ hashmap_remove(prefix->network->prefixes_by_section,
+ prefix->section);
+ }
+
+ prefix->radv_prefix = sd_radv_prefix_unref(prefix->radv_prefix);
+
+ free(prefix);
+}
+
+int prefix_new(Prefix **ret) {
+ Prefix *prefix = NULL;
+
+ prefix = new0(Prefix, 1);
+ if (!prefix)
+ return -ENOMEM;
+
+ if (sd_radv_prefix_new(&prefix->radv_prefix) < 0)
+ return -ENOMEM;
+
+ *ret = prefix;
+ prefix = NULL;
+
+ return 0;
+}
+
+int prefix_new_static(Network *network, const char *filename,
+ unsigned section_line, Prefix **ret) {
+ _cleanup_network_config_section_free_ NetworkConfigSection *n = NULL;
+ _cleanup_prefix_free_ Prefix *prefix = NULL;
+ int r;
+
+ assert(network);
+ assert(ret);
+ assert(!!filename == (section_line > 0));
+
+ if (filename) {
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (section_line) {
+ prefix = hashmap_get(network->prefixes_by_section, n);
+ if (prefix) {
+ *ret = prefix;
+ prefix = NULL;
+
+ return 0;
+ }
+ }
+ }
+
+ r = prefix_new(&prefix);
+ if (r < 0)
+ return r;
+
+ if (filename) {
+ prefix->section = n;
+ n = NULL;
+
+ r = hashmap_put(network->prefixes_by_section, prefix->section,
+ prefix);
+ if (r < 0)
+ return r;
+ }
+
+ prefix->network = network;
+ LIST_APPEND(prefixes, network->static_prefixes, prefix);
+ network->n_static_prefixes++;
+
+ *ret = prefix;
+ prefix = NULL;
+
+ return 0;
+}
+
+int config_parse_prefix(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Network *network = userdata;
+ _cleanup_prefix_free_ Prefix *p = NULL;
+ uint8_t prefixlen = 64;
+ union in_addr_union in6addr;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = prefix_new_static(network, filename, section_line, &p);
+ if (r < 0)
+ return r;
+
+ r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ if (sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen) < 0)
+ return -EADDRNOTAVAIL;
+
+ log_syntax(unit, LOG_INFO, filename, line, r, "Found prefix %s", rvalue);
+
+ p = NULL;
+
+ return 0;
+}
+
+int config_parse_prefix_flags(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_prefix_free_ Prefix *p = NULL;
+ int r, val;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = prefix_new_static(network, filename, section_line, &p);
+ if (r < 0)
+ return r;
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address flag, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ val = r;
+
+ if (streq(lvalue, "OnLink"))
+ r = sd_radv_prefix_set_onlink(p->radv_prefix, val);
+ else if (streq(lvalue, "AddressAutoconfiguration"))
+ r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, val);
+ if (r < 0)
+ return r;
+
+ p = NULL;
+
+ return 0;
+}
+
+int config_parse_prefix_lifetime(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_prefix_free_ Prefix *p = NULL;
+ usec_t usec;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = prefix_new_static(network, filename, section_line, &p);
+ if (r < 0)
+ return r;
+
+ r = parse_sec(rvalue, &usec);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ /* a value of 0xffffffff represents infinity */
+ if (streq(lvalue, "PreferredLifetimeSec"))
+ r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix,
+ DIV_ROUND_UP(usec, USEC_PER_SEC));
+ else if (streq(lvalue, "ValidLifetimeSec"))
+ r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix,
+ DIV_ROUND_UP(usec, USEC_PER_SEC));
+ if (r < 0)
+ return r;
+
+ p = NULL;
+
+ return 0;
+};
#include "in-addr-util.h"
typedef struct Address Address;
+typedef struct Prefix Prefix;
#include "networkd-link.h"
#include "networkd-network.h"
typedef struct Link Link;
typedef struct NetworkConfigSection NetworkConfigSection;
+struct Prefix {
+ Network *network;
+ NetworkConfigSection *section;
+
+ sd_radv_prefix *radv_prefix;
+
+ LIST_FIELDS(Prefix, prefixes);
+};
+
struct Address {
Network *network;
NetworkConfigSection *section;
DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
#define _cleanup_address_free_ _cleanup_(address_freep)
+int prefix_new(Prefix **ret);
+void prefix_free(Prefix *prefix);
+int prefix_new_static(Network *network, const char *filename, unsigned section,
+ Prefix **ret);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Prefix*, prefix_free);
+#define _cleanup_prefix_free_ _cleanup_(prefix_freep)
+
int config_parse_address(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);
int config_parse_broadcast(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);
int config_parse_label(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);
int config_parse_lifetime(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);
int config_parse_address_flags(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);
+int config_parse_router_preference(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);
+int config_parse_prefix(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);
+int config_parse_prefix_flags(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);
+int config_parse_prefix_lifetime(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);
assert(m);
return config_parse_many_nulstr(PKGSYSCONFDIR "/networkd.conf",
- CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
- "DHCP\0",
- config_item_perf_lookup, networkd_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/networkd.conf.d"),
+ "DHCP\0",
+ config_item_perf_lookup, networkd_gperf_lookup,
+ false, m);
}
static const char* const duid_type_table[_DUID_TYPE_MAX] = {
return 1;
}
+static int route_scope_from_address(const Route *route, const struct in_addr *self_addr) {
+ assert(route);
+ assert(self_addr);
+
+ if (in_addr_is_localhost(AF_INET, &route->dst) ||
+ (self_addr->s_addr && route->dst.in.s_addr == self_addr->s_addr))
+ return RT_SCOPE_HOST;
+ else if (in4_addr_is_null(&route->gw.in))
+ return RT_SCOPE_LINK;
+ else
+ return RT_SCOPE_UNIVERSE;
+}
+
static int link_set_dhcp_routes(Link *link) {
- struct in_addr gateway;
+ struct in_addr gateway, address;
_cleanup_free_ sd_dhcp_route **static_routes = NULL;
int r, n, i;
if (!link->network->dhcp_use_routes)
return 0;
+ r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
+
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
if (r < 0 && r != -ENODATA)
return log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
if (r >= 0) {
- struct in_addr address;
_cleanup_route_free_ Route *route = NULL;
_cleanup_route_free_ Route *route_gw = NULL;
- r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
- if (r < 0)
- return log_link_warning_errno(link, r, "DHCP error: could not get address: %m");
-
r = route_new(&route);
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate route: %m");
assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0);
route->priority = link->network->dhcp_route_metric;
route->table = link->network->dhcp_route_table;
+ route->scope = route_scope_from_address(route, &address);
r = route_configure(route, link, dhcp4_route_handler);
if (r < 0)
link->ipv4ll_address = true;
- if (link->ipv4ll_route == true)
+ if (link->ipv4ll_route)
link_check_ready(link);
return 1;
switch(event) {
case SD_IPV4LL_EVENT_STOP:
+ r = ipv4ll_address_lost(link);
+ if (r < 0) {
+ link_enter_failed(link);
+ return;
+ }
+ break;
case SD_IPV4LL_EVENT_CONFLICT:
r = ipv4ll_address_lost(link);
if (r < 0) {
link_enter_failed(link);
return;
}
+
+ r = sd_ipv4ll_restart(ll);
+ if (r < 0)
+ log_link_warning(link, "Could not acquire IPv4 link-local address");
break;
case SD_IPV4LL_EVENT_BIND:
r = ipv4ll_address_claimed(ll, link);
if (!link->network)
return false;
+ if (link->network->ipv6_proxy_ndp != -1)
+ return link->network->ipv6_proxy_ndp;
+
if (link->network->n_ipv6_proxy_ndp_addresses == 0)
return false;
#include "networkd-lldp-tx.h"
#include "networkd-manager.h"
#include "networkd-ndisc.h"
+#include "networkd-radv.h"
#include "set.h"
#include "socket-util.h"
#include "stdio-util.h"
return link_ipv6ll_enabled(link) || network_has_static_ipv6_addresses(link->network);
}
+static bool link_radv_enabled(Link *link) {
+ assert(link);
+
+ if (!link_ipv6ll_enabled(link))
+ return false;
+
+ return link->network->router_prefix_delegation;
+}
+
static bool link_lldp_rx_enabled(Link *link) {
assert(link);
if (!link->network)
return false;
- if (link->network->bridge)
+ /* LLDP should be handled on bridge slaves as those have a direct
+ * connection to their peers not on the bridge master. Linux doesn't
+ * even (by default) forward lldp packets to the bridge master.*/
+ if (streq_ptr("bridge", link->kind))
return false;
return link->network->lldp_mode != LLDP_MODE_NO;
sd_ipv4ll_unref(link->ipv4ll);
sd_dhcp6_client_unref(link->dhcp6_client);
sd_ndisc_unref(link->ndisc);
+ sd_radv_unref(link->radv);
if (link->manager)
hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex));
r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
}
+ if (link->radv) {
+ k = sd_radv_stop(link->radv);
+ if (k < 0)
+ r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
+ }
+
link_lldp_emit_stop(link);
return r;
}
return 1;
}
+static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
+ _cleanup_link_unref_ Link *link = userdata;
+ int r;
+
+ assert(rtnl);
+ assert(m);
+ assert(link);
+ assert(link->ifname);
+ assert(link->link_messages > 0);
+
+ link->link_messages--;
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST)
+ log_link_warning_errno(link, r, "could not set address label: %m");
+ else if (r >= 0)
+ manager_rtnl_process_address(rtnl, m, link->manager);
+
+ if (link->link_messages == 0) {
+ log_link_debug(link, "Addresses label set");
+ link_enter_set_routes(link);
+ }
+
+ return 1;
+}
+
static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
}
static int link_enter_set_addresses(Link *link) {
+ AddressLabel *label;
Address *ad;
int r;
link->link_messages++;
}
+ LIST_FOREACH(labels, label, link->network->address_labels) {
+ r = address_label_configure(label, link, address_label_handler, false);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Could not set address label: %m");
+ link_enter_failed(link);
+ return r;
+ }
+
+ link->link_messages++;
+ }
+
/* now that we can figure out a default address for the dhcp server,
start it */
if (link_dhcp4_server_enabled(link)) {
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_COST attribute: %m");
}
+ if (link->network->priority != LINK_BRIDGE_PORT_PRIORITY_INVALID) {
+ r = sd_netlink_message_append_u16(req, IFLA_BRPORT_PRIORITY, link->network->priority);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_BRPORT_PRIORITY attribute: %m");
+ }
r = sd_netlink_message_close_container(req);
if (r < 0)
return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
}
+ if (link_radv_enabled(link)) {
+ assert(link->radv);
+ assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
+
+ log_link_debug(link, "Starting IPv6 Router Advertisements");
+
+ r = sd_radv_start(link->radv);
+ if (r < 0 && r != -EBUSY)
+ return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
+ }
+
return 0;
}
return 1;
}
-static int link_up(Link *link) {
+int link_up(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
uint8_t ipv6ll_mode;
int r;
return 1;
}
-static int link_down(Link *link) {
+int link_down(Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
log_link_error_errno(link, r, "Could not set bridge vlan: %m");
}
+ /* Skip setting up addresses until it gets carrier,
+ or it would try to set addresses twice,
+ which is bad for non-idempotent steps. */
+ if (!link_has_carrier(link))
+ return 0;
+
return link_enter_set_addresses(link);
}
}
static int link_drop_config(Link *link) {
- Address *address;
+ Address *address, *pool_address;
Route *route;
Iterator i;
int r;
r = address_remove(address, link, link_address_remove_handler);
if (r < 0)
return r;
+
+ /* If this address came from an address pool, clean up the pool */
+ LIST_FOREACH(addresses, pool_address, link->pool_addresses) {
+ if (address_equal(address, pool_address)) {
+ LIST_REMOVE(addresses, link->pool_addresses, pool_address);
+ address_free(pool_address);
+ break;
+ }
+ }
}
SET_FOREACH(route, link->routes, i) {
return r;
}
+ if (link_radv_enabled(link)) {
+ r = radv_configure(link);
+ if (r < 0)
+ return r;
+ }
+
if (link_lldp_rx_enabled(link)) {
r = sd_lldp_new(&link->lldp);
if (r < 0)
return r;
}
+ (void) sd_dhcp_server_stop(link->dhcp_server);
+
r = link_drop_config(link);
if (r < 0)
return r;
return r;
}
}
+
+ if (link->radv) {
+ r = sd_radv_set_mtu(link->radv, link->mtu);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not set MTU for Router Advertisement: %m");
+ }
}
/* The kernel may broadcast NEWLINK messages without the MAC address
if (r < 0)
return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
}
+
+ if (link->radv) {
+ r = sd_radv_set_mac(link->radv, &link->mac);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Could not update MAC for Router Advertisement: %m");
+ }
}
}
sd_dhcp6_lease *dhcp6_lease = NULL;
const char *dhcp_domainname = NULL;
char **dhcp6_domains = NULL;
+ char **dhcp_domains = NULL;
unsigned j;
if (link->dhcp6_client) {
fputc('\n', f);
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
- if (link->dhcp_lease)
+ if (link->dhcp_lease) {
(void) sd_dhcp_lease_get_domainname(link->dhcp_lease, &dhcp_domainname);
+ (void) sd_dhcp_lease_get_search_domains(link->dhcp_lease, &dhcp_domains);
+ }
if (dhcp6_lease)
(void) sd_dhcp6_lease_get_domains(dhcp6_lease, &dhcp6_domains);
}
fputs("DOMAINS=", f);
+ space = false;
fputstrv(f, link->network->search_domains, NULL, &space);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) {
if (dhcp_domainname)
fputs_with_space(f, dhcp_domainname, NULL, &space);
+ if (dhcp_domains)
+ fputstrv(f, dhcp_domains, NULL, &space);
if (dhcp6_domains)
fputstrv(f, dhcp6_domains, NULL, &space);
fputc('\n', f);
fputs("ROUTE_DOMAINS=", f);
- fputstrv(f, link->network->route_domains, NULL, NULL);
+ space = false;
+ fputstrv(f, link->network->route_domains, NULL, &space);
if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_ROUTE) {
NDiscDNSSL *dd;
if (dhcp_domainname)
fputs_with_space(f, dhcp_domainname, NULL, &space);
+ if (dhcp_domains)
+ fputstrv(f, dhcp_domains, NULL, &space);
if (dhcp6_domains)
fputstrv(f, dhcp6_domains, NULL, &space);
#include "sd-ipv4ll.h"
#include "sd-lldp.h"
#include "sd-ndisc.h"
+#include "sd-radv.h"
#include "sd-netlink.h"
#include "list.h"
Set *ndisc_rdnss;
Set *ndisc_dnssl;
+ sd_radv *radv;
+
sd_dhcp6_client *dhcp6_client;
bool rtnl_extended_attrs;
int link_add(Manager *manager, sd_netlink_message *message, Link **ret);
void link_drop(Link *link);
+int link_up(Link *link);
+int link_down(Link *link);
+
int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata);
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
const char *domainname;
+ char **domains = NULL;
+ OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
if (r >= 0) {
+ r = ordered_set_put_strdup(target_domains, domainname);
+ if (r < 0)
+ return r;
+ } else if (r != -ENODATA)
+ return r;
- if (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES)
- r = ordered_set_put_strdup(search_domains, domainname);
- else
- r = ordered_set_put_strdup(route_domains, domainname);
-
+ r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
+ if (r >= 0) {
+ r = ordered_set_put_strdupv(target_domains, domains);
if (r < 0)
return r;
} else if (r != -ENODATA)
#define NDISC_DNSSL_MAX 64U
#define NDISC_RDNSS_MAX 64U
+#define NDISC_PREFIX_LFT_MIN 7200U
static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
static void ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
_cleanup_address_free_ Address *address = NULL;
- uint32_t lifetime_valid, lifetime_preferred;
+ Address *existing_address;
+ uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
+ usec_t time_now;
unsigned prefixlen;
int r;
assert(link);
assert(rt);
+ r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
+ if (r < 0) {
+ log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
+ return;
+ }
+
r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
if (r < 0) {
log_link_error_errno(link, r, "Failed to get prefix length: %m");
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
address->cinfo.ifa_prefered = lifetime_preferred;
- address->cinfo.ifa_valid = lifetime_valid;
+
+ /* see RFC4862 section 5.5.3.e */
+ r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address);
+ if (r > 0) {
+ lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC;
+ if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining)
+ address->cinfo.ifa_valid = lifetime_valid;
+ else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN)
+ address->cinfo.ifa_valid = lifetime_remaining;
+ else
+ address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
+ } else if (lifetime_valid > 0)
+ address->cinfo.ifa_valid = lifetime_valid;
+ else
+ return; /* see RFC4862 section 5.5.3.d */
+
+ if (address->cinfo.ifa_valid == 0)
+ return;
r = address_configure(address, link, ndisc_netlink_handler, true);
if (r < 0) {
Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
Network.IPv6DuplicateAddressDetection, config_parse_int, 0, offsetof(Network, ipv6_dad_transmits)
Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit)
+Network.IPv6ProxyNDP, config_parse_tristate, 0, offsetof(Network, ipv6_proxy_ndp)
Network.ActiveSlave, config_parse_bool, 0, offsetof(Network, active_slave)
Network.PrimarySlave, config_parse_bool, 0, offsetof(Network, primary_slave)
Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
Address.ManageTemporaryAddress, config_parse_address_flags, 0, 0
Address.PrefixRoute, config_parse_address_flags, 0, 0
Address.AutoJoin, config_parse_address_flags, 0, 0
+IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0
+IPv6AddressLabel.Label, config_parse_address_label, 0, 0
Route.Gateway, config_parse_gateway, 0, 0
Route.Destination, config_parse_destination, 0, 0
Route.Source, config_parse_destination, 0, 0
Route.Scope, config_parse_route_scope, 0, 0
Route.PreferredSource, config_parse_preferred_src, 0, 0
Route.Table, config_parse_route_table, 0, 0
+Route.GatewayOnlink, config_parse_gateway_onlink, 0, 0
+Route.IPv6Preference, config_parse_ipv6_route_preference, 0, 0
+Route.Protocol, config_parse_route_protocol, 0, 0
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_use_ntp)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)
DHCPServer.PoolSize, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_size)
-Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost)
+Bridge.Cost, config_parse_uint32, 0, offsetof(Network, cost)
Bridge.UseBPDU, config_parse_bool, 0, offsetof(Network, use_bpdu)
Bridge.HairPin, config_parse_bool, 0, offsetof(Network, hairpin)
Bridge.FastLeave, config_parse_bool, 0, offsetof(Network, fast_leave)
Bridge.AllowPortToBeRoot, config_parse_bool, 0, offsetof(Network, allow_port_to_be_root)
Bridge.UnicastFlood, config_parse_bool, 0, offsetof(Network, unicast_flood)
+Bridge.Priority, config_parse_bridge_port_priority, 0, offsetof(Network, priority)
BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0
BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
+Network.IPv6PrefixDelegation, config_parse_bool, 0, offsetof(Network, router_prefix_delegation)
+IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
+IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
+IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
+IPv6PrefixDelegation.RouterPreference, config_parse_router_preference, 0, 0
+IPv6Prefix.Prefix, config_parse_prefix, 0, 0
+IPv6Prefix.OnLink, config_parse_prefix_flags, 0, 0
+IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags, 0, 0
+IPv6Prefix.ValidLifetimeSec, config_parse_prefix_lifetime, 0, 0
+IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, 0, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
LIST_HEAD_INIT(network->static_routes);
LIST_HEAD_INIT(network->static_fdb_entries);
LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses);
+ LIST_HEAD_INIT(network->address_labels);
+ LIST_HEAD_INIT(network->static_prefixes);
network->stacked_netdevs = hashmap_new(&string_hash_ops);
if (!network->stacked_netdevs)
if (!network->fdb_entries_by_section)
return log_oom();
+ network->address_labels_by_section = hashmap_new(&network_config_hash_ops);
+ if (!network->address_labels_by_section)
+ log_oom();
+
+ network->prefixes_by_section = hashmap_new(&network_config_hash_ops);
+ if (!network->prefixes_by_section)
+ return log_oom();
+
network->filename = strdup(filename);
if (!network->filename)
return log_oom();
network->use_bpdu = true;
network->allow_port_to_be_root = true;
network->unicast_flood = true;
+ network->priority = LINK_BRIDGE_PORT_PRIORITY_INVALID;
network->lldp_mode = LLDP_MODE_ROUTERS_ONLY;
network->ipv6_accept_ra = -1;
network->ipv6_dad_transmits = -1;
network->ipv6_hop_limit = -1;
+ network->ipv6_proxy_ndp = -1;
network->duid.type = _DUID_TYPE_INVALID;
network->proxy_arp = -1;
network->arp = -1;
"Link\0"
"Network\0"
"Address\0"
+ "IPv6AddressLabel\0"
"Route\0"
"DHCP\0"
"DHCPv4\0" /* compat */
"IPv6NDPProxyAddress\0"
"Bridge\0"
"BridgeFDB\0"
- "BridgeVLAN\0",
+ "BridgeVLAN\0"
+ "IPv6PrefixDelegation\0"
+ "IPv6Prefix\0",
config_item_perf_lookup, network_network_gperf_lookup,
false, network);
if (r < 0)
Address *address;
FdbEntry *fdb_entry;
IPv6ProxyNDPAddress *ipv6_proxy_ndp_address;
+ AddressLabel *label;
+ Prefix *prefix;
Iterator i;
if (!network)
while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses))
ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address);
+ while ((label = network->address_labels))
+ address_label_free(label);
+
+ while ((prefix = network->static_prefixes))
+ prefix_free(prefix);
+
hashmap_free(network->addresses_by_section);
hashmap_free(network->routes_by_section);
hashmap_free(network->fdb_entries_by_section);
+ hashmap_free(network->address_labels_by_section);
+ hashmap_free(network->prefixes_by_section);
if (network->manager) {
if (network->manager->networks)
if (network->ipv4ll_route) {
Route *route;
- r = route_new_static(network, "Network", 0, &route);
+ r = route_new_static(network, NULL, 0, &route);
if (r < 0)
return r;
#include "resolve-util.h"
#include "networkd-address.h"
+#include "networkd-address-label.h"
#include "networkd-brvlan.h"
#include "networkd-fdb.h"
#include "networkd-lldp-tx.h"
AddressFamilyBoolean link_local;
bool ipv4ll_route;
+ /* IPv6 prefix delegation support */
+ bool router_prefix_delegation;
+ usec_t router_lifetime_usec;
+ uint8_t router_preference;
+ bool router_managed;
+ bool router_other_information;
+
/* Bridge Support */
bool use_bpdu;
bool hairpin;
bool fast_leave;
bool allow_port_to_be_root;
bool unicast_flood;
- unsigned cost;
+ uint32_t cost;
+ uint16_t priority;
bool use_br_vlan;
uint16_t pvid;
int ipv6_accept_ra;
int ipv6_dad_transmits;
int ipv6_hop_limit;
+ int ipv6_proxy_ndp;
int proxy_arp;
bool ipv6_accept_ra_use_dns;
LIST_HEAD(Route, static_routes);
LIST_HEAD(FdbEntry, static_fdb_entries);
LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses);
+ LIST_HEAD(AddressLabel, address_labels);
+ LIST_HEAD(Prefix, static_prefixes);
unsigned n_static_addresses;
unsigned n_static_routes;
unsigned n_static_fdb_entries;
unsigned n_ipv6_proxy_ndp_addresses;
+ unsigned n_address_labels;
+ unsigned n_static_prefixes;
Hashmap *addresses_by_section;
Hashmap *routes_by_section;
Hashmap *fdb_entries_by_section;
+ Hashmap *address_labels_by_section;
+ Hashmap *prefixes_by_section;
struct in_addr_data *dns;
unsigned n_dns;
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/icmp6.h>
+#include <arpa/inet.h>
+
+#include "networkd-address.h"
+#include "networkd-radv.h"
+#include "sd-radv.h"
+
+int radv_configure(Link *link) {
+ int r;
+ Prefix *p;
+
+ assert(link);
+ assert(link->network);
+
+ r = sd_radv_new(&link->radv);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_attach_event(link->radv, NULL, 0);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_mac(link->radv, &link->mac);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_ifindex(link->radv, link->ifindex);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_managed_information(link->radv, link->network->router_managed);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_set_other_information(link->radv, link->network->router_other_information);
+ if (r < 0)
+ return r;
+
+ /* a value of 0xffffffff represents infinity, 0x0 means this host is
+ not a router */
+ r = sd_radv_set_router_lifetime(link->radv,
+ DIV_ROUND_UP(link->network->router_lifetime_usec, USEC_PER_SEC));
+ if (r < 0)
+ return r;
+
+ if (link->network->router_lifetime_usec > 0) {
+ r = sd_radv_set_preference(link->radv,
+ link->network->router_preference);
+ if (r < 0)
+ return r;
+ }
+
+ LIST_FOREACH(prefixes, p, link->network->static_prefixes) {
+ r = sd_radv_add_prefix(link->radv, p->radv_prefix);
+ if (r != -EEXIST && r < 0)
+ return r;
+ }
+
+ return 0;
+}
--- /dev/null
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Intel Corporation. All rights reserved.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "networkd-link.h"
+
+int radv_configure(Link *link);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <linux/icmpv6.h>
+
#include "alloc-util.h"
#include "conf-parser.h"
#include "in-addr-util.h"
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
Route route, *existing;
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
_cleanup_route_free_ Route *route = NULL;
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
return route_add_internal(link, &link->routes_foreign, family, dst, dst_prefixlen, tos, priority, table, ret);
unsigned char dst_prefixlen,
unsigned char tos,
uint32_t priority,
- unsigned char table,
+ uint32_t table,
Route **ret) {
Route *route;
Network *network = userdata;
_cleanup_route_free_ Route *n = NULL;
- const char *address, *e;
union in_addr_union buffer;
unsigned char prefixlen;
- int r, f;
+ int r;
assert(filename);
assert(section);
if (r < 0)
return r;
- /* Destination|Source=address/prefixlen */
-
- /* address */
- e = strchr(rvalue, '/');
- if (e)
- address = strndupa(rvalue, e - rvalue);
- else
- address = rvalue;
-
- r = in_addr_from_string_auto(address, &f, &buffer);
+ r = in_addr_prefix_from_string(rvalue, AF_INET, &buffer, &prefixlen);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Destination is invalid, ignoring assignment: %s", address);
- return 0;
- }
-
- if (f != AF_INET && f != AF_INET6) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown address family, ignoring assignment: %s", address);
- return 0;
- }
-
- /* prefixlen */
- if (e) {
- r = safe_atou8(e + 1, &prefixlen);
+ r = in_addr_prefix_from_string(rvalue, AF_INET6, &buffer, &prefixlen);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Route destination prefix length is invalid, ignoring assignment: %s", e + 1);
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Route %s= prefix is invalid, ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
- } else {
- switch (f) {
- case AF_INET:
- prefixlen = 32;
- break;
- case AF_INET6:
- prefixlen = 128;
- break;
- }
- }
- n->family = f;
+ n->family = AF_INET6;
+ } else
+ n->family = AF_INET;
+
if (streq(lvalue, "Destination")) {
n->dst = buffer;
n->dst_prefixlen = prefixlen;
return 0;
}
+
+int config_parse_gateway_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) {
+ Network *network = userdata;
+ _cleanup_route_free_ Route *n = NULL;
+ int r;
+
+ assert(filename);
+ assert(section);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Could not parse gateway onlink \"%s\", ignoring assignment: %m", rvalue);
+ return 0;
+ }
+
+ SET_FLAG(n->flags, RTNH_F_ONLINK, r);
+ n = NULL;
+
+ return 0;
+}
+
+int config_parse_ipv6_route_preference(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_route_free_ Route *n = NULL;
+ int r;
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (streq(rvalue, "low"))
+ n->pref = ICMPV6_ROUTER_PREF_LOW;
+ else if (streq(rvalue, "medium"))
+ n->pref = ICMPV6_ROUTER_PREF_MEDIUM;
+ else if (streq(rvalue, "high"))
+ n->pref = ICMPV6_ROUTER_PREF_HIGH;
+ else {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown route preference: %s", rvalue);
+ return 0;
+ }
+
+ n = NULL;
+
+ return 0;
+}
+
+int config_parse_route_protocol(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Network *network = userdata;
+ _cleanup_route_free_ Route *n = NULL;
+ int r;
+
+ r = route_new_static(network, filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ if (streq(rvalue, "kernel"))
+ n->protocol = RTPROT_KERNEL;
+ else if (streq(rvalue, "boot"))
+ n->protocol = RTPROT_BOOT;
+ else if (streq(rvalue, "static"))
+ n->protocol = RTPROT_STATIC;
+ else {
+ r = safe_atou8(rvalue , &n->protocol);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Could not parse route protocol \"%s\", ignoring assignment: %m", rvalue);
+ return 0;
+ }
+ }
+
+ n = NULL;
+
+ return 0;
+}
int route_configure(Route *route, Link *link, sd_netlink_message_handler_t callback);
int route_remove(Route *route, Link *link, sd_netlink_message_handler_t callback);
-int route_get(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
-int route_add(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
-int route_add_foreign(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, unsigned char table, Route **ret);
+int route_get(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
+int route_add(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
+int route_add_foreign(Link *link, int family, const union in_addr_union *dst, unsigned char dst_prefixlen, unsigned char tos, uint32_t priority, uint32_t table, Route **ret);
int route_update(Route *route, const union in_addr_union *src, unsigned char src_prefixlen, const union in_addr_union *gw, const union in_addr_union *prefsrc, unsigned char scope, unsigned char protocol);
int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdata);
int config_parse_route_priority(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);
int config_parse_route_scope(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);
int config_parse_route_table(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);
+int config_parse_gateway_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);
+int config_parse_ipv6_route_preference(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);
+int config_parse_route_protocol(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);
--- /dev/null
+systemd_nspawn_sources = files('''
+ nspawn.c
+ nspawn-settings.c
+ nspawn-settings.h
+ nspawn-mount.c
+ nspawn-mount.h
+ nspawn-network.c
+ nspawn-network.h
+ nspawn-expose-ports.c
+ nspawn-expose-ports.h
+ nspawn-cgroup.c
+ nspawn-cgroup.h
+ nspawn-seccomp.c
+ nspawn-seccomp.h
+ nspawn-register.c
+ nspawn-register.h
+ nspawn-setuid.c
+ nspawn-setuid.h
+ nspawn-stub-pid1.c
+ nspawn-stub-pid1.h
+ nspawn-patch-uid.c
+ nspawn-patch-uid.h
+'''.split())
+
+nspawn_gperf_c = custom_target(
+ 'nspawn-gperf.c',
+ input : 'nspawn-gperf.gperf',
+ output : 'nspawn-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_nspawn_sources += [nspawn_gperf_c]
+
+tests += [
+ [['src/nspawn/test-patch-uid.c',
+ 'src/nspawn/nspawn-patch-uid.c',
+ 'src/nspawn/nspawn-patch-uid.h'],
+ [libshared],
+ [libacl],
+ '', 'manual'],
+]
"cgroup.subtree_control")
if (fchownat(fd, fn, uid_shift, uid_shift, 0) < 0)
log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
- "Failed to chown() cgroup file %s, ignoring: %m", fn);
+ "Failed to chown \"%s/%s\", ignoring: %m", path, fn);
return 0;
}
{ NULL, "/proc/sysrq-trigger", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, MOUNT_IN_USERNS|MOUNT_APPLY_APIVFS_RO }, /* ... then, make it r/o */
/* outer child mounts */
- { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_STRICTATIME, MOUNT_FATAL },
+ { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, MOUNT_FATAL },
{ "tmpfs", "/sys", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_APPLY_APIVFS_NETNS },
{ "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL|MOUNT_APPLY_APIVFS_RO }, /* skipped if above was mounted */
{ "sysfs", "/sys", "sysfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, MOUNT_FATAL }, /* skipped if above was mounted */
#include <linux/veth.h>
#include <net/if.h>
+#include <sys/file.h>
#include "libudev.h"
#include "sd-id128.h"
#include "strv.h"
#include "util.h"
+static int append_machine_properties(
+ sd_bus_message *m,
+ CustomMount *mounts,
+ unsigned n_mounts,
+ int kill_signal,
+ char **properties) {
+
+ unsigned j;
+ int r;
+
+ assert(m);
+
+ r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* If you make changes here, also make sure to update systemd-nspawn@.service, to keep the device policies in
+ * sync regardless if we are run with or without the --keep-unit switch. */
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
+ /* Allow the container to
+ * access and create the API
+ * device nodes, so that
+ * PrivateDevices= in the
+ * container can work
+ * fine */
+ "/dev/net/tun", "rwm",
+ /* Allow the container
+ * access to ptys. However,
+ * do not permit the
+ * container to ever create
+ * these device nodes. */
+ "char-pts", "rw");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ for (j = 0; j < n_mounts; j++) {
+ CustomMount *cm = mounts + j;
+
+ if (cm->type != CUSTOM_MOUNT_BIND)
+ continue;
+
+ r = is_device_node(cm->source);
+ if (r == -ENOENT) {
+ /* The bind source might only appear as the image is put together, hence don't complain */
+ log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
+ continue;
+ }
+ if (r < 0)
+ return log_error_errno(r, "Failed to stat %s: %m", cm->source);
+
+ if (r) {
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
+ cm->source, cm->read_only ? "r" : "rw");
+ if (r < 0)
+ return log_error_errno(r, "Failed to append message arguments: %m");
+ }
+ }
+
+ if (kill_signal != 0) {
+ r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ return 0;
+}
+
int register_machine(
const char *machine_name,
pid_t pid,
local_ifindex > 0 ? 1 : 0, local_ifindex);
} else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- unsigned j;
r = sd_bus_message_new_method_call(
bus,
return bus_log_create_error(r);
}
- r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
- if (r < 0)
- return bus_log_create_error(r);
-
- /* If you make changes here, also make sure to update
- * systemd-nspawn@.service, to keep the device
- * policies in sync regardless if we are run with or
- * without the --keep-unit switch. */
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
- /* Allow the container to
- * access and create the API
- * device nodes, so that
- * PrivateDevices= in the
- * container can work
- * fine */
- "/dev/net/tun", "rwm",
- /* Allow the container
- * access to ptys. However,
- * do not permit the
- * container to ever create
- * these device nodes. */
- "char-pts", "rw");
+ r = append_machine_properties(
+ m,
+ mounts,
+ n_mounts,
+ kill_signal,
+ properties);
if (r < 0)
- return bus_log_create_error(r);
-
- for (j = 0; j < n_mounts; j++) {
- CustomMount *cm = mounts + j;
-
- if (cm->type != CUSTOM_MOUNT_BIND)
- continue;
-
- r = is_device_node(cm->source);
- if (r == -ENOENT) {
- /* The bind source might only appear as the image is put together, hence don't complain */
- log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
- continue;
- }
- if (r < 0)
- return log_error_errno(r, "Failed to stat %s: %m", cm->source);
-
- if (r) {
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
- cm->source, cm->read_only ? "r" : "rw");
- if (r < 0)
- return log_error_errno(r, "Failed to append message arguments: %m");
- }
- }
-
- if (kill_signal != 0) {
- r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
- if (r < 0)
- return bus_log_create_error(r);
- }
+ return r;
r = bus_append_unit_property_assignment_many(m, properties);
if (r < 0)
return 0;
}
+
+int allocate_scope(
+ const char *machine_name,
+ pid_t pid,
+ const char *slice,
+ CustomMount *mounts,
+ unsigned n_mounts,
+ int kill_signal,
+ char **properties) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
+ _cleanup_free_ char *scope = NULL;
+ const char *description, *object;
+ int r;
+
+ r = sd_bus_default_system(&bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to open system bus: %m");
+
+ r = bus_wait_for_jobs_new(bus, &w);
+ if (r < 0)
+ return log_error_errno(r, "Could not watch job: %m");
+
+ r = unit_name_mangle_with_suffix(machine_name, UNIT_NAME_NOGLOB, ".scope", &scope);
+ if (r < 0)
+ return log_error_errno(r, "Failed to mangle scope name: %m");
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ss", scope, "fail");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* Properties */
+ r = sd_bus_message_open_container(m, 'a', "(sv)");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ description = strjoina("Container ", machine_name);
+
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
+ "PIDs", "au", 1, pid,
+ "Description", "s", description,
+ "Delegate", "b", 1,
+ "Slice", "s", isempty(slice) ? "machine.slice" : slice);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = append_machine_properties(
+ m,
+ mounts,
+ n_mounts,
+ kill_signal,
+ properties);
+ if (r < 0)
+ return r;
+
+ r = bus_append_unit_property_assignment_many(m, properties);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* No auxiliary units */
+ r = sd_bus_message_append(
+ m,
+ "a(sa(sv))",
+ 0);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0) {
+ log_error("Failed to allocate scope: %s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = sd_bus_message_read(reply, "o", &object);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = bus_wait_for_jobs_one(w, object, false);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
int register_machine(const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit, const char *service);
int terminate_machine(pid_t pid);
+
+int allocate_scope(const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties);
***/
#include <sys/reboot.h>
-#include <sys/unistd.h>
#include <sys/wait.h>
#include <sys/prctl.h>
+#include <unistd.h>
#include "fd-util.h"
#include "log.h"
else
assert_not_reached("Got unexpected signal");
- /* (void) kill_and_sigcont(pid, SIGTERM); */
+ r = kill_and_sigcont(pid, SIGTERM);
+
+ /* Let's send a SIGHUP after the SIGTERM, as shells tend to ignore SIGTERM but do react to SIGHUP. We
+ * do it strictly in this order, so that the SIGTERM is dispatched first, and SIGHUP second for those
+ * processes which handle both. That's because services tend to bind configuration reload or something
+ * else to SIGHUP. */
+
+ if (r != -ESRCH)
+ (void) kill(pid, SIGHUP);
+
quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
}
***/
#ifdef HAVE_BLKID
-#include <blkid/blkid.h>
+#include <blkid.h>
#endif
#include <errno.h>
#include <getopt.h>
if (r < 0) {
log_warning_errno(r, "Failed to parse SYSTEMD_NSPAWN_API_VFS_WRITABLE from environment, ignoring.");
return;
- } else if (r > 0)
- arg_mount_settings &= ~MOUNT_APPLY_APIVFS_RO;
- else
- arg_mount_settings |= MOUNT_APPLY_APIVFS_RO;
+ }
- arg_mount_settings &= ~MOUNT_APPLY_APIVFS_NETNS;
+ SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_RO, r == 0);
+ SET_FLAG(arg_mount_settings, MOUNT_APPLY_APIVFS_NETNS, false);
}
static int parse_argv(int argc, char *argv[]) {
if (arg_userns_mode == USER_NAMESPACE_PICK)
arg_userns_chown = true;
- if (arg_keep_unit && cg_pid_get_owner_uid(0, NULL) >= 0) {
- log_error("--keep-unit may not be used when invoked from a user session.");
+ if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0) {
+ log_error("--keep-unit --register=yes may not be used when invoked from a user session.");
return -EINVAL;
}
arg_caps_retain = (arg_caps_retain | plus | (arg_private_network ? 1ULL << CAP_NET_ADMIN : 0)) & ~minus;
+ r = cg_unified_flush();
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m");
+
e = getenv("SYSTEMD_NSPAWN_CONTAINER_SERVICE");
if (e)
arg_container_service_name = e;
return 0;
}
-static int resolved_running(void) {
+static int resolved_listening(void) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ char *dns_stub_listener_mode = NULL;
int r;
- /* Check if resolved is running */
+ /* Check if resolved is listening */
r = sd_bus_open_system(&bus);
if (r < 0)
return r;
- return bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+ r = bus_name_has_owner(bus, "org.freedesktop.resolve1", NULL);
+ if (r <= 0)
+ return r;
+
+ r = sd_bus_get_property_string(bus,
+ "org.freedesktop.resolve1",
+ "/org/freedesktop/resolve1",
+ "org.freedesktop.resolve1.Manager",
+ "DNSStubListener",
+ NULL,
+ &dns_stub_listener_mode);
+ if (r < 0)
+ return r;
+
+ return STR_IN_SET(dns_stub_listener_mode, "udp", "yes");
}
static int setup_resolv_conf(const char *dest) {
}
if (access("/usr/lib/systemd/resolv.conf", F_OK) >= 0 &&
- resolved_running() > 0) {
+ resolved_listening() > 0) {
/* resolved is enabled on the host. In this, case bind mount its static resolv.conf file into the
* container, so that the container can use the host's resolver. Given that network namespacing is
if (r < 0)
return log_error_errno(r, "Failed to find image for machine '%s': %m", arg_machine);
if (r == 0) {
- log_error("No image for machine '%s': %m", arg_machine);
+ log_error("No image for machine '%s'.", arg_machine);
return -ENOENT;
}
arg_container_service_name);
if (r < 0)
return r;
- }
+ } else if (!arg_keep_unit) {
+ r = allocate_scope(
+ arg_machine,
+ *pid,
+ arg_slice,
+ arg_custom_mounts, arg_n_custom_mounts,
+ arg_kill_signal,
+ arg_property);
+ if (r < 0)
+ return r;
+
+ } else if (arg_slice || arg_property)
+ log_notice("Machine and scope registration turned off, --slice= and --property= settings will have no effect.");
r = sync_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift);
if (r < 0)
log_parse_environment();
log_open();
- r = cg_unified_flush();
- if (r < 0)
- return log_error_errno(r, "Failed to determine whether the unified cgroups hierarchy is used: %m");
-
/* Make sure rename_process() in the stub init process can work */
saved_argv = argv;
saved_argc = argc;
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <dlfcn.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#define DNS_CALL_TIMEOUT_USEC (45*USEC_PER_SEC)
-typedef void (*voidfunc_t)(void);
-
-static voidfunc_t find_fallback(const char *module, const char *symbol) {
- void *dl;
-
- /* Try to find a fallback NSS module symbol */
-
- dl = dlopen(module, RTLD_LAZY|RTLD_NODELETE);
- if (!dl)
- return NULL;
-
- return dlsym(dl, symbol);
-}
-
static bool bus_error_shall_fallback(sd_bus_error *e) {
return sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER) ||
r = sd_bus_open_system(&bus);
if (r < 0)
- goto fallback;
+ goto fail;
r = sd_bus_message_new_method_call(
bus,
return NSS_STATUS_NOTFOUND;
}
- if (bus_error_shall_fallback(&error))
- goto fallback;
+ /* Return NSS_STATUS_UNAVAIL when communication with systemd-resolved fails,
+ allowing falling back to other nss modules. Treat all other error conditions as
+ NOTFOUND. This includes DNSSEC errors and suchlike. (We don't use UNAVAIL in this
+ case so that the nsswitch.conf configuration can distuingish such executed but
+ negative replies from complete failure to talk to resolved). */
+ if (!bus_error_shall_fallback(&error))
+ ret = NSS_STATUS_NOTFOUND;
- /* Treat all other error conditions as NOTFOUND, and fail. This includes DNSSEC errors and
- suchlike. (We don't use UNAVAIL in this case so that the nsswitch.conf configuration can distuingish
- such executed but negative replies from complete failure to talk to resolved. */
- ret = NSS_STATUS_NOTFOUND;
goto fail;
}
return NSS_STATUS_SUCCESS;
-fallback:
- {
- _nss_gethostbyname4_r_t fallback;
-
- fallback = (_nss_gethostbyname4_r_t)
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname4_r");
-
- if (fallback)
- return fallback(name, pat, buffer, buflen, errnop, h_errnop, ttlp);
- }
-
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
r = sd_bus_open_system(&bus);
if (r < 0)
- goto fallback;
+ goto fail;
r = sd_bus_message_new_method_call(
bus,
return NSS_STATUS_NOTFOUND;
}
- if (bus_error_shall_fallback(&error))
- goto fallback;
+ if (!bus_error_shall_fallback(&error))
+ ret = NSS_STATUS_NOTFOUND;
- ret = NSS_STATUS_NOTFOUND;
goto fail;
}
return NSS_STATUS_SUCCESS;
-fallback:
- {
- _nss_gethostbyname3_r_t fallback;
-
- fallback = (_nss_gethostbyname3_r_t)
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyname3_r");
- if (fallback)
- return fallback(name, af, result, buffer, buflen, errnop, h_errnop, ttlp, canonp);
- }
-
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
r = sd_bus_open_system(&bus);
if (r < 0)
- goto fallback;
+ goto fail;
r = sd_bus_message_new_method_call(
bus,
return NSS_STATUS_NOTFOUND;
}
- if (bus_error_shall_fallback(&error))
- goto fallback;
+ if (!bus_error_shall_fallback(&error))
+ ret = NSS_STATUS_NOTFOUND;
- ret = NSS_STATUS_NOTFOUND;
goto fail;
}
return NSS_STATUS_SUCCESS;
-fallback:
- {
- _nss_gethostbyaddr2_r_t fallback;
-
- fallback = (_nss_gethostbyaddr2_r_t)
- find_fallback("libnss_dns.so.2", "_nss_dns_gethostbyaddr2_r");
-
- if (fallback)
- return fallback(addr, len, af, result, buffer, buflen, errnop, h_errnop, ttlp);
- }
-
fail:
*errnop = -r;
*h_errnop = NO_RECOVERY;
#include "string-util.h"
#include "util.h"
-#ifndef RC_LOCAL_SCRIPT_PATH_START
-#define RC_LOCAL_SCRIPT_PATH_START "/etc/rc.d/rc.local"
-#endif
-
-#ifndef RC_LOCAL_SCRIPT_PATH_STOP
-#define RC_LOCAL_SCRIPT_PATH_STOP "/sbin/halt.local"
-#endif
-
static const char *arg_dest = "/tmp";
static int add_symlink(const char *service, const char *where) {
--- /dev/null
+BEGIN{
+ print "const char *dns_type_to_string(int type) {\n\tswitch(type) {"
+}
+{
+ printf " case DNS_TYPE_%s: return ", $1;
+ sub(/_/, "-");
+ printf "\"%s\";\n", $1
+}
+END{
+ print " default: return NULL;\n\t}\n}\n"
+}
--- /dev/null
+#!/usr/bin/env python3
+
+"""Generate %-from-name.gperf from %-list.txt
+"""
+
+import sys
+
+name, prefix, input = sys.argv[1:]
+
+print("""\
+struct {}_name {{ const char* name; int id; }};
+%null-strings
+%%""".format(name))
+
+for line in open(input):
+ line = line.rstrip()
+ s = line.replace('_', '-')
+ print("{}, {}{}".format(s, prefix, line))
--- /dev/null
+s/.* DNS_TYPE_(\w+).*/\1/p
--- /dev/null
+basic_dns_sources = files('''
+ resolved-dns-dnssec.c
+ resolved-dns-dnssec.h
+ resolved-dns-packet.c
+ resolved-dns-packet.h
+ resolved-dns-rr.c
+ resolved-dns-rr.h
+ resolved-dns-answer.c
+ resolved-dns-answer.h
+ resolved-dns-question.c
+ resolved-dns-question.h
+ dns-type.c
+'''.split())
+
+dns_type_h = files('dns-type.h')[0]
+
+systemd_resolved_only_sources = files('''
+ resolved.c
+ resolved-manager.c
+ resolved-manager.h
+ resolved-conf.c
+ resolved-conf.h
+ resolved-resolv-conf.c
+ resolved-resolv-conf.h
+ resolved-bus.c
+ resolved-bus.h
+ resolved-link.h
+ resolved-link.c
+ resolved-link-bus.c
+ resolved-link-bus.h
+ resolved-llmnr.h
+ resolved-llmnr.c
+ resolved-mdns.h
+ resolved-mdns.c
+ resolved-def.h
+ resolved-dns-query.h
+ resolved-dns-query.c
+ resolved-dns-synthesize.h
+ resolved-dns-synthesize.c
+ resolved-dns-transaction.h
+ resolved-dns-transaction.c
+ resolved-dns-scope.h
+ resolved-dns-scope.c
+ resolved-dns-server.h
+ resolved-dns-server.c
+ resolved-dns-search-domain.h
+ resolved-dns-search-domain.c
+ resolved-dns-cache.h
+ resolved-dns-cache.c
+ resolved-dns-zone.h
+ resolved-dns-zone.c
+ resolved-dns-stream.h
+ resolved-dns-stream.c
+ resolved-dns-trust-anchor.h
+ resolved-dns-trust-anchor.c
+ resolved-dns-stub.h
+ resolved-dns-stub.c
+ resolved-etc-hosts.h
+ resolved-etc-hosts.c
+'''.split())
+
+systemd_resolve_only_sources = files('resolve-tool.c')
+
+############################################################
+
+dns_type_list_txt = custom_target(
+ 'dns_type-list.txt',
+ input : ['generate-dns_type-list.sed', dns_type_h],
+ output : 'dns_type-list.txt',
+ command : [sed, '-n', '-r', '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+generate_dns_type_gperf = find_program('generate-dns_type-gperf.py')
+
+dns_type_headers = [dns_type_h]
+foreach item : [['dns_type', dns_type_list_txt, 'dns_type', 'DNS_TYPE_']]
+
+ fname = '@0@-from-name.gperf'.format(item[0])
+ gperf_file = custom_target(
+ fname,
+ input : item[1],
+ output : fname,
+ command : [generate_dns_type_gperf, item[2], item[3], '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-from-name.h'.format(item[0])
+ target1 = custom_target(
+ fname,
+ input : gperf_file,
+ output : fname,
+ command : [gperf,
+ '-L', 'ANSI-C', '-t', '--ignore-case',
+ '-N', 'lookup_@0@'.format(item[2]),
+ '-H', 'hash_@0@_name'.format(item[2]),
+ '-p', '-C',
+ '@INPUT@'],
+ capture : true)
+
+ fname = '@0@-to-name.h'.format(item[0])
+ awkscript = '@0@-to-name.awk'.format(item[0])
+ target2 = custom_target(
+ fname,
+ input : [awkscript, item[1]],
+ output : fname,
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+ dns_type_headers += [target1, target2]
+endforeach
+
+resolved_gperf_c = custom_target(
+ 'resolved_gperf.c',
+ input : 'resolved-gperf.gperf',
+ output : 'resolved-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_resolved_sources = (basic_dns_sources +
+ [resolved_gperf_c] +
+ systemd_resolved_only_sources +
+ dns_type_headers)
+
+systemd_resolve_sources = (basic_dns_sources +
+ systemd_resolve_only_sources +
+ dns_type_headers)
+
+if conf.get('ENABLE_RESOLVED', false)
+ install_data('org.freedesktop.resolve1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.resolve1.service',
+ install_dir : dbussystemservicedir)
+
+ resolved_conf = configure_file(
+ input : 'resolved.conf.in',
+ output : 'resolved.conf',
+ configuration : substs)
+ install_data(resolved_conf,
+ install_dir : pkgsysconfdir)
+
+ install_data('resolv.conf',
+ install_dir : rootlibexecdir)
+endif
+
+tests += [
+ [['src/resolve/test-resolve-tables.c',
+ basic_dns_sources,
+ dns_type_headers,
+ 'src/shared/test-tables.h'],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-dns-packet.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-resolved-packet.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-dnssec.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
+ [['src/resolve/test-dnssec-complex.c',
+ 'src/resolve/dns-type.c',
+ dns_type_headers],
+ [],
+ [],
+ 'ENABLE_RESOLVED', 'manual'],
+]
flags & SD_RESOLVED_DNS ? " DNS" :"",
flags & SD_RESOLVED_LLMNR_IPV4 ? " LLMNR/IPv4" : "",
flags & SD_RESOLVED_LLMNR_IPV6 ? " LLMNR/IPv6" : "",
- flags & SD_RESOLVED_MDNS_IPV4 ? "mDNS/IPv4" : "",
- flags & SD_RESOLVED_MDNS_IPV6 ? "mDNS/IPv6" : "");
+ flags & SD_RESOLVED_MDNS_IPV4 ? " mDNS/IPv4" : "",
+ flags & SD_RESOLVED_MDNS_IPV6 ? " mDNS/IPv6" : "");
assert_se(format_timespan(rtt_str, sizeof(rtt_str), rtt, 100));
return r;
r = dns_question_new_address(&question_idna, family, hostname, true);
- if (r < 0)
+ if (r < 0 && r != -EALREADY)
return r;
- r = dns_query_new(m, &q, question_utf8, question_idna, ifindex, flags);
+ r = dns_query_new(m, &q, question_utf8, question_idna ?: question_utf8, ifindex, flags);
if (r < 0)
return r;
return sd_bus_message_close_container(reply);
}
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode);
+
static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
DnsScope *s;
SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0),
SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
+ SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
assert(m);
r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf",
- CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
- "Resolve\0",
- config_item_perf_lookup, resolved_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
+ "Resolve\0",
+ config_item_perf_lookup, resolved_gperf_lookup,
+ false, m);
if (r < 0)
return r;
return r;
}
+#ifndef HAVE_GCRYPT
+ if (m->dnssec_mode != DNSSEC_NO) {
+ log_warning("DNSSEC option cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support.");
+ m->dnssec_mode = DNSSEC_NO;
+ }
+#endif
return 0;
}
#define EDNS0_OPT_DO (1<<15)
+#define DNS_PACKET_SIZE_START 512u
+assert_cc(DNS_PACKET_SIZE_START > DNS_PACKET_HEADER_SIZE)
+
typedef struct DnsPacketRewinder {
DnsPacket *packet;
size_t saved_rindex;
#define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while (0)
#define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while (0)
-int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
+int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize) {
DnsPacket *p;
size_t a;
assert(ret);
- if (mtu <= UDP_PACKET_HEADER_SIZE)
+ /* The caller may not check what is going to be truly allocated, so do not allow to
+ * allocate a DNS packet bigger than DNS_PACKET_SIZE_MAX.
+ */
+ if (min_alloc_dsize > DNS_PACKET_SIZE_MAX) {
+ log_error("Requested packet data size too big: %zu", min_alloc_dsize);
+ return -EFBIG;
+ }
+
+ /* When dns_packet_new() is called with min_alloc_dsize == 0, allocate more than the
+ * absolute minimum (which is the dns packet header size), to avoid
+ * resizing immediately again after appending the first data to the packet.
+ */
+ if (min_alloc_dsize < DNS_PACKET_HEADER_SIZE)
a = DNS_PACKET_SIZE_START;
else
- a = mtu - UDP_PACKET_HEADER_SIZE;
-
- if (a < DNS_PACKET_HEADER_SIZE)
- a = DNS_PACKET_HEADER_SIZE;
+ a = min_alloc_dsize;
/* round up to next page size */
a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
}
}
-int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled) {
+int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled) {
DnsPacket *p;
int r;
assert(ret);
- r = dns_packet_new(&p, protocol, mtu);
+ r = dns_packet_new(&p, protocol, min_alloc_dsize);
if (r < 0)
return r;
if (r < 0)
return r;
+ if (!p->question)
+ return 0;
+
if (p->question->n_keys != 1)
return 0;
/* The various DNS protocols deviate in how large a packet can grow,
but the TCP transport has a 16bit size field, hence that appears to
be the absolute maximum. */
-#define DNS_PACKET_SIZE_MAX 0xFFFF
+#define DNS_PACKET_SIZE_MAX 0xFFFFu
/* RFC 1035 say 512 is the maximum, for classic unicast DNS */
-#define DNS_PACKET_UNICAST_SIZE_MAX 512
+#define DNS_PACKET_UNICAST_SIZE_MAX 512u
/* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
-#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096
-
-#define DNS_PACKET_SIZE_START 512
+#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096u
struct DnsPacket {
int n_ref;
(unsigned) DNS_PACKET_ARCOUNT(p);
}
-int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t mtu);
-int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled);
+int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t min_alloc_dsize);
+int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled);
void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated);
r = dns_name_apply_idna(name, &buf);
if (r < 0)
return r;
-
- name = buf;
+ if (r > 0 && !streq(name, buf))
+ name = buf;
+ else
+ /* We did not manage to create convert the idna name, or it's
+ * the same as the original name. We assume the caller already
+ * created an uncoverted question, so let's not repeat work
+ * unnecessarily. */
+ return -EALREADY;
}
q = dns_question_new(family == AF_UNSPEC ? 2 : 1);
r = dns_name_apply_idna(domain, &buf);
if (r < 0)
return r;
-
- domain = buf;
+ if (r > 0)
+ domain = buf;
}
r = dns_service_join(service, type, domain, &joined);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-messages.h>
+#include "sd-messages.h"
#include "alloc-util.h"
#include "resolved-dns-server.h"
if (s->max_rtt < rtt) {
s->max_rtt = rtt;
s->resend_timeout = CLAMP(s->max_rtt * 2, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
- }
+ } else if (s->resend_timeout > rtt)
+ /* If we received the packet faster than the resend_timeout, bias
+ * the resend_timeout back to the rtt. */
+ s->resend_timeout = CLAMP((2 * s->resend_timeout + rtt) / 3, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
}
void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel level, usec_t usec) {
return s;
if (s)
- log_info("Switching to %s DNS server %s.",
- dns_server_type_to_string(s->type),
- dns_server_string(s));
+ log_debug("Switching to %s DNS server %s.",
+ dns_server_type_to_string(s->type),
+ dns_server_string(s));
dns_server_unref(m->current_dns_server);
m->current_dns_server = dns_server_ref(s);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-messages.h>
+#include "sd-messages.h"
#include "af-list.h"
#include "alloc-util.h"
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sd-messages.h>
+#include "sd-messages.h"
#include "alloc-util.h"
#include "conf-files.h"
Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0
Resolve.Domains, config_parse_search_domains, 0, 0
Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support)
+Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
Resolve.Cache, config_parse_bool, 0, offsetof(Manager, enable_cache)
Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
#include "mkdir.h"
#include "parse-util.h"
#include "resolved-link.h"
+#include "resolved-llmnr.h"
+#include "resolved-mdns.h"
#include "string-util.h"
#include "strv.h"
assert(l);
+#ifndef HAVE_GCRYPT
+ if (mode == DNSSEC_YES || mode == DNSSEC_ALLOW_DOWNGRADE)
+ log_warning("DNSSEC option for the link cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support.");
+ return;
+#endif
+
if (l->dnssec_mode == mode)
return;
}
int link_update(Link *l) {
+ int r;
+
assert(l);
link_read_settings(l);
link_load_user(l);
+
+ if (l->llmnr_support != RESOLVE_SUPPORT_NO) {
+ r = manager_llmnr_start(l->manager);
+ if (r < 0)
+ return r;
+ }
+
+ if (l->mdns_support != RESOLVE_SUPPORT_NO) {
+ r = manager_mdns_start(l->manager);
+ if (r < 0)
+ return r;
+ }
+
link_allocate_scopes(l);
link_add_rrs(l, false);
assert(l);
- /* A link is relevant for local multicast traffic if it isn't a loopback or pointopoint device, has a link
+ /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
* beat, can do multicast and has at least one link-local (or better) IP address.
*
* A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
return false;
if (local_multicast) {
- if (l->flags & IFF_POINTOPOINT)
- return false;
-
if ((l->flags & IFF_MULTICAST) != IFF_MULTICAST)
return false;
}
return s;
if (s)
- log_info("Switching to DNS server %s for interface %s.", dns_server_string(s), l->name);
+ log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s), l->name);
dns_server_unref(l->current_dns_server);
l->current_dns_server = dns_server_ref(s);
return 0;
eaddrinuse:
- log_warning("There appears to be another LLMNR responder running. Turning off LLMNR support.");
+ log_warning("Another LLMNR responder prohibits binding the socket to the same port. Turning off LLMNR support.");
m->llmnr_support = RESOLVE_SUPPORT_NO;
manager_llmnr_stop(m);
m->llmnr_ipv4_udp_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv4_udp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to create socket: %m");
/* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_TTL: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_TTL: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_PKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_RECVTTL: %m");
goto fail;
}
/* Disable Don't-Fragment bit in the IP header */
r = setsockopt(m->llmnr_ipv4_udp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set IP_MTU_DISCOVER: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv4(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv4_udp_fd, &sa.sa, sizeof(sa.in));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv4_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, m->llmnr_ipv4_udp_fd, EPOLLIN, on_llmnr_packet, m);
m->llmnr_ipv6_udp_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv6_udp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to create socket: %m");
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_UNICAST_HOPS: %m");
goto fail;
}
/* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_HOPS: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_V6ONLY: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVPKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_udp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVHOPLIMIT: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv6(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv6_udp_fd, &sa.sa, sizeof(sa.in6));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv6_udp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, m->llmnr_ipv6_udp_fd, EPOLLIN, on_llmnr_packet, m);
m->llmnr_ipv4_tcp_fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv4_tcp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to create socket: %m");
/* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_TTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_TTL: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_PKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_RECVTTL: %m");
goto fail;
}
/* Disable Don't-Fragment bit in the IP header */
r = setsockopt(m->llmnr_ipv4_tcp_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set IP_MTU_DISCOVER: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv4(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv4_tcp_fd, &sa.sa, sizeof(sa.in));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv4_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = listen(m->llmnr_ipv4_tcp_fd, SOMAXCONN);
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to listen the stream: %m");
goto fail;
}
m->llmnr_ipv6_tcp_fd = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->llmnr_ipv6_tcp_fd < 0)
- return -errno;
+ return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to create socket: %m");
/* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_UNICAST_HOPS: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_V6ONLY: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVPKTINFO: %m");
goto fail;
}
r = setsockopt(m->llmnr_ipv6_tcp_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVHOPLIMIT: %m");
goto fail;
}
+ /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("LLMNR-IPv6(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->llmnr_ipv6_tcp_fd, &sa.sa, sizeof(sa.in6));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
+ r = setsockopt(m->llmnr_ipv6_tcp_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = listen(m->llmnr_ipv6_tcp_fd, SOMAXCONN);
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to listen the stream: %m");
goto fail;
}
#include <poll.h>
#include <sys/ioctl.h>
+#ifdef HAVE_LIBIDN2
+#include <idn2.h>
+#endif
+
#include "af-list.h"
#include "alloc-util.h"
#include "dirent-util.h"
static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
_cleanup_free_ char *h = NULL, *n = NULL;
+#if defined(HAVE_LIBIDN2)
+ _cleanup_free_ char *utf8 = NULL;
+#elif defined(HAVE_LIBIDN)
+ int k;
+#endif
char label[DNS_LABEL_MAX];
- const char *p;
- int r, k;
+ const char *p, *decoded;
+ int r;
assert(full_hostname);
assert(llmnr_hostname);
return log_debug_errno(r, "Can't determine system hostname: %m");
p = h;
- r = dns_label_unescape(&p, label, sizeof(label));
+ r = dns_label_unescape(&p, label, sizeof label);
if (r < 0)
return log_error_errno(r, "Failed to unescape host name: %m");
if (r == 0) {
return -EINVAL;
}
- k = dns_label_undo_idna(label, r, label, sizeof(label));
+#if defined(HAVE_LIBIDN2)
+ r = idn2_to_unicode_8z8z(label, &utf8, 0);
+ if (r != IDN2_OK)
+ return log_error("Failed to undo IDNA: %s", idn2_strerror(r));
+ assert(utf8_is_valid(utf8));
+
+ r = strlen(utf8);
+ decoded = utf8;
+#elif defined(HAVE_LIBIDN)
+ k = dns_label_undo_idna(label, r, label, sizeof label);
if (k < 0)
return log_error_errno(k, "Failed to undo IDNA: %m");
if (k > 0)
log_error("System hostname is not UTF-8 clean.");
return -EINVAL;
}
+ decoded = label;
+#else
+ decoded = label; /* no decoding */
+#endif
- r = dns_label_escape_new(label, r, &n);
+ r = dns_label_escape_new(decoded, r, &n);
if (r < 0)
return log_error_errno(r, "Failed to escape host name: %m");
r = manager_parse_config_file(m);
if (r < 0)
- return r;
+ log_warning_errno(r, "Failed to parse configuration file: %m");
r = sd_event_default(&m->event);
if (r < 0)
if (r < 0)
return r;
- r = manager_llmnr_start(m);
- if (r < 0)
- return r;
-
- r = manager_mdns_start(m);
- if (r < 0)
- return r;
-
return 0;
}
return 0;
eaddrinuse:
- log_warning("There appears to be another mDNS responder running. Turning off mDNS support.");
+ log_warning("Another mDNS responder prohibits binding the socket to the same port. Turning off mDNS support.");
m->mdns_support = RESOLVE_SUPPORT_NO;
manager_mdns_stop(m);
m->mdns_ipv4_fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->mdns_ipv4_fd < 0)
- return -errno;
+ return log_error_errno(errno, "mDNS-IPv4: Failed to create socket: %m");
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_TTL: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MULTICAST_TTL: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_PKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_PKTINFO: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_RECVTTL, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_RECVTTL: %m");
goto fail;
}
/* Disable Don't-Fragment bit in the IP header */
r = setsockopt(m->mdns_ipv4_fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set IP_MTU_DISCOVER: %m");
goto fail;
}
+ /* See the section 15.1 of RFC6762 */
+ /* first try to bind without SO_REUSEADDR to detect another mDNS responder */
r = bind(m->mdns_ipv4_fd, &sa.sa, sizeof(sa.in));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("mDNS-IPv4: There appears to be another mDNS responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->mdns_ipv4_fd, &sa.sa, sizeof(sa.in));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple mDNS responders */
+ r = setsockopt(m->mdns_ipv4_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv4: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->mdns_ipv4_event_source, m->mdns_ipv4_fd, EPOLLIN, on_mdns_packet, m);
m->mdns_ipv6_fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (m->mdns_ipv6_fd < 0)
- return -errno;
+ return log_error_errno(errno, "mDNS-IPv6: Failed to create socket: %m");
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_UNICAST_HOPS: %m");
goto fail;
}
/* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_MULTICAST_HOPS: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_MULTICAST_LOOP: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));
if (r < 0) {
- r = -errno;
- goto fail;
- }
-
- r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_V6ONLY: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_RECVPKTINFO: %m");
goto fail;
}
r = setsockopt(m->mdns_ipv6_fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &one, sizeof(one));
if (r < 0) {
- r = -errno;
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set IPV6_RECVHOPLIMIT: %m");
goto fail;
}
+ /* See the section 15.1 of RFC6762 */
+ /* first try to bind without SO_REUSEADDR to detect another mDNS responder */
r = bind(m->mdns_ipv6_fd, &sa.sa, sizeof(sa.in6));
if (r < 0) {
- r = -errno;
- goto fail;
+ if (errno != EADDRINUSE) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to bind socket: %m");
+ goto fail;
+ }
+
+ log_warning("mDNS-IPv6: There appears to be another mDNS responder running, or previously systemd-resolved crashed with some outstanding transfers.");
+
+ /* try again with SO_REUSEADDR */
+ r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
+
+ r = bind(m->mdns_ipv6_fd, &sa.sa, sizeof(sa.in6));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to bind socket: %m");
+ goto fail;
+ }
+ } else {
+ /* enable SO_REUSEADDR for the case that the user really wants multiple mDNS responders */
+ r = setsockopt(m->mdns_ipv6_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+ if (r < 0) {
+ r = log_error_errno(errno, "mDNS-IPv6: Failed to set SO_REUSEADDR: %m");
+ goto fail;
+ }
}
r = sd_event_add_io(m->event, &m->mdns_ipv6_event_source, m->mdns_ipv6_fd, EPOLLIN, on_mdns_packet, m);
#FallbackDNS=@DNS_SERVERS@
#Domains=
#LLMNR=yes
+#MulticastDNS=yes
#DNSSEC=@DEFAULT_DNSSEC_MODE@
#Cache=yes
#DNSStubListener=udp
test_hostname_lookup(bus, "poettering.de", AF_INET, NULL);
test_hostname_lookup(bus, "poettering.de", AF_INET6, NULL);
-#ifdef HAVE_LIBIDN
+#if defined(HAVE_LIBIDN2) || defined(HAVE_LIBIDN)
/* Unsigned A with IDNA conversion necessary */
test_hostname_lookup(bus, "pöttering.de", AF_UNSPEC, NULL);
test_hostname_lookup(bus, "pöttering.de", AF_INET, NULL);
--- /dev/null
+/***
+ This file is part of systemd
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "log.h"
+#include "resolved-dns-packet.h"
+
+static void test_dns_packet_new(void) {
+ size_t i;
+ _cleanup_(dns_packet_unrefp) DnsPacket *p2 = NULL;
+
+ for (i = 0; i <= DNS_PACKET_SIZE_MAX; i++) {
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+
+ assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, i) == 0);
+
+ log_debug("dns_packet_new: %zu → %zu", i, p->allocated);
+ assert_se(p->allocated >= MIN(DNS_PACKET_SIZE_MAX, i));
+ }
+
+ assert_se(dns_packet_new(&p2, DNS_PROTOCOL_DNS, DNS_PACKET_SIZE_MAX + 1) == -EFBIG);
+}
+
+int main(int argc, char **argv) {
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_dns_packet_new();
+
+ return 0;
+}
{ "usr", 0755, NULL, NULL },
{ "var", 0755, NULL, NULL },
{ "etc", 0755, NULL, NULL },
+ { "proc", 0755, NULL, NULL, true },
+ { "sys", 0755, NULL, NULL, true },
+ { "dev", 0755, NULL, NULL, true },
#if defined(__i386__) || defined(__x86_64__)
{ "lib64", 0, "usr/lib/x86_64-linux-gnu\0"
"usr/lib64\0", "ld-linux-x86-64.so.2" },
if (!table[i].ignore_failure)
return -errno;
+
+ continue;
}
if (uid != UID_INVALID || gid != UID_INVALID) {
"StandardInput", "StandardOutput", "StandardError",
"Description", "Slice", "Type", "WorkingDirectory",
"RootDirectory", "SyslogIdentifier", "ProtectSystem",
- "ProtectHome", "SELinuxContext", "Restart", "RootImage"))
+ "ProtectHome", "SELinuxContext", "Restart", "RootImage",
+ "NotifyAccess"))
r = sd_bus_message_append(m, "v", "s", eq);
else if (streq(field, "SyslogLevel")) {
r = sd_bus_message_append(m, "v", "i", (int32_t) n);
+ } else if (streq(field, "FileDescriptorStoreMax")) {
+ unsigned u;
+
+ r = safe_atou(eq, &u);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse file descriptor store limit: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "u", (uint32_t) u);
+
+ } else if (streq(field, "IOSchedulingClass")) {
+ int c;
+
+ c = ioprio_class_from_string(eq);
+ if (c < 0)
+ return log_error_errno(r, "Failed to parse IO scheduling class: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "i", (int32_t) c);
+
+ } else if (streq(field, "IOSchedulingPriority")) {
+ int q;
+
+ r = ioprio_parse_priority(eq, &q);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse IO scheduling priority: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "i", (int32_t) q);
+
} else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
const char *p;
assert(service);
- service_shell_quoted = shell_maybe_quote(service);
+ service_shell_quoted = shell_maybe_quote(service, ESCAPE_BACKSLASH);
if (extra_args) {
_cleanup_free_ char *t;
return r;
if (all || !isempty(s)) {
- _cleanup_free_ char *escaped = NULL;
+ bool good;
- escaped = xescape(s, "\n");
- if (!escaped)
- return -ENOMEM;
-
- print_property(name, "%s", escaped);
+ /* This property has a single value, so we need to take
+ * care not to print a new line, everything else is OK. */
+ good = !strchr(s, '\n');
+ print_property(name, "%s", good ? s : "[unprintable]");
}
return 1;
return r;
while ((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
- _cleanup_free_ char *escaped = NULL;
+ bool good;
if (first && !value)
printf("%s=", name);
- escaped = xescape(str, "\n ");
- if (!escaped)
- return -ENOMEM;
+ /* This property has multiple space-seperated values, so
+ * neither spaces not newlines can be allowed in a value. */
+ good = str[strcspn(str, " \n")] == '\0';
- printf("%s%s", first ? "" : " ", escaped);
+ printf("%s%s", first ? "" : " ", good ? str : "[unprintable]");
first = false;
}
#include <stdlib.h>
#include <string.h>
-#include <systemd/sd-bus.h>
-
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include <stdbool.h>
#include <sys/types.h>
-#include <systemd/sd-bus.h>
+#include "sd-bus.h"
#include "logs-show.h"
#include "output-mode.h"
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
+#include "user-util.h"
#include "util.h"
#include "virt.h"
return false;
}
+static int condition_test_user(Condition *c) {
+ uid_t id;
+ int r;
+ _cleanup_free_ char *username = NULL;
+ const char *u;
+
+ assert(c);
+ assert(c->parameter);
+ assert(c->type == CONDITION_USER);
+
+ r = parse_uid(c->parameter, &id);
+ if (r >= 0)
+ return id == getuid() || id == geteuid();
+
+ if (streq("@system", c->parameter))
+ return getuid() <= SYSTEM_UID_MAX || geteuid() <= SYSTEM_UID_MAX;
+
+ username = getusername_malloc();
+ if (!username)
+ return -ENOMEM;
+
+ if (streq(username, c->parameter))
+ return 1;
+
+ if (getpid() == 1)
+ return streq(c->parameter, "root");
+
+ u = c->parameter;
+ r = get_user_creds(&u, &id, NULL, NULL, NULL);
+ if (r < 0)
+ return 0;
+
+ return id == getuid() || id == geteuid();
+}
+
+static int condition_test_group(Condition *c) {
+ gid_t id;
+ int r;
+
+ assert(c);
+ assert(c->parameter);
+ assert(c->type == CONDITION_GROUP);
+
+ r = parse_gid(c->parameter, &id);
+ if (r >= 0)
+ return in_gid(id);
+
+ /* Avoid any NSS lookups if we are PID1 */
+ if (getpid() == 1)
+ return streq(c->parameter, "root");
+
+ return in_group(c->parameter) > 0;
+}
+
static int condition_test_virtualization(Condition *c) {
int b, v;
assert(c->type == CONDITION_SECURITY);
if (streq(c->parameter, "selinux"))
- return mac_selinux_have();
+ return mac_selinux_use();
if (streq(c->parameter, "smack"))
return mac_smack_use();
if (streq(c->parameter, "apparmor"))
[CONDITION_ARCHITECTURE] = condition_test_architecture,
[CONDITION_NEEDS_UPDATE] = condition_test_needs_update,
[CONDITION_FIRST_BOOT] = condition_test_first_boot,
+ [CONDITION_USER] = condition_test_user,
+ [CONDITION_GROUP] = condition_test_group,
[CONDITION_NULL] = condition_test_null,
};
[CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
[CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
[CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
+ [CONDITION_USER] = "ConditionUser",
+ [CONDITION_GROUP] = "ConditionGroup",
[CONDITION_NULL] = "ConditionNull"
};
[CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
[CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
[CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
+ [CONDITION_USER] = "AssertUser",
+ [CONDITION_GROUP] = "AssertGroup",
[CONDITION_NULL] = "AssertNull"
};
CONDITION_NULL,
+ CONDITION_USER,
+ CONDITION_GROUP,
+
_CONDITION_TYPE_MAX,
_CONDITION_TYPE_INVALID = -1
} ConditionType;
DEFINE_PARSER(int, int, safe_atoi);
DEFINE_PARSER(long, long, safe_atoli);
+DEFINE_PARSER(uint8, uint8_t, safe_atou8);
DEFINE_PARSER(uint16, uint16_t, safe_atou16);
DEFINE_PARSER(uint32, uint32_t, safe_atou32);
DEFINE_PARSER(uint64, uint64_t, safe_atou64);
int k;
bool *b = data;
+ bool fatal = ltype;
assert(filename);
assert(lvalue);
k = parse_boolean(rvalue);
if (k < 0) {
- log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, k,
+ "Failed to parse boolean value%s: %s",
+ fatal ? "" : ", ignoring", rvalue);
+ return fatal ? -ENOEXEC : 0;
}
*b = !!k;
void *userdata) {
char **s = data, *n;
+ bool fatal = ltype;
assert(filename);
assert(lvalue);
if (!utf8_is_valid(rvalue)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
- return 0;
+ return fatal ? -ENOEXEC : 0;
}
if (!path_is_absolute(rvalue)) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", rvalue);
- return 0;
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Not an absolute path%s: %s",
+ fatal ? "" : ", ignoring", rvalue);
+ return fatal ? -ENOEXEC : 0;
}
n = strdup(rvalue);
}
if (!utf8_is_valid(word)) {
- log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
+ log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, word);
free(word);
continue;
}
return 0;
}
+
+int config_parse_ip_port(
+ 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) {
+
+ uint16_t *s = data;
+ uint16_t port;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (isempty(rvalue)) {
+ *s = 0;
+ return 0;
+ }
+
+ r = parse_ip_port(rvalue, &port);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse port '%s'.", rvalue);
+ return 0;
+ }
+
+ *s = port;
+
+ return 0;
+}
int config_parse_int(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);
int config_parse_unsigned(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);
int config_parse_long(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);
+int config_parse_uint8(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);
int config_parse_uint16(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);
int config_parse_uint32(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);
int config_parse_uint64(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);
int config_parse_signal(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);
int config_parse_personality(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);
int config_parse_ifname(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);
+int config_parse_ip_port(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);
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
int function(const char *unit, \
#ifdef HAVE_LIBCRYPTSETUP
#include <libcryptsetup.h>
#endif
-#include <linux/dm-ioctl.h>
#include <sys/mount.h>
#include "architecture.h"
#include "fs-util.h"
#include "gpt.h"
#include "hexdecoct.h"
+#include "linux-3.13/dm-ioctl.h"
#include "mount-util.h"
#include "path-util.h"
#include "stat-util.h"
#include "udev-util.h"
#include "xattr-util.h"
-static int probe_filesystem(const char *node, char **ret_fstype) {
+_unused_ static int probe_filesystem(const char *node, char **ret_fstype) {
#ifdef HAVE_BLKID
_cleanup_blkid_free_probe_ blkid_probe b = NULL;
const char *fstype;
_cleanup_udev_device_unref_ struct udev_device *q;
unsigned long long pflags;
blkid_partition pp;
- const char *node;
+ const char *node, *sysname;
dev_t qn;
int nr;
if (st.st_rdev == qn)
continue;
+ /* Filter out weird MMC RPMB partitions, which cannot reasonably be read, see
+ * https://github.com/systemd/systemd/issues/5806 */
+ sysname = udev_device_get_sysname(q);
+ if (sysname && startswith(sysname, "mmcblk") && endswith(sysname, "rpmb"))
+ continue;
+
node = udev_device_get_devnode(q);
if (!node)
continue;
*
* = 0 → There was nothing to decrypt
* > 0 → Decrypted successfully
- * -ENOKEY → There's some to decrypt but no key was supplied
+ * -ENOKEY → There's something to decrypt but no key was supplied
* -EKEYREJECTED → Passed key was not correct
*/
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#ifdef HAVE_LIBIDN
-#include <idna.h>
-#include <stringprep.h>
+#if defined(HAVE_LIBIDN2)
+# include <idn2.h>
+#elif defined(HAVE_LIBIDN)
+# include <idna.h>
+# include <stringprep.h>
#endif
#include <endian.h>
return r;
}
-int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
#ifdef HAVE_LIBIDN
+int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
_cleanup_free_ uint32_t *input = NULL;
size_t input_size, l;
const char *p;
decoded[l] = 0;
return (int) l;
-#else
- return 0;
-#endif
}
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
-#ifdef HAVE_LIBIDN
size_t input_size, output_size;
_cleanup_free_ uint32_t *input = NULL;
_cleanup_free_ char *result = NULL;
decoded[w] = 0;
return w;
-#else
- return 0;
-#endif
}
+#endif
int dns_name_concat(const char *a, const char *b, char **_ret) {
_cleanup_free_ char *ret = NULL;
}
int dns_name_apply_idna(const char *name, char **ret) {
+ /* Return negative on error, 0 if not implemented, positive on success. */
+
+#if defined(HAVE_LIBIDN2)
+ int r;
+
+ assert(name);
+ assert(ret);
+
+ r = idn2_lookup_u8((uint8_t*) name, (uint8_t**) ret,
+ IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL);
+ if (r == IDN2_OK)
+ return 1; /* *ret has been written */
+ log_debug("idn2_lookup_u8(\"%s\") failed: %s", name, idn2_strerror(r));
+ if (r == IDN2_2HYPHEN)
+ /* The name has two hypens — forbidden by IDNA2008 in some cases */
+ return 0;
+ if (IN_SET(r, IDN2_TOO_BIG_DOMAIN, IDN2_TOO_BIG_LABEL))
+ return -ENOSPC;
+ return -EINVAL;
+#elif defined(HAVE_LIBIDN)
_cleanup_free_ char *buf = NULL;
size_t n = 0, allocated = 0;
bool first = true;
else
buf[n++] = '.';
- n +=r;
+ n += r;
}
if (n > DNS_HOSTNAME_MAX)
*ret = buf;
buf = NULL;
- return (int) n;
+ return 1;
+#else
+ return 0;
+#endif
}
int dns_name_is_valid_or_address(const char *name) {
return dns_label_unescape(name, NULL, DNS_LABEL_MAX);
}
+#if defined(HAVE_LIBIDN)
int dns_label_apply_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max);
+#endif
int dns_name_concat(const char *a, const char *b, char **ret);
_cleanup_close_ int fd = -1;
assert(name);
+ assert(value);
if (asprintf(&p,
"/sys/firmware/efi/efivars/%s-%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
#include "strv.h"
#include "util.h"
-bool fstab_is_mount_point(const char *mount) {
+int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
f = setmntent("/etc/fstab", "re");
if (!f)
- return false;
+ return errno == ENOENT ? false : -errno;
- while ((m = getmntent(f)))
- if (path_equal(m->mnt_dir, mount))
+ for (;;) {
+ errno = 0;
+ m = getmntent(f);
+ if (!m)
+ return errno != 0 ? -errno : false;
+
+ if (streq(m->mnt_type, fstype))
return true;
+ }
+ return false;
+}
+
+int fstab_is_mount_point(const char *mount) {
+ _cleanup_endmntent_ FILE *f = NULL;
+ struct mntent *m;
+ f = setmntent("/etc/fstab", "re");
+ if (!f)
+ return errno == ENOENT ? false : -errno;
+
+ for (;;) {
+ errno = 0;
+ m = getmntent(f);
+ if (!m)
+ return errno != 0 ? -errno : false;
+
+ if (path_equal(m->mnt_dir, mount))
+ return true;
+ }
return false;
}
#include "macro.h"
-bool fstab_is_mount_point(const char *mount);
+int fstab_is_mount_point(const char *mount);
+int fstab_has_fstype(const char *fstype);
int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered);
usec_t u;
int r;
- r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
+ r = fstab_filter_options(opts, "comment=systemd.device-timeout\0"
+ "x-systemd.device-timeout\0",
NULL, &timeout, filtered);
if (r <= 0)
return r;
- r = parse_sec(timeout, &u);
+ r = parse_sec_fix_0(timeout, &u);
if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
return 0;
return write_drop_in_format(dir, unit, 50, "device-timeout",
"# Automatically generated by %s\n\n"
- "[Unit]\nJobTimeoutSec=%s",
+ "[Unit]\nJobRunningTimeoutSec=%s",
program_invocation_short_name, timeout);
}
+int generator_write_device_deps(
+ const char *dir,
+ const char *what,
+ const char *where,
+ const char *opts) {
+
+ /* fstab records that specify _netdev option should apply the network
+ * ordering on the actual device depending on network connection. If we
+ * are not mounting real device (NFS, CIFS), we rely on _netdev effect
+ * on the mount unit itself. */
+
+ _cleanup_free_ char *node = NULL, *unit = NULL;
+ int r;
+
+ if (!fstab_test_option(opts, "_netdev\0"))
+ return 0;
+
+ node = fstab_node_to_udev_node(what);
+ if (!node)
+ return log_oom();
+
+ /* Nothing to apply dependencies to. */
+ if (!is_device_path(node))
+ return 0;
+
+ r = unit_name_from_path(node, ".device", &unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make unit name from path: %m");
+
+ /* See mount_add_default_dependencies for explanation why we create such
+ * dependencies. */
+ return write_drop_in_format(dir, unit, 50, "netdev-dependencies",
+ "# Automatically generated by %s\n\n"
+ "[Unit]\n"
+ "After=" SPECIAL_NETWORK_ONLINE_TARGET " " SPECIAL_NETWORK_TARGET "\n"
+ "Wants=" SPECIAL_NETWORK_ONLINE_TARGET "\n",
+ program_invocation_short_name);
+}
+
int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
_cleanup_free_ char *unit = NULL;
int r;
const char *opts,
char **filtered);
+int generator_write_device_deps(
+ const char *dir,
+ const char *what,
+ const char *where,
+ const char *opts);
+
int generator_write_initrd_root_device_deps(
const char *dir,
const char *what);
a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
- return path_equal_or_files_same(a, b);
+ return path_equal_or_files_same(a, b, 0);
}
static int create_symlink(
if (errno == ENOENT)
continue;
if (IN_SET(errno, ENOTDIR, EACCES)) {
- log_debug("Failed to open \"%s\": %m", *i);
+ log_debug_errno(errno, "Failed to open \"%s\": %m", *i);
continue;
}
--- /dev/null
+/*
+ * Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
+ * Copyright (C) 2004 - 2009 Red Hat, Inc. All rights reserved.
+ *
+ * This file is released under the LGPL.
+ */
+
+#ifndef _LINUX_DM_IOCTL_V4_H
+#define _LINUX_DM_IOCTL_V4_H
+
+#include <linux/types.h>
+
+#define DM_DIR "mapper" /* Slashes not supported */
+#define DM_CONTROL_NODE "control"
+#define DM_MAX_TYPE_NAME 16
+#define DM_NAME_LEN 128
+#define DM_UUID_LEN 129
+
+/*
+ * A traditional ioctl interface for the device mapper.
+ *
+ * Each device can have two tables associated with it, an
+ * 'active' table which is the one currently used by io passing
+ * through the device, and an 'inactive' one which is a table
+ * that is being prepared as a replacement for the 'active' one.
+ *
+ * DM_VERSION:
+ * Just get the version information for the ioctl interface.
+ *
+ * DM_REMOVE_ALL:
+ * Remove all dm devices, destroy all tables. Only really used
+ * for debug.
+ *
+ * DM_LIST_DEVICES:
+ * Get a list of all the dm device names.
+ *
+ * DM_DEV_CREATE:
+ * Create a new device, neither the 'active' or 'inactive' table
+ * slots will be filled. The device will be in suspended state
+ * after creation, however any io to the device will get errored
+ * since it will be out-of-bounds.
+ *
+ * DM_DEV_REMOVE:
+ * Remove a device, destroy any tables.
+ *
+ * DM_DEV_RENAME:
+ * Rename a device or set its uuid if none was previously supplied.
+ *
+ * DM_SUSPEND:
+ * This performs both suspend and resume, depending which flag is
+ * passed in.
+ * Suspend: This command will not return until all pending io to
+ * the device has completed. Further io will be deferred until
+ * the device is resumed.
+ * Resume: It is no longer an error to issue this command on an
+ * unsuspended device. If a table is present in the 'inactive'
+ * slot, it will be moved to the active slot, then the old table
+ * from the active slot will be _destroyed_. Finally the device
+ * is resumed.
+ *
+ * DM_DEV_STATUS:
+ * Retrieves the status for the table in the 'active' slot.
+ *
+ * DM_DEV_WAIT:
+ * Wait for a significant event to occur to the device. This
+ * could either be caused by an event triggered by one of the
+ * targets of the table in the 'active' slot, or a table change.
+ *
+ * DM_TABLE_LOAD:
+ * Load a table into the 'inactive' slot for the device. The
+ * device does _not_ need to be suspended prior to this command.
+ *
+ * DM_TABLE_CLEAR:
+ * Destroy any table in the 'inactive' slot (ie. abort).
+ *
+ * DM_TABLE_DEPS:
+ * Return a set of device dependencies for the 'active' table.
+ *
+ * DM_TABLE_STATUS:
+ * Return the targets status for the 'active' table.
+ *
+ * DM_TARGET_MSG:
+ * Pass a message string to the target at a specific offset of a device.
+ *
+ * DM_DEV_SET_GEOMETRY:
+ * Set the geometry of a device by passing in a string in this format:
+ *
+ * "cylinders heads sectors_per_track start_sector"
+ *
+ * Beware that CHS geometry is nearly obsolete and only provided
+ * for compatibility with dm devices that can be booted by a PC
+ * BIOS. See struct hd_geometry for range limits. Also note that
+ * the geometry is erased if the device size changes.
+ */
+
+/*
+ * All ioctl arguments consist of a single chunk of memory, with
+ * this structure at the start. If a uuid is specified any
+ * lookup (eg. for a DM_INFO) will be done on that, *not* the
+ * name.
+ */
+struct dm_ioctl {
+ /*
+ * The version number is made up of three parts:
+ * major - no backward or forward compatibility,
+ * minor - only backwards compatible,
+ * patch - both backwards and forwards compatible.
+ *
+ * All clients of the ioctl interface should fill in the
+ * version number of the interface that they were
+ * compiled with.
+ *
+ * All recognised ioctl commands (ie. those that don't
+ * return -ENOTTY) fill out this field, even if the
+ * command failed.
+ */
+ __u32 version[3]; /* in/out */
+ __u32 data_size; /* total size of data passed in
+ * including this struct */
+
+ __u32 data_start; /* offset to start of data
+ * relative to start of this struct */
+
+ __u32 target_count; /* in/out */
+ __s32 open_count; /* out */
+ __u32 flags; /* in/out */
+
+ /*
+ * event_nr holds either the event number (input and output) or the
+ * udev cookie value (input only).
+ * The DM_DEV_WAIT ioctl takes an event number as input.
+ * The DM_SUSPEND, DM_DEV_REMOVE and DM_DEV_RENAME ioctls
+ * use the field as a cookie to return in the DM_COOKIE
+ * variable with the uevents they issue.
+ * For output, the ioctls return the event number, not the cookie.
+ */
+ __u32 event_nr; /* in/out */
+ __u32 padding;
+
+ __u64 dev; /* in/out */
+
+ char name[DM_NAME_LEN]; /* device name */
+ char uuid[DM_UUID_LEN]; /* unique identifier for
+ * the block device */
+ char data[7]; /* padding or data */
+};
+
+/*
+ * Used to specify tables. These structures appear after the
+ * dm_ioctl.
+ */
+struct dm_target_spec {
+ __u64 sector_start;
+ __u64 length;
+ __s32 status; /* used when reading from kernel only */
+
+ /*
+ * Location of the next dm_target_spec.
+ * - When specifying targets on a DM_TABLE_LOAD command, this value is
+ * the number of bytes from the start of the "current" dm_target_spec
+ * to the start of the "next" dm_target_spec.
+ * - When retrieving targets on a DM_TABLE_STATUS command, this value
+ * is the number of bytes from the start of the first dm_target_spec
+ * (that follows the dm_ioctl struct) to the start of the "next"
+ * dm_target_spec.
+ */
+ __u32 next;
+
+ char target_type[DM_MAX_TYPE_NAME];
+
+ /*
+ * Parameter string starts immediately after this object.
+ * Be careful to add padding after string to ensure correct
+ * alignment of subsequent dm_target_spec.
+ */
+};
+
+/*
+ * Used to retrieve the target dependencies.
+ */
+struct dm_target_deps {
+ __u32 count; /* Array size */
+ __u32 padding; /* unused */
+ __u64 dev[0]; /* out */
+};
+
+/*
+ * Used to get a list of all dm devices.
+ */
+struct dm_name_list {
+ __u64 dev;
+ __u32 next; /* offset to the next record from
+ the _start_ of this */
+ char name[0];
+};
+
+/*
+ * Used to retrieve the target versions
+ */
+struct dm_target_versions {
+ __u32 next;
+ __u32 version[3];
+
+ char name[0];
+};
+
+/*
+ * Used to pass message to a target
+ */
+struct dm_target_msg {
+ __u64 sector; /* Device sector */
+
+ char message[0];
+};
+
+/*
+ * If you change this make sure you make the corresponding change
+ * to dm-ioctl.c:lookup_ioctl()
+ */
+enum {
+ /* Top level cmds */
+ DM_VERSION_CMD = 0,
+ DM_REMOVE_ALL_CMD,
+ DM_LIST_DEVICES_CMD,
+
+ /* device level cmds */
+ DM_DEV_CREATE_CMD,
+ DM_DEV_REMOVE_CMD,
+ DM_DEV_RENAME_CMD,
+ DM_DEV_SUSPEND_CMD,
+ DM_DEV_STATUS_CMD,
+ DM_DEV_WAIT_CMD,
+
+ /* Table level cmds */
+ DM_TABLE_LOAD_CMD,
+ DM_TABLE_CLEAR_CMD,
+ DM_TABLE_DEPS_CMD,
+ DM_TABLE_STATUS_CMD,
+
+ /* Added later */
+ DM_LIST_VERSIONS_CMD,
+ DM_TARGET_MSG_CMD,
+ DM_DEV_SET_GEOMETRY_CMD
+};
+
+#define DM_IOCTL 0xfd
+
+#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
+#define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
+#define DM_LIST_DEVICES _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl)
+
+#define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
+#define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
+#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
+#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
+#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
+#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
+
+#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
+#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
+#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
+#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl)
+
+#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
+
+#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
+#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
+
+#define DM_VERSION_MAJOR 4
+#define DM_VERSION_MINOR 27
+#define DM_VERSION_PATCHLEVEL 0
+#define DM_VERSION_EXTRA "-ioctl (2013-10-30)"
+
+/* Status bits */
+#define DM_READONLY_FLAG (1 << 0) /* In/Out */
+#define DM_SUSPEND_FLAG (1 << 1) /* In/Out */
+#define DM_PERSISTENT_DEV_FLAG (1 << 3) /* In */
+
+/*
+ * Flag passed into ioctl STATUS command to get table information
+ * rather than current status.
+ */
+#define DM_STATUS_TABLE_FLAG (1 << 4) /* In */
+
+/*
+ * Flags that indicate whether a table is present in either of
+ * the two table slots that a device has.
+ */
+#define DM_ACTIVE_PRESENT_FLAG (1 << 5) /* Out */
+#define DM_INACTIVE_PRESENT_FLAG (1 << 6) /* Out */
+
+/*
+ * Indicates that the buffer passed in wasn't big enough for the
+ * results.
+ */
+#define DM_BUFFER_FULL_FLAG (1 << 8) /* Out */
+
+/*
+ * This flag is now ignored.
+ */
+#define DM_SKIP_BDGET_FLAG (1 << 9) /* In */
+
+/*
+ * Set this to avoid attempting to freeze any filesystem when suspending.
+ */
+#define DM_SKIP_LOCKFS_FLAG (1 << 10) /* In */
+
+/*
+ * Set this to suspend without flushing queued ios.
+ * Also disables flushing uncommitted changes in the thin target before
+ * generating statistics for DM_TABLE_STATUS and DM_DEV_WAIT.
+ */
+#define DM_NOFLUSH_FLAG (1 << 11) /* In */
+
+/*
+ * If set, any table information returned will relate to the inactive
+ * table instead of the live one. Always check DM_INACTIVE_PRESENT_FLAG
+ * is set before using the data returned.
+ */
+#define DM_QUERY_INACTIVE_TABLE_FLAG (1 << 12) /* In */
+
+/*
+ * If set, a uevent was generated for which the caller may need to wait.
+ */
+#define DM_UEVENT_GENERATED_FLAG (1 << 13) /* Out */
+
+/*
+ * If set, rename changes the uuid not the name. Only permitted
+ * if no uuid was previously supplied: an existing uuid cannot be changed.
+ */
+#define DM_UUID_FLAG (1 << 14) /* In */
+
+/*
+ * If set, all buffers are wiped after use. Use when sending
+ * or requesting sensitive data such as an encryption key.
+ */
+#define DM_SECURE_DATA_FLAG (1 << 15) /* In */
+
+/*
+ * If set, a message generated output data.
+ */
+#define DM_DATA_OUT_FLAG (1 << 16) /* Out */
+
+/*
+ * If set with DM_DEV_REMOVE or DM_REMOVE_ALL this indicates that if
+ * the device cannot be removed immediately because it is still in use
+ * it should instead be scheduled for removal when it gets closed.
+ *
+ * On return from DM_DEV_REMOVE, DM_DEV_STATUS or other ioctls, this
+ * flag indicates that the device is scheduled to be removed when it
+ * gets closed.
+ */
+#define DM_DEFERRED_REMOVE (1 << 17) /* In/Out */
+
+#endif /* _LINUX_DM_IOCTL_H */
}
} else {
+ char usec[7];
+
gettime_r = (flags & OUTPUT_UTC) ? gmtime_r : localtime_r;
t = (time_t) (x / USEC_PER_SEC);
case OUTPUT_SHORT_ISO:
if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm)) <= 0) {
- log_error("Failed for format ISO time");
+ log_error("Failed to format ISO time");
+ return -EINVAL;
+ }
+ break;
+
+ case OUTPUT_SHORT_ISO_PRECISE:
+ /* No usec in strftime, so we leave space and copy over */
+ if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.xxxxxx%z", gettime_r(&t, &tm)) <= 0) {
+ log_error("Failed to format ISO-precise time");
return -EINVAL;
}
+ xsprintf(usec, "%06"PRI_USEC, x % USEC_PER_SEC);
+ memcpy(buf + 20, usec, 6);
break;
case OUTPUT_SHORT:
_cleanup_free_ char *cursor = NULL;
uint64_t realtime = 0;
char ts[FORMAT_TIMESTAMP_MAX + 7];
+ const char *timestamp;
int r;
assert(f);
if (r < 0)
return log_error_errno(r, "Failed to get cursor: %m");
+ timestamp = flags & OUTPUT_UTC ? format_timestamp_us_utc(ts, sizeof ts, realtime)
+ : format_timestamp_us(ts, sizeof ts, realtime);
fprintf(f, "%s [%s]\n",
- flags & OUTPUT_UTC ?
- format_timestamp_us_utc(ts, sizeof(ts), realtime) :
- format_timestamp_us(ts, sizeof(ts), realtime),
+ timestamp ?: "(no timestamp)",
cursor);
JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
[OUTPUT_SHORT] = output_short,
[OUTPUT_SHORT_ISO] = output_short,
+ [OUTPUT_SHORT_ISO_PRECISE] = output_short,
[OUTPUT_SHORT_PRECISE] = output_short,
[OUTPUT_SHORT_MONOTONIC] = output_short,
[OUTPUT_SHORT_UNIX] = output_short,
n_columns = columns();
ret = output_funcs[mode](f, j, mode, n_columns, flags);
- fflush(stdout);
if (ellipsized && ret > 0)
*ellipsized = true;
--- /dev/null
+shared_sources = '''
+ acl-util.h
+ acpi-fpdt.c
+ acpi-fpdt.h
+ apparmor-util.c
+ apparmor-util.h
+ ask-password-api.c
+ ask-password-api.h
+ base-filesystem.c
+ base-filesystem.h
+ boot-timestamps.c
+ boot-timestamps.h
+ bus-unit-util.c
+ bus-unit-util.h
+ bus-util.c
+ bus-util.h
+ cgroup-show.c
+ cgroup-show.h
+ clean-ipc.c
+ clean-ipc.h
+ condition.c
+ condition.h
+ conf-parser.c
+ conf-parser.h
+ dev-setup.c
+ dev-setup.h
+ dissect-image.c
+ dissect-image.h
+ dns-domain.c
+ dns-domain.h
+ dropin.c
+ dropin.h
+ efivars.c
+ efivars.h
+ fdset.c
+ fdset.h
+ firewall-util.h
+ fstab-util.c
+ fstab-util.h
+ gcrypt-util.c
+ gcrypt-util.h
+ generator.c
+ generator.h
+ gpt.h
+ ima-util.c
+ ima-util.h
+ import-util.c
+ import-util.h
+ initreq.h
+ install.c
+ install.h
+ install-printf.c
+ install-printf.h
+ journal-util.c
+ journal-util.h
+ logs-show.c
+ logs-show.h
+ loop-util.c
+ loop-util.h
+ machine-image.c
+ machine-image.h
+ machine-pool.c
+ machine-pool.h
+ nsflags.c
+ nsflags.h
+ output-mode.c
+ output-mode.h
+ pager.c
+ pager.h
+ path-lookup.c
+ path-lookup.h
+ ptyfwd.c
+ ptyfwd.h
+ resolve-util.c
+ resolve-util.h
+ seccomp-util.h
+ sleep-config.c
+ sleep-config.h
+ spawn-ask-password-agent.c
+ spawn-ask-password-agent.h
+ spawn-polkit-agent.c
+ spawn-polkit-agent.h
+ specifier.c
+ specifier.h
+ switch-root.c
+ switch-root.h
+ sysctl-util.c
+ sysctl-util.h
+ tests.c
+ tests.h
+ udev-util.h
+ udev-util.c
+ uid-range.c
+ uid-range.h
+ utmp-wtmp.h
+ vlan-util.c
+ vlan-util.h
+ volatile-util.c
+ volatile-util.h
+ watchdog.c
+ watchdog.h
+'''.split()
+
+test_tables_h = files('test-tables.h')
+shared_sources += [test_tables_h]
+
+if conf.get('HAVE_ACL', false)
+ shared_sources += ['acl-util.c']
+endif
+
+if conf.get('HAVE_UTMP', false)
+ shared_sources += ['utmp-wtmp.c']
+endif
+
+if conf.get('HAVE_SECCOMP', false)
+ shared_sources += ['seccomp-util.c']
+endif
+
+if conf.get('HAVE_LIBIPTC', false)
+ shared_sources += ['firewall-util.c']
+endif
+
+libshared_name = 'systemd-shared-@0@'.format(meson.project_version())
+
+libshared_deps = [threads,
+ librt,
+ libcap,
+ libacl,
+ libcryptsetup,
+ libgcrypt,
+ libiptc,
+ libseccomp,
+ libselinux,
+ libidn,
+ libxz,
+ liblz4,
+ libblkid]
+
+libshared = shared_library(
+ libshared_name,
+ shared_sources,
+ basic_sources,
+ journal_internal_sources,
+ libsystemd_internal_sources,
+ libudev_sources,
+ include_directories : includes,
+ link_args : ['-shared'],
+ c_args : ['-fvisibility=default'],
+ dependencies : libshared_deps,
+ install : true,
+ install_dir : rootlibexecdir)
+
+libshared_static = static_library(
+ libshared_name,
+ shared_sources,
+ basic_sources,
+ include_directories : includes,
+ dependencies : libshared_deps)
[OUTPUT_SHORT] = "short",
[OUTPUT_SHORT_FULL] = "short-full",
[OUTPUT_SHORT_ISO] = "short-iso",
+ [OUTPUT_SHORT_ISO_PRECISE] = "short-iso-precise",
[OUTPUT_SHORT_PRECISE] = "short-precise",
[OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
[OUTPUT_SHORT_UNIX] = "short-unix",
OUTPUT_SHORT,
OUTPUT_SHORT_FULL,
OUTPUT_SHORT_ISO,
+ OUTPUT_SHORT_ISO_PRECISE,
OUTPUT_SHORT_PRECISE,
OUTPUT_SHORT_MONOTONIC,
OUTPUT_SHORT_UNIX,
_exit(EXIT_SUCCESS);
}
+static int stored_stdout = -1;
+static int stored_stderr = -1;
+static bool stdout_redirected = false;
+static bool stderr_redirected = false;
+
int pager_open(bool no_pager, bool jump_to_end) {
_cleanup_close_pair_ int fd[2] = { -1, -1 };
const char *pager;
}
/* Return in the parent */
- if (dup2(fd[1], STDOUT_FILENO) < 0)
+ stored_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);
+ if (dup2(fd[1], STDOUT_FILENO) < 0) {
+ stored_stdout = safe_close(stored_stdout);
return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
- if (dup2(fd[1], STDERR_FILENO) < 0)
+ }
+ stdout_redirected = true;
+
+ stored_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
+ if (dup2(fd[1], STDERR_FILENO) < 0) {
+ stored_stderr = safe_close(stored_stderr);
return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
+ }
+ stderr_redirected = true;
return 1;
}
return;
/* Inform pager that we are done */
- stdout = safe_fclose(stdout);
- stderr = safe_fclose(stderr);
+ (void) fflush(stdout);
+ if (stdout_redirected)
+ if (stored_stdout < 0 || dup2(stored_stdout, STDOUT_FILENO) < 0)
+ (void) close(STDOUT_FILENO);
+ stored_stdout = safe_close(stored_stdout);
+ (void) fflush(stderr);
+ if (stderr_redirected)
+ if (stored_stderr < 0 || dup2(stored_stderr, STDERR_FILENO) < 0)
+ (void) close(STDERR_FILENO);
+ stored_stderr = safe_close(stored_stderr);
+ stdout_redirected = stderr_redirected = false;
(void) kill(pager_pid, SIGCONT);
(void) wait_for_terminate(pager_pid, NULL);
SECCOMP_FOREACH_LOCAL_ARCH(arch) {
_cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
- int clone_reversed_order = -1;
unsigned i;
log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
- switch (arch) {
-
- case SCMP_ARCH_X86_64:
- case SCMP_ARCH_X86:
- case SCMP_ARCH_X32:
- case SCMP_ARCH_PPC64:
- case SCMP_ARCH_PPC64LE:
- clone_reversed_order = 0;
- break;
-
- case SCMP_ARCH_S390:
- case SCMP_ARCH_S390X:
- /* On s390/s390x the first two parameters to clone are switched */
- clone_reversed_order = 1;
- break;
-
- /* Please add more definitions here, if you port systemd to other architectures! */
-
-#if SECCOMP_RESTRICT_NAMESPACES_BROKEN
-# warning "Consider adding the right clone() syscall definitions here!"
-#endif
- }
-
- if (clone_reversed_order < 0) /* we don't know the right order, let's ignore this arch... */
- continue;
-
r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
if (r < 0)
return r;
break;
}
- if (clone_reversed_order == 0)
+ /* On s390/s390x the first two parameters to clone are switched */
+ if (!IN_SET(arch, SCMP_ARCH_S390, SCMP_ARCH_S390X))
r = seccomp_rule_add_exact(
seccomp,
SCMP_ACT_ERRNO(EPERM),
case SCMP_ARCH_X32:
case SCMP_ARCH_ARM:
case SCMP_ARCH_AARCH64:
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
/* These we know we support (i.e. are the ones that do not use socketcall()) */
supported = true;
break;
- case SCMP_ARCH_X86:
case SCMP_ARCH_S390:
case SCMP_ARCH_S390X:
case SCMP_ARCH_PPC:
- case SCMP_ARCH_PPC64:
- case SCMP_ARCH_PPC64LE:
+ case SCMP_ARCH_X86:
default:
/* These we either know we don't support (i.e. are the ones that do use socketcall()), or we
* don't know */
return 0;
}
+static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp,
+ uint32_t arch,
+ int nr,
+ unsigned int arg_cnt,
+ const struct scmp_arg_cmp arg) {
+ int r;
+
+ r = seccomp_rule_add_exact(seccomp, SCMP_ACT_ERRNO(EPERM), nr, arg_cnt, arg);
+ if (r < 0) {
+ _cleanup_free_ char *n = NULL;
+
+ n = seccomp_syscall_resolve_num_arch(arch, nr);
+ log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
+ strna(n),
+ seccomp_arch_to_string(arch));
+ }
+
+ return r;
+}
+
+/* For known architectures, check that syscalls are indeed defined or not. */
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+assert_cc(SCMP_SYS(shmget) > 0);
+assert_cc(SCMP_SYS(shmat) > 0);
+assert_cc(SCMP_SYS(shmdt) > 0);
+#elif defined(__i386__) || defined(__powerpc64__)
+assert_cc(SCMP_SYS(shmget) < 0);
+assert_cc(SCMP_SYS(shmat) < 0);
+assert_cc(SCMP_SYS(shmdt) < 0);
+#endif
+
int seccomp_memory_deny_write_execute(void) {
uint32_t arch;
case SCMP_ARCH_X86:
filter_syscall = SCMP_SYS(mmap2);
block_syscall = SCMP_SYS(mmap);
+ break;
+
+ case SCMP_ARCH_PPC64:
+ case SCMP_ARCH_PPC64LE:
+ filter_syscall = SCMP_SYS(mmap);
+
+ /* Note that shmat() isn't available, and the call is multiplexed through ipc().
+ * We ignore that here, which means there's still a way to get writable/executable
+ * memory, if an IPC key is mapped like this. That's a pity, but no total loss. */
- /* Note that shmat() isn't available on i386, where the call is multiplexed through ipc(). We
- * ignore that here, which means there's still a way to get writable/executable memory, if an
- * IPC key is mapped like this on i386. That's a pity, but no total loss. */
+ break;
+
+ case SCMP_ARCH_AARCH64:
+ block_syscall = SCMP_SYS(mmap);
+ /* fall through */
+
+ case SCMP_ARCH_ARM:
+ filter_syscall = SCMP_SYS(mmap2); /* arm has only mmap2 */
+ shmat_syscall = SCMP_SYS(shmat);
break;
case SCMP_ARCH_X86_64:
case SCMP_ARCH_X32:
- filter_syscall = SCMP_SYS(mmap);
+ filter_syscall = SCMP_SYS(mmap); /* amd64 and x32 have only mmap */
shmat_syscall = SCMP_SYS(shmat);
break;
/* Please add more definitions here, if you port systemd to other architectures! */
-#if !defined(__i386__) && !defined(__x86_64__)
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__)
#warning "Consider adding the right mmap() syscall definitions here!"
#endif
}
if (r < 0)
return r;
- if (filter_syscall != 0) {
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- filter_syscall,
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC|PROT_WRITE, PROT_EXEC|PROT_WRITE));
- if (r < 0) {
- _cleanup_free_ char *n = NULL;
-
- n = seccomp_syscall_resolve_num_arch(arch, filter_syscall);
- log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
- strna(n),
- seccomp_arch_to_string(arch));
- continue;
- }
- }
+ r = add_seccomp_syscall_filter(seccomp, arch, filter_syscall,
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC|PROT_WRITE, PROT_EXEC|PROT_WRITE));
+ if (r < 0)
+ continue;
if (block_syscall != 0) {
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- block_syscall,
- 0);
- if (r < 0) {
- _cleanup_free_ char *n = NULL;
-
- n = seccomp_syscall_resolve_num_arch(arch, block_syscall);
- log_debug_errno(r, "Failed to add %s() rule for architecture %s, skipping: %m",
- strna(n),
- seccomp_arch_to_string(arch));
+ r = add_seccomp_syscall_filter(seccomp, arch, block_syscall, 0, (const struct scmp_arg_cmp){} );
+ if (r < 0)
continue;
- }
}
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(mprotect),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
- if (r < 0) {
- log_debug_errno(r, "Failed to add mprotect() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(mprotect),
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
+ if (r < 0)
continue;
- }
if (shmat_syscall != 0) {
- r = seccomp_rule_add_exact(
- seccomp,
- SCMP_ACT_ERRNO(EPERM),
- SCMP_SYS(shmat),
- 1,
- SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
- if (r < 0) {
- log_debug_errno(r, "Failed to add shmat() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+ r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(shmat),
+ 1,
+ SCMP_A2(SCMP_CMP_MASKED_EQ, SHM_EXEC, SHM_EXEC));
+ if (r < 0)
continue;
- }
}
r = seccomp_load(seccomp);
int seccomp_restrict_realtime(void);
int seccomp_memory_deny_write_execute(void);
-#if defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__) || defined (__mips__)
-/* On these archs, socket() is implemented via the socketcall() syscall multiplexer, and we can't restrict it hence via
- * seccomp */
-#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1
-#else
-#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
-#endif
-
-/* mmap() blocking is only available on some archs for now */
-#if defined(__x86_64__) || defined(__i386__)
-#define SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN 0
-#else
-#define SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN 1
-#endif
-
-/* we don't know the right order of the clone() parameters except for these archs, for now */
-#if defined(__x86_64__) || defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__)
-#define SECCOMP_RESTRICT_NAMESPACES_BROKEN 0
-#else
-#define SECCOMP_RESTRICT_NAMESPACES_BROKEN 1
-#endif
-
extern const uint32_t seccomp_local_archs[];
#define SECCOMP_FOREACH_LOCAL_ARCH(arch) \
};
config_parse_many_nulstr(PKGSYSCONFDIR "/sleep.conf",
- CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
- "Sleep\0", config_item_table_lookup, items,
- false, NULL);
+ CONF_PATHS_NULSTR("systemd/sleep.conf.d"),
+ "Sleep\0", config_item_table_lookup, items,
+ false, NULL);
if (streq(verb, "suspend")) {
/* empty by default */
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <string.h>
+
+#include "fileio.h"
+#include "log.h"
+#include "string-util.h"
+#include "udev-util.h"
+
+int udev_parse_config(void) {
+ _cleanup_free_ char *val = NULL;
+ const char *log;
+ size_t n;
+ int r;
+
+ r = parse_env_file("/etc/udev/udev.conf", NEWLINE, "udev_log", &val, NULL);
+ if (r == -ENOENT || !val)
+ return 0;
+ if (r < 0)
+ return r;
+
+ /* unquote */
+ n = strlen(val);
+ if (n >= 2 &&
+ ((val[0] == '"' && val[n-1] == '"') ||
+ (val[0] == '\'' && val[n-1] == '\''))) {
+ val[n - 1] = '\0';
+ log = val + 1;
+ } else
+ log = val;
+
+ /* we set the udev log level here explicitly, this is supposed
+ * to regulate the code in libudev/ and udev/. */
+ r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log);
+ if (r < 0)
+ log_debug_errno(r, "/etc/udev/udev.conf: failed to set udev log level '%s', ignoring: %m", log);
+
+ return 0;
+}
#define _cleanup_udev_ctrl_msg_unref_ _cleanup_(udev_ctrl_msg_unrefp)
#define _cleanup_udev_monitor_unref_ _cleanup_(udev_monitor_unrefp)
#define _cleanup_udev_list_cleanup_ _cleanup_(udev_list_cleanup)
+
+int udev_parse_config(void);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "vlan-util.h"
-#include "parse-util.h"
#include "conf-parser.h"
+#include "parse-util.h"
+#include "string-util.h"
+#include "vlan-util.h"
int parse_vlanid(const char *p, uint16_t *ret) {
uint16_t id;
return 0;
}
+int config_parse_default_port_vlanid(
+ 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) {
+ uint16_t *id = data;
+
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ if (streq(rvalue, "none")) {
+ *id = 0;
+ return 0;
+ }
+
+ return config_parse_vlanid(unit, filename, line, section, section_line,
+ lvalue, ltype, rvalue, data, userdata);
+}
+
int config_parse_vlanid(
const char *unit,
const char *filename,
int parse_vlanid(const char *p, uint16_t *ret);
+int config_parse_default_port_vlanid(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);
int config_parse_vlanid(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);
in_fd = SD_LISTEN_FDS_START;
out_fd = SD_LISTEN_FDS_START;
} else {
- log_error("Illegal number of file descriptors passed\n");
+ log_error("Illegal number of file descriptors passed.");
goto finish;
}
}
for (;;) {
- _cleanup_(sd_bus_message_unrefp)sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
int events_a, events_b, fd;
uint64_t timeout_a, timeout_b, t;
struct timespec _ts, *ts;
r = ppoll(p, ELEMENTSOF(p), ts, NULL);
}
if (r < 0) {
- log_error("ppoll() failed: %m");
+ log_error_errno(errno, "ppoll() failed: %m");
goto finish;
}
}
--- /dev/null
+systemd-sulogin-shell
--- /dev/null
+gen = configure_file(
+ input : 'systemd-sulogin-shell.in',
+ output : 'systemd-sulogin-shell',
+ configuration : substs)
+
+install_data(gen,
+ install_dir : rootlibexecdir)
--- /dev/null
+#!/bin/sh
+
+if [ -x /bin/plymouth ]; then
+ /bin/plymouth --wait quit
+fi
+
+echo "You are in $1 mode. After logging in, type \"journalctl -xb\" to view"
+echo "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or ^D to boot"
+echo "into default mode."
+
+@SULOGIN@
+@SYSTEMCTL@ --job-mode=fail --no-block default
#include "dropin.h"
#include "efivars.h"
#include "env-util.h"
+#include "escape.h"
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
STRV_FOREACH(c, deps) {
if (strv_contains(*units, *c)) {
if (!arg_plain) {
+ printf(" ");
r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
if (r < 0)
return r;
return r;
}
+#ifdef ENABLE_LOGIND
static int logind_set_wall_message(void) {
-#ifdef HAVE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
_cleanup_free_ char *m = NULL;
if (r < 0)
return log_warning_errno(r, "Failed to set wall message, ignoring: %s", bus_error_message(&error, r));
-
-#endif
return 0;
}
+#endif
/* Ask systemd-logind, which might grant access to unprivileged users
* through PolicyKit */
static int logind_reboot(enum action a) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
const char *method, *description;
sd_bus *bus;
}
static int logind_check_inhibitors(enum action a) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_strv_free_ char **sessions = NULL;
const char *what, *who, *why, *mode;
}
static int logind_prepare_firmware_setup(void) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
int r;
bool failed_assert_negate;
const char *failed_assert;
const char *failed_assert_parameter;
+ usec_t next_elapse_real;
+ usec_t next_elapse_monotonic;
/* Socket */
unsigned n_accepted;
else
printf("\n");
+ if (endswith(i->id, ".timer")) {
+ char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
+ tstamp2[FORMAT_TIMESTAMP_MAX];
+ char *next_rel_time, *next_time;
+ dual_timestamp nw, next = {i->next_elapse_real,
+ i->next_elapse_monotonic};
+ usec_t next_elapse;
+
+ printf(" Trigger: ");
+
+ dual_timestamp_get(&nw);
+ next_elapse = calc_next_elapse(&nw, &next);
+ next_rel_time = format_timestamp_relative(tstamp1,
+ sizeof(tstamp1),
+ next_elapse);
+ next_time = format_timestamp(tstamp2,
+ sizeof(tstamp2),
+ next_elapse);
+
+ if (next_time && next_rel_time)
+ printf("%s; %s\n", next_time, next_rel_time);
+ else
+ printf("n/a\n");
+ }
+
if (!i->condition_result && i->condition_timestamp > 0) {
UnitCondition *c;
int n = 0;
i->tasks_max = u;
else if (streq(name, "CPUUsageNSec"))
i->cpu_usage_nsec = u;
+ else if (streq(name, "NextElapseUSecMonotonic"))
+ i->next_elapse_monotonic = u;
+ else if (streq(name, "NextElapseUSecRealtime"))
+ i->next_elapse_real = u;
break;
}
return r;
}
+static int print_variable(const char *s) {
+ const char *sep;
+ _cleanup_free_ char *esc = NULL;
+
+ sep = strchr(s, '=');
+ if (!sep) {
+ log_error("Invalid environment block");
+ return -EUCLEAN;
+ }
+
+ esc = shell_maybe_quote(sep + 1, ESCAPE_POSIX);
+ if (!esc)
+ return log_oom();
+
+ printf("%.*s=%s\n", (int)(sep-s), s, esc);
+ return 0;
+}
+
static int show_environment(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
if (r < 0)
return bus_log_parse_error(r);
- while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
- puts(text);
+ while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0) {
+ r = print_variable(text);
+ if (r < 0)
+ return r;
+ }
if (r < 0)
return bus_log_parse_error(r);
/* If the passed init is actually the same as the
* systemd binary, then let's suppress it. */
- if (files_same(root_init_path, root_systemd_path) > 0)
+ if (files_same(root_init_path, root_systemd_path, 0) > 0)
init = NULL;
}
if (!l)
return log_oom();
- log_info("Executing: %s", l);
+ if (!arg_quiet)
+ log_info("Executing: %s", l);
pid = fork();
if (pid < 0)
return 0;
}
+static int normalize_filenames(char **names) {
+ char **u;
+ int r;
+
+ STRV_FOREACH(u, names)
+ if (!path_is_absolute(*u)) {
+ char* normalized_path;
+
+ if (!isempty(arg_root)) {
+ log_error("Non-absolute paths are not allowed when --root is used: %s", *u);
+ return -EINVAL;
+ }
+
+ if (!strchr(*u,'/')) {
+ log_error("Link argument does contain at least one directory separator: %s", *u);
+ return -EINVAL;
+ }
+
+ r = path_make_absolute_cwd(*u, &normalized_path);
+ if (r < 0)
+ return r;
+
+ free_and_replace(*u, normalized_path);
+ }
+
+ return 0;
+}
+
static int normalize_names(char **names, bool warn_if_path) {
char **u;
bool was_path = false;
return r;
}
+ if (streq(verb, "link")) {
+ r = normalize_filenames(names);
+ if (r < 0)
+ return r;
+ }
+
if (install_client_side()) {
UnitFileFlags flags;
" --root=PATH Enable unit files in the specified root directory\n"
" -n --lines=INTEGER Number of journal entries to show\n"
" -o --output=STRING Change journal output mode (short, short-precise,\n"
- " short-iso, short-full, short-monotonic, short-unix,\n"
+ " short-iso, short-iso-precise, short-full,\n"
+ " short-monotonic, short-unix,\n"
" verbose, export, json, json-pretty, json-sse, cat)\n"
" --firmware-setup Tell the firmware to show the setup menu on next boot\n"
" --plain Print unit dependencies as a list instead of a tree\n\n"
switch (a) {
case ACTION_HALT:
- log_info("Halting.");
+ if (!arg_quiet)
+ log_info("Halting.");
(void) reboot(RB_HALT_SYSTEM);
return -errno;
case ACTION_POWEROFF:
- log_info("Powering off.");
+ if (!arg_quiet)
+ log_info("Powering off.");
(void) reboot(RB_POWER_OFF);
return -errno;
_cleanup_free_ char *param = NULL;
r = read_one_line_file("/run/systemd/reboot-param", ¶m);
- if (r < 0)
+ if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read reboot parameter file: %m");
if (!isempty(param)) {
- log_info("Rebooting with argument '%s'.", param);
+ if (!arg_quiet)
+ log_info("Rebooting with argument '%s'.", param);
(void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
}
- log_info("Rebooting.");
+ if (!arg_quiet)
+ log_info("Rebooting.");
(void) reboot(RB_AUTOBOOT);
return -errno;
}
static int logind_schedule_shutdown(void) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char date[FORMAT_TIMESTAMP_MAX];
const char *action;
if (r < 0)
return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
- log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
+ if (!arg_quiet)
+ log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
return 0;
#else
log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
}
static int logind_cancel_shutdown(void) {
-#ifdef HAVE_LOGIND
+#ifdef ENABLE_LOGIND
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
int r;
goto finish;
if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
- log_info("Running in chroot, ignoring request.");
+
+ if (!arg_quiet)
+ log_info("Running in chroot, ignoring request.");
r = 0;
goto finish;
}
/* This is a private header; never even think of including this directly! */
-#if __INCLUDE_LEVEL__ <= 1
-#error "Do not include _sd-common.h directly; it is a private header."
+#if defined(__INCLUDE_LEVEL__) && __INCLUDE_LEVEL__ <= 1
+# error "Do not include _sd-common.h directly; it is a private header."
#endif
#ifndef _sd_printf_
--- /dev/null
+_systemd_headers = '''
+ sd-bus.h
+ sd-bus-protocol.h
+ sd-bus-vtable.h
+ sd-daemon.h
+ sd-event.h
+ sd-id128.h
+ sd-journal.h
+ sd-login.h
+ sd-messages.h
+'''.split()
+
+# https://github.com/mesonbuild/meson/issues/1633
+systemd_headers = files(_systemd_headers)
+
+# sd-device.h
+# sd-hwdb.h
+# sd-dhcp6-client.h
+# sd-dhcp6-lease.h
+# sd-dhcp-client.h
+# sd-dhcp-lease.h
+# sd-dhcp-server.h
+# sd-ipv4acd.h
+# sd-ipv4ll.h
+# sd-lldp.h
+# sd-ndisc.h
+# sd-netlink.h
+# sd-network.h
+# sd-path.h
+# sd-resolve.h
+# sd-utf8.h
+
+install_headers(
+ systemd_headers,
+ '_sd-common.h',
+ subdir : 'systemd')
+
+
+############################################################
+
+opts = [['c'],
+ ['c', '-ansi'],
+ ['c', '-std=iso9899:1990']]
+
+cxx = find_program('c++', required : false)
+if cxx.found()
+ opts += [['c++']]
+endif
+
+foreach header : _systemd_headers
+ foreach opt : opts
+ name = ''.join([header, ':'] + opt)
+ test('cc-' + name,
+ check_compilation_sh,
+ args : cc.cmd_array() + ['-c', '-x'] + opt +
+ ['-Werror', '-include',
+ join_paths(meson.current_source_dir(), header)])
+ endforeach
+endforeach
.member = _member, \
.signature = _signature, \
.get = _get, \
+ .set = NULL, \
.offset = _offset, \
}, \
}, \
#define SD_BUS_VTABLE_END \
{ \
.type = _SD_BUS_VTABLE_END, \
+ .flags = 0, \
+ .x = { \
+ }, \
}
_SD_END_DECLARATIONS;
int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority);
int sd_bus_message_append(sd_bus_message *m, const char *types, ...);
+int sd_bus_message_appendv(sd_bus_message *m, const char *types, va_list ap);
int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p);
int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size);
int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr);
SD_DHCP_OPTION_FQDN = 81,
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
SD_DHCP_OPTION_NEW_TZDB_TIMEZONE = 101,
+ SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
SD_DHCP_OPTION_PRIVATE_LAST = 254,
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
+int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
typedef int (*sd_event_io_handler_t)(sd_event_source *s, int fd, uint32_t revents, void *userdata);
typedef int (*sd_event_time_handler_t)(sd_event_source *s, uint64_t usec, void *userdata);
typedef int (*sd_event_signal_handler_t)(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata);
-#if defined __USE_POSIX199309 || defined __USE_XOPEN_EXTENDED
+#if defined _GNU_SOURCE || _POSIX_C_SOURCE >= 199309L
typedef int (*sd_event_child_handler_t)(sd_event_source *s, const siginfo_t *si, void *userdata);
#else
typedef void* sd_event_child_handler_t;
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address);
int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint64_t seed);
int sd_ipv4ll_is_running(sd_ipv4ll *ll);
+int sd_ipv4ll_restart(sd_ipv4ll *ll);
int sd_ipv4ll_start(sd_ipv4ll *ll);
int sd_ipv4ll_stop(sd_ipv4ll *ll);
sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll);
int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state);
int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags);
+int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family);
+int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen);
+
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref);
--- /dev/null
+#ifndef foosdradvfoo
+#define foosdradvfoo
+
+/***
+ This file is part of systemd.
+
+ Copyright (C) 2017 Intel Corporation. All rights reserved.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <net/ethernet.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+
+#include "sd-ndisc.h"
+
+#include "sd-event.h"
+
+#include "_sd-common.h"
+
+_SD_BEGIN_DECLARATIONS;
+
+typedef struct sd_radv sd_radv;
+typedef struct sd_radv_prefix sd_radv_prefix;
+
+/* Router Advertisment */
+int sd_radv_new(sd_radv **ret);
+sd_radv *sd_radv_ref(sd_radv *ra);
+sd_radv *sd_radv_unref(sd_radv *ra);
+
+int sd_radv_attach_event(sd_radv *ra, sd_event *event, int64_t priority);
+int sd_radv_detach_event(sd_radv *nd);
+sd_event *sd_radv_get_event(sd_radv *ra);
+
+int sd_radv_start(sd_radv *ra);
+int sd_radv_stop(sd_radv *ra);
+
+int sd_radv_set_ifindex(sd_radv *ra, int interface_index);
+int sd_radv_set_mac(sd_radv *ra, const struct ether_addr *mac_addr);
+int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu);
+int sd_radv_set_hop_limit(sd_radv *ra, uint8_t hop_limit);
+int sd_radv_set_router_lifetime(sd_radv *ra, uint32_t router_lifetime);
+int sd_radv_set_managed_information(sd_radv *ra, int managed);
+int sd_radv_set_other_information(sd_radv *ra, int other);
+int sd_radv_set_preference(sd_radv *ra, unsigned preference);
+int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p);
+
+/* Advertised prefixes */
+int sd_radv_prefix_new(sd_radv_prefix **ret);
+sd_radv_prefix *sd_radv_prefix_ref(sd_radv_prefix *ra);
+sd_radv_prefix *sd_radv_prefix_unref(sd_radv_prefix *ra);
+
+int sd_radv_prefix_set_prefix(sd_radv_prefix *p, struct in6_addr *in6_addr,
+ unsigned char prefixlen);
+int sd_radv_prefix_set_onlink(sd_radv_prefix *p, int onlink);
+int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix *p,
+ int address_autoconfiguration);
+int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix *p,
+ uint32_t valid_lifetime);
+int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix *p,
+ uint32_t preferred_lifetime);
+
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv, sd_radv_unref);
+_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_radv_prefix, sd_radv_prefix_unref);
+
+_SD_END_DECLARATIONS;
+
+#endif
#include "copy.h"
#include "def.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "fileio-label.h"
#include "format-util.h"
#include "hashmap.h"
return 0;
}
+#ifdef ENABLE_GSHADOW
static int putsgent_with_members(const struct sgrp *sg, FILE *gshadow) {
char **a;
return 0;
}
+#endif
static int sync_rights(FILE *from, FILE *to) {
struct stat st;
return r;
}
-static int write_files(void) {
-
- _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL;
- _cleanup_free_ char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
- const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL;
- bool group_changed = false;
+static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char **tmpfile_path) {
+ _cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
+ _cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
Iterator iterator;
Item *i;
int r;
- if (hashmap_size(todo_gids) > 0 || hashmap_size(members) > 0) {
- _cleanup_fclose_ FILE *original = NULL;
+ if (hashmap_size(todo_uids) == 0)
+ return 0;
- /* First we update the actual group list file */
- group_path = prefix_roota(arg_root, "/etc/group");
- r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
+ r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
+ if (r < 0)
+ return r;
+
+ original = fopen(passwd_path, "re");
+ if (original) {
+ struct passwd *pw;
+
+ r = sync_rights(original, passwd);
if (r < 0)
- goto finish;
+ return r;
- original = fopen(group_path, "re");
- if (original) {
- struct group *gr;
+ errno = 0;
+ while ((pw = fgetpwent(original))) {
- r = sync_rights(original, group);
- if (r < 0)
- goto finish;
+ i = hashmap_get(users, pw->pw_name);
+ if (i && i->todo_user) {
+ log_error("%s: User \"%s\" already exists.", passwd_path, pw->pw_name);
+ return -EEXIST;
+ }
+
+ if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
+ log_error("%s: Detected collision for UID " UID_FMT ".", passwd_path, pw->pw_uid);
+ return -EEXIST;
+ }
errno = 0;
- while ((gr = fgetgrent(original))) {
- /* Safety checks against name and GID
- * collisions. Normally, this should
- * be unnecessary, but given that we
- * look at the entries anyway here,
- * let's make an extra verification
- * step that we don't generate
- * duplicate entries. */
-
- i = hashmap_get(groups, gr->gr_name);
- if (i && i->todo_group) {
- log_error("%s: Group \"%s\" already exists.", group_path, gr->gr_name);
- r = -EEXIST;
- goto finish;
- }
+ if (putpwent(pw, passwd) < 0)
+ return errno ? -errno : -EIO;
- if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
- log_error("%s: Detected collision for GID " GID_FMT ".", group_path, gr->gr_gid);
- r = -EEXIST;
- goto finish;
- }
+ errno = 0;
+ }
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
- r = putgrent_with_members(gr, group);
- if (r < 0)
- goto finish;
- if (r > 0)
- group_changed = true;
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(passwd), 0644) < 0)
+ return -errno;
+ }
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
- }
+ HASHMAP_FOREACH(i, todo_uids, iterator) {
+ struct passwd n = {
+ .pw_name = i->name,
+ .pw_uid = i->uid,
+ .pw_gid = i->gid,
+ .pw_gecos = i->description,
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(group), 0644) < 0) {
- r = -errno;
- goto finish;
- }
+ /* "x" means the password is stored in the shadow file */
+ .pw_passwd = (char*) "x",
- HASHMAP_FOREACH(i, todo_gids, iterator) {
- struct group n = {
- .gr_name = i->name,
- .gr_gid = i->gid,
- .gr_passwd = (char*) "x",
- };
+ /* We default to the root directory as home */
+ .pw_dir = i->home ? i->home : (char*) "/",
- r = putgrent_with_members(&n, group);
- if (r < 0)
- goto finish;
+ /* Initialize the shell to nologin, with one exception:
+ * for root we patch in something special */
+ .pw_shell = i->uid == 0 ? (char*) "/bin/sh" : (char*) "/sbin/nologin",
+ };
- group_changed = true;
- }
+ errno = 0;
+ if (putpwent(&n, passwd) != 0)
+ return errno ? -errno : -EIO;
+ }
- r = fflush_and_check(group);
- if (r < 0)
- goto finish;
+ r = fflush_and_check(passwd);
+ if (r < 0)
+ return r;
- if (original) {
- fclose(original);
- original = NULL;
- }
+ *tmpfile = passwd;
+ *tmpfile_path = passwd_tmp;
+ passwd = NULL;
+ passwd_tmp = NULL;
+ return 0;
+}
- /* OK, now also update the shadow file for the group list */
- gshadow_path = prefix_roota(arg_root, "/etc/gshadow");
- r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
- if (r < 0)
- goto finish;
+static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char **tmpfile_path) {
+ _cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
+ _cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
+ Iterator iterator;
+ long lstchg;
+ Item *i;
+ int r;
- original = fopen(gshadow_path, "re");
- if (original) {
- struct sgrp *sg;
+ if (hashmap_size(todo_uids) == 0)
+ return 0;
- r = sync_rights(original, gshadow);
- if (r < 0)
- goto finish;
+ r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
+ if (r < 0)
+ return r;
- errno = 0;
- while ((sg = fgetsgent(original))) {
+ lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
- i = hashmap_get(groups, sg->sg_namp);
- if (i && i->todo_group) {
- log_error("%s: Group \"%s\" already exists.", gshadow_path, sg->sg_namp);
- r = -EEXIST;
- goto finish;
- }
+ original = fopen(shadow_path, "re");
+ if (original) {
+ struct spwd *sp;
- r = putsgent_with_members(sg, gshadow);
- if (r < 0)
- goto finish;
- if (r > 0)
- group_changed = true;
+ r = sync_rights(original, shadow);
+ if (r < 0)
+ return r;
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
- }
+ errno = 0;
+ while ((sp = fgetspent(original))) {
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(gshadow), 0000) < 0) {
- r = -errno;
- goto finish;
- }
+ i = hashmap_get(users, sp->sp_namp);
+ if (i && i->todo_user) {
+ /* we will update the existing entry */
+ sp->sp_lstchg = lstchg;
- HASHMAP_FOREACH(i, todo_gids, iterator) {
- struct sgrp n = {
- .sg_namp = i->name,
- .sg_passwd = (char*) "!!",
- };
+ /* only the /etc/shadow stage is left, so we can
+ * safely remove the item from the todo set */
+ i->todo_user = false;
+ hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
+ }
- r = putsgent_with_members(&n, gshadow);
- if (r < 0)
- goto finish;
+ errno = 0;
+ if (putspent(sp, shadow) < 0)
+ return errno ? -errno : -EIO;
- group_changed = true;
+ errno = 0;
}
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
- r = fflush_and_check(gshadow);
- if (r < 0)
- goto finish;
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(shadow), 0000) < 0)
+ return -errno;
}
- if (hashmap_size(todo_uids) > 0) {
- _cleanup_fclose_ FILE *original = NULL;
- long lstchg;
-
- /* First we update the user database itself */
- passwd_path = prefix_roota(arg_root, "/etc/passwd");
- r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
- if (r < 0)
- goto finish;
-
- original = fopen(passwd_path, "re");
- if (original) {
- struct passwd *pw;
+ HASHMAP_FOREACH(i, todo_uids, iterator) {
+ struct spwd n = {
+ .sp_namp = i->name,
+ .sp_pwdp = (char*) "!!",
+ .sp_lstchg = lstchg,
+ .sp_min = -1,
+ .sp_max = -1,
+ .sp_warn = -1,
+ .sp_inact = -1,
+ .sp_expire = -1,
+ .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
+ };
- r = sync_rights(original, passwd);
- if (r < 0)
- goto finish;
+ errno = 0;
+ if (putspent(&n, shadow) != 0)
+ return errno ? -errno : -EIO;
+ }
- errno = 0;
- while ((pw = fgetpwent(original))) {
+ r = fflush_and_check(shadow);
+ if (r < 0)
+ return r;
- i = hashmap_get(users, pw->pw_name);
- if (i && i->todo_user) {
- log_error("%s: User \"%s\" already exists.", passwd_path, pw->pw_name);
- r = -EEXIST;
- goto finish;
- }
+ *tmpfile = shadow;
+ *tmpfile_path = shadow_tmp;
+ shadow = NULL;
+ shadow_tmp = NULL;
+ return 0;
+}
- if (hashmap_contains(todo_uids, UID_TO_PTR(pw->pw_uid))) {
- log_error("%s: Detected collision for UID " UID_FMT ".", passwd_path, pw->pw_uid);
- r = -EEXIST;
- goto finish;
- }
+static int write_temporary_group(const char *group_path, FILE **tmpfile, char **tmpfile_path) {
+ _cleanup_fclose_ FILE *original = NULL, *group = NULL;
+ _cleanup_(unlink_and_freep) char *group_tmp = NULL;
+ bool group_changed = false;
+ Iterator iterator;
+ Item *i;
+ int r;
- errno = 0;
- if (putpwent(pw, passwd) < 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
+ if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0)
+ return 0;
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
- }
+ r = fopen_temporary_label("/etc/group", group_path, &group, &group_tmp);
+ if (r < 0)
+ return r;
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(passwd), 0644) < 0) {
- r = -errno;
- goto finish;
- }
+ original = fopen(group_path, "re");
+ if (original) {
+ struct group *gr;
- HASHMAP_FOREACH(i, todo_uids, iterator) {
- struct passwd n = {
- .pw_name = i->name,
- .pw_uid = i->uid,
- .pw_gid = i->gid,
- .pw_gecos = i->description,
+ r = sync_rights(original, group);
+ if (r < 0)
+ return r;
- /* "x" means the password is stored in
- * the shadow file */
- .pw_passwd = (char*) "x",
+ errno = 0;
+ while ((gr = fgetgrent(original))) {
+ /* Safety checks against name and GID collisions. Normally,
+ * this should be unnecessary, but given that we look at the
+ * entries anyway here, let's make an extra verification
+ * step that we don't generate duplicate entries. */
+
+ i = hashmap_get(groups, gr->gr_name);
+ if (i && i->todo_group) {
+ log_error("%s: Group \"%s\" already exists.", group_path, gr->gr_name);
+ return -EEXIST;
+ }
- /* We default to the root directory as home */
- .pw_dir = i->home ? i->home : (char*) "/",
+ if (hashmap_contains(todo_gids, GID_TO_PTR(gr->gr_gid))) {
+ log_error("%s: Detected collision for GID " GID_FMT ".", group_path, gr->gr_gid);
+ return -EEXIST;
+ }
- /* Initialize the shell to nologin,
- * with one exception: for root we
- * patch in something special */
- .pw_shell = i->uid == 0 ? (char*) "/bin/sh" : (char*) "/sbin/nologin",
- };
+ r = putgrent_with_members(gr, group);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ group_changed = true;
errno = 0;
- if (putpwent(&n, passwd) != 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
}
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
- r = fflush_and_check(passwd);
- if (r < 0)
- goto finish;
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(group), 0644) < 0)
+ return -errno;
+ }
- if (original) {
- fclose(original);
- original = NULL;
- }
+ HASHMAP_FOREACH(i, todo_gids, iterator) {
+ struct group n = {
+ .gr_name = i->name,
+ .gr_gid = i->gid,
+ .gr_passwd = (char*) "x",
+ };
- /* The we update the shadow database */
- shadow_path = prefix_roota(arg_root, "/etc/shadow");
- r = fopen_temporary_label("/etc/shadow", shadow_path, &shadow, &shadow_tmp);
+ r = putgrent_with_members(&n, group);
if (r < 0)
- goto finish;
+ return r;
- lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+ group_changed = true;
+ }
- original = fopen(shadow_path, "re");
- if (original) {
- struct spwd *sp;
+ r = fflush_and_check(group);
+ if (r < 0)
+ return r;
- r = sync_rights(original, shadow);
- if (r < 0)
- goto finish;
+ if (group_changed) {
+ *tmpfile = group;
+ *tmpfile_path = group_tmp;
+ group = NULL;
+ group_tmp = NULL;
+ }
+ return 0;
+}
- errno = 0;
- while ((sp = fgetspent(original))) {
+static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, char **tmpfile_path) {
+#ifdef ENABLE_GSHADOW
+ _cleanup_fclose_ FILE *original = NULL, *gshadow = NULL;
+ _cleanup_(unlink_and_freep) char *gshadow_tmp = NULL;
+ bool group_changed = false;
+ Iterator iterator;
+ Item *i;
+ int r;
- i = hashmap_get(users, sp->sp_namp);
- if (i && i->todo_user) {
- /* we will update the existing entry */
- sp->sp_lstchg = lstchg;
+ if (hashmap_size(todo_gids) == 0 && hashmap_size(members) == 0)
+ return 0;
- /* only the /etc/shadow stage is left, so we can
- * safely remove the item from the todo set */
- i->todo_user = false;
- hashmap_remove(todo_uids, UID_TO_PTR(i->uid));
- }
+ r = fopen_temporary_label("/etc/gshadow", gshadow_path, &gshadow, &gshadow_tmp);
+ if (r < 0)
+ return r;
- errno = 0;
- if (putspent(sp, shadow) < 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
+ original = fopen(gshadow_path, "re");
+ if (original) {
+ struct sgrp *sg;
- errno = 0;
- }
- if (!IN_SET(errno, 0, ENOENT)) {
- r = -errno;
- goto finish;
+ r = sync_rights(original, gshadow);
+ if (r < 0)
+ return r;
+
+ errno = 0;
+ while ((sg = fgetsgent(original))) {
+
+ i = hashmap_get(groups, sg->sg_namp);
+ if (i && i->todo_group) {
+ log_error("%s: Group \"%s\" already exists.", gshadow_path, sg->sg_namp);
+ return -EEXIST;
}
- } else if (errno != ENOENT) {
- r = -errno;
- goto finish;
- } else if (fchmod(fileno(shadow), 0000) < 0) {
- r = -errno;
- goto finish;
- }
- HASHMAP_FOREACH(i, todo_uids, iterator) {
- struct spwd n = {
- .sp_namp = i->name,
- .sp_pwdp = (char*) "!!",
- .sp_lstchg = lstchg,
- .sp_min = -1,
- .sp_max = -1,
- .sp_warn = -1,
- .sp_inact = -1,
- .sp_expire = -1,
- .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */
- };
+ r = putsgent_with_members(sg, gshadow);
+ if (r < 0)
+ return r;
+ if (r > 0)
+ group_changed = true;
errno = 0;
- if (putspent(&n, shadow) != 0) {
- r = errno ? -errno : -EIO;
- goto finish;
- }
}
+ if (!IN_SET(errno, 0, ENOENT))
+ return -errno;
+
+ } else {
+ if (errno != ENOENT)
+ return -errno;
+ if (fchmod(fileno(gshadow), 0000) < 0)
+ return -errno;
+ }
+
+ HASHMAP_FOREACH(i, todo_gids, iterator) {
+ struct sgrp n = {
+ .sg_namp = i->name,
+ .sg_passwd = (char*) "!!",
+ };
- r = fflush_and_check(shadow);
+ r = putsgent_with_members(&n, gshadow);
if (r < 0)
- goto finish;
+ return r;
+
+ group_changed = true;
}
- /* Make a backup of the old files */
+ r = fflush_and_check(gshadow);
+ if (r < 0)
+ return r;
+
if (group_changed) {
- if (group) {
- r = make_backup("/etc/group", group_path);
- if (r < 0)
- goto finish;
- }
- if (gshadow) {
- r = make_backup("/etc/gshadow", gshadow_path);
- if (r < 0)
- goto finish;
- }
+ *tmpfile = gshadow;
+ *tmpfile_path = gshadow_tmp;
+ gshadow = NULL;
+ gshadow_tmp = NULL;
+ }
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+static int write_files(void) {
+ _cleanup_fclose_ FILE *passwd = NULL, *group = NULL, *shadow = NULL, *gshadow = NULL;
+ _cleanup_(unlink_and_freep) char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL;
+ const char *passwd_path = NULL, *group_path = NULL, *shadow_path = NULL, *gshadow_path = NULL;
+ int r;
+
+ passwd_path = prefix_roota(arg_root, "/etc/passwd");
+ shadow_path = prefix_roota(arg_root, "/etc/shadow");
+ group_path = prefix_roota(arg_root, "/etc/group");
+ gshadow_path = prefix_roota(arg_root, "/etc/gshadow");
+
+ r = write_temporary_group(group_path, &group, &group_tmp);
+ if (r < 0)
+ return r;
+
+ r = write_temporary_gshadow(gshadow_path, &gshadow, &gshadow_tmp);
+ if (r < 0)
+ return r;
+
+ r = write_temporary_passwd(passwd_path, &passwd, &passwd_tmp);
+ if (r < 0)
+ return r;
+
+ r = write_temporary_shadow(shadow_path, &shadow, &shadow_tmp);
+ if (r < 0)
+ return r;
+
+ /* Make a backup of the old files */
+ if (group) {
+ r = make_backup("/etc/group", group_path);
+ if (r < 0)
+ return r;
+ }
+ if (gshadow) {
+ r = make_backup("/etc/gshadow", gshadow_path);
+ if (r < 0)
+ return r;
}
if (passwd) {
r = make_backup("/etc/passwd", passwd_path);
if (r < 0)
- goto finish;
+ return r;
}
if (shadow) {
r = make_backup("/etc/shadow", shadow_path);
if (r < 0)
- goto finish;
+ return r;
}
/* And make the new files count */
- if (group_changed) {
- if (group) {
- r = rename_and_apply_smack(group_tmp, group_path);
- if (r < 0)
- goto finish;
+ if (group) {
+ r = rename_and_apply_smack(group_tmp, group_path);
+ if (r < 0)
+ return r;
- group_tmp = mfree(group_tmp);
- }
- if (gshadow) {
- r = rename_and_apply_smack(gshadow_tmp, gshadow_path);
- if (r < 0)
- goto finish;
+ group_tmp = mfree(group_tmp);
+ }
+ if (gshadow) {
+ r = rename_and_apply_smack(gshadow_tmp, gshadow_path);
+ if (r < 0)
+ return r;
- gshadow_tmp = mfree(gshadow_tmp);
- }
+ gshadow_tmp = mfree(gshadow_tmp);
}
if (passwd) {
r = rename_and_apply_smack(passwd_tmp, passwd_path);
if (r < 0)
- goto finish;
+ return r;
passwd_tmp = mfree(passwd_tmp);
}
if (shadow) {
r = rename_and_apply_smack(shadow_tmp, shadow_path);
if (r < 0)
- goto finish;
+ return r;
shadow_tmp = mfree(shadow_tmp);
}
- r = 0;
-
-finish:
- if (passwd_tmp)
- unlink(passwd_tmp);
- if (shadow_tmp)
- unlink(shadow_tmp);
- if (group_tmp)
- unlink(group_tmp);
- if (gshadow_tmp)
- unlink(gshadow_tmp);
-
- return r;
+ return 0;
}
static int uid_is_ok(uid_t uid, const char *name) {
r = strv_extend(&s->before, SPECIAL_NETWORK_TARGET);
if (r < 0)
return log_oom();
+ r = strv_extend(&s->wants, SPECIAL_NETWORK_TARGET);
+ if (r < 0)
+ return log_oom();
}
break;
--- /dev/null
+#!/usr/bin/env python3
+import sys, re
+
+print('#include <stdio.h>')
+for header in sys.argv[2:]:
+ print('#include "{}"'.format(header.split('/')[-1]))
+
+print('''
+void* functions[] = {''')
+
+for line in open(sys.argv[1]):
+ match = re.search('^ +([a-zA-Z0-9_]+);', line)
+ if match:
+ print(' {},'.format(match.group(1)))
+
+print('''};
+
+int main(void) {
+ unsigned i;
+ for (i = 0; i < sizeof(functions)/sizeof(void*); i++)
+ printf("%p\\n", functions[i]);
+ return 0;
+}''')
--- /dev/null
+awkscript = 'test-hashmap-ordered.awk'
+test_hashmap_ordered_c = custom_target(
+ 'test-hashmap-ordered.c',
+ input : [awkscript, 'test-hashmap-plain.c'],
+ output : 'test-hashmap-ordered.c',
+ command : [awk, '-f', '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+test_include_dir = include_directories('.')
+
+path = run_command('sh', ['-c', 'echo "$PATH"']).stdout()
+test_env = environment()
+test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map)
+test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map)
+test_env.set('PATH', path)
+test_env.prepend('PATH', meson.build_root())
+
+############################################################
+
+generate_sym_test_py = find_program('generate-sym-test.py')
+
+test_libsystemd_sym_c = custom_target(
+ 'test-libsystemd-sym.c',
+ input : [libsystemd_sym_path] + systemd_headers,
+ output : 'test-libsystemd-sym.c',
+ command : [generate_sym_test_py, libsystemd_sym_path] + systemd_headers,
+ capture : true)
+
+test_libudev_sym_c = custom_target(
+ 'test-libudev-sym.c',
+ input : [libudev_sym_path, libudev_h_path],
+ output : 'test-libudev-sym.c',
+ command : [generate_sym_test_py, '@INPUT0@', '@INPUT1@'],
+ capture : true)
+
+test_dlopen_c = files('test-dlopen.c')
+
+############################################################
+
+tests += [
+ [['src/test/test-device-nodes.c'],
+ [],
+ []],
+
+ [['src/test/test-engine.c'],
+ [libcore,
+ libudev,
+ libsystemd_internal],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-job-type.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-ns.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ '', 'manual'],
+
+ [['src/test/test-loopback.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-hostname.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid],
+ '', 'unsafe'],
+
+ [['src/test/test-dns-domain.c'],
+ [libcore,
+ libsystemd_network],
+ []],
+
+ [['src/test/test-boot-timestamps.c'],
+ [],
+ [],
+ 'ENABLE_EFI'],
+
+ [['src/test/test-unit-name.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-unit-file.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-utf8.c'],
+ [],
+ []],
+
+ [['src/test/test-capability.c'],
+ [],
+ [libcap]],
+
+ [['src/test/test-async.c'],
+ [],
+ []],
+
+ [['src/test/test-locale-util.c'],
+ [],
+ []],
+
+ [['src/test/test-copy.c'],
+ [libshared_static],
+ []],
+
+ [['src/test/test-sigbus.c'],
+ [],
+ []],
+
+ [['src/test/test-condition.c'],
+ [],
+ []],
+
+ [['src/test/test-fdset.c'],
+ [],
+ []],
+
+ [['src/test/test-fstab-util.c'],
+ [],
+ []],
+
+ [['src/test/test-random-util.c'],
+ [],
+ []],
+
+ [['src/test/test-ratelimit.c'],
+ [],
+ []],
+
+ [['src/test/test-util.c'],
+ [],
+ []],
+
+ [['src/test/test-mount-util.c'],
+ [],
+ []],
+
+ [['src/test/test-exec-util.c'],
+ [],
+ []],
+
+ [['src/test/test-hexdecoct.c'],
+ [],
+ []],
+
+ [['src/test/test-alloc-util.c'],
+ [],
+ []],
+
+ [['src/test/test-xattr-util.c'],
+ [],
+ []],
+
+ [['src/test/test-io-util.c'],
+ [],
+ []],
+
+ [['src/test/test-glob-util.c'],
+ [],
+ []],
+
+ [['src/test/test-fs-util.c'],
+ [],
+ []],
+
+ [['src/test/test-proc-cmdline.c'],
+ [],
+ []],
+
+ [['src/test/test-fd-util.c'],
+ [],
+ []],
+
+ [['src/test/test-web-util.c'],
+ [],
+ []],
+
+ [['src/test/test-cpu-set-util.c'],
+ [],
+ []],
+
+ [['src/test/test-stat-util.c'],
+ [],
+ []],
+
+ [['src/test/test-escape.c'],
+ [],
+ []],
+
+ [['src/test/test-string-util.c'],
+ [],
+ []],
+
+ [['src/test/test-extract-word.c'],
+ [],
+ []],
+
+ [['src/test/test-parse-util.c'],
+ [],
+ []],
+
+ [['src/test/test-user-util.c'],
+ [],
+ []],
+
+ [['src/test/test-hostname-util.c'],
+ [],
+ []],
+
+ [['src/test/test-process-util.c'],
+ [],
+ []],
+
+ [['src/test/test-terminal-util.c'],
+ [],
+ []],
+
+ [['src/test/test-path-lookup.c'],
+ [],
+ []],
+
+ [['src/test/test-uid-range.c'],
+ [],
+ []],
+
+ [['src/test/test-cap-list.c',
+ generated_gperf_headers],
+ [],
+ [libcap]],
+
+ [['src/test/test-socket-util.c'],
+ [],
+ []],
+
+ [['src/test/test-barrier.c'],
+ [],
+ []],
+
+ [['src/test/test-tmpfiles.c'],
+ [],
+ []],
+
+ [['src/test/test-namespace.c'],
+ [libcore,
+ libshared],
+ [threads,
+ libblkid]],
+
+ [['src/test/test-verbs.c'],
+ [],
+ []],
+
+ [['src/test/test-install-root.c'],
+ [],
+ []],
+
+ [['src/test/test-acl-util.c'],
+ [],
+ [],
+ 'HAVE_ACL'],
+
+ [['src/test/test-seccomp.c'],
+ [],
+ [libseccomp],
+ 'HAVE_SECCOMP'],
+
+ [['src/test/test-rlimit-util.c'],
+ [],
+ []],
+
+ [['src/test/test-ask-password-api.c'],
+ [],
+ [],
+ '', 'manual'],
+
+ [['src/test/test-dissect-image.c'],
+ [],
+ [libblkid],
+ '', 'manual'],
+
+ [['src/test/test-signal-util.c'],
+ [],
+ []],
+
+ [['src/test/test-selinux.c'],
+ [],
+ []],
+
+ [['src/test/test-sizeof.c'],
+ [libbasic],
+ []],
+
+ [['src/test/test-hashmap.c',
+ 'src/test/test-hashmap-plain.c',
+ test_hashmap_ordered_c],
+ [],
+ [],
+ '', 'timeout=90'],
+
+ [['src/test/test-set.c'],
+ [],
+ []],
+
+ [['src/test/test-bitmap.c'],
+ [],
+ []],
+
+ [['src/test/test-xml.c'],
+ [],
+ []],
+
+ [['src/test/test-list.c'],
+ [],
+ []],
+
+ [['src/test/test-unaligned.c'],
+ [],
+ []],
+
+ [['src/test/test-tables.c',
+ 'src/shared/test-tables.h',
+ 'src/journal/journald-server.c',
+ 'src/journal/journald-server.h'],
+ [libcore,
+ libjournal_core,
+ libudev_core,
+ libudev_internal,
+ libsystemd_network,
+ libshared],
+ [threads,
+ libseccomp,
+ libmount,
+ libxz,
+ liblz4,
+ libblkid],
+ '', '', [], libudev_core_includes],
+
+ [['src/test/test-prioq.c'],
+ [],
+ []],
+
+ [['src/test/test-fileio.c'],
+ [],
+ []],
+
+ [['src/test/test-time.c'],
+ [],
+ []],
+
+ [['src/test/test-clock.c'],
+ [],
+ []],
+
+ [['src/test/test-architecture.c'],
+ [],
+ []],
+
+ [['src/test/test-log.c'],
+ [],
+ []],
+
+ [['src/test/test-ipcrm.c'],
+ [],
+ [],
+ '', 'unsafe'],
+
+ [['src/test/test-btrfs.c'],
+ [],
+ [],
+ '', 'manual'],
+
+
+ [['src/test/test-firewall-util.c'],
+ [libshared],
+ [],
+ 'HAVE_LIBIPTC'],
+
+ [['src/test/test-netlink-manual.c'],
+ [],
+ [libkmod],
+ 'HAVE_KMOD', 'manual'],
+
+ [['src/test/test-ellipsize.c'],
+ [],
+ []],
+
+ [['src/test/test-date.c'],
+ [],
+ []],
+
+ [['src/test/test-sleep.c'],
+ [],
+ []],
+
+ [['src/test/test-replace-var.c'],
+ [],
+ []],
+
+ [['src/test/test-calendarspec.c'],
+ [],
+ []],
+
+ [['src/test/test-strip-tab-ansi.c'],
+ [],
+ []],
+
+ [['src/test/test-daemon.c'],
+ [],
+ []],
+
+ [['src/test/test-cgroup.c'],
+ [],
+ [],
+ '', 'manual'],
+
+
+ [['src/test/test-cgroup-mask.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-cgroup-util.c'],
+ [],
+ []],
+
+ [['src/test/test-env-util.c'],
+ [],
+ []],
+
+ [['src/test/test-strbuf.c'],
+ [],
+ []],
+
+ [['src/test/test-strv.c'],
+ [],
+ []],
+
+ [['src/test/test-path-util.c'],
+ [],
+ []],
+
+ [['src/test/test-path.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-execute.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-siphash24.c'],
+ [],
+ []],
+
+ [['src/test/test-strxcpyx.c'],
+ [],
+ []],
+
+ [['src/test/test-install.c'],
+ [libcore,
+ libshared],
+ [],
+ '', 'manual'],
+
+ [['src/test/test-watchdog.c'],
+ [],
+ []],
+
+ [['src/test/test-sched-prio.c'],
+ [libcore,
+ libshared],
+ [threads,
+ librt,
+ libseccomp,
+ libselinux,
+ libmount,
+ libblkid]],
+
+ [['src/test/test-conf-files.c'],
+ [],
+ []],
+
+ [['src/test/test-conf-parser.c'],
+ [],
+ []],
+
+ [['src/test/test-af-list.c',
+ generated_gperf_headers],
+ [],
+ []],
+
+ [['src/test/test-arphrd-list.c',
+ generated_gperf_headers],
+ [],
+ []],
+
+ [['src/test/test-journal-importer.c'],
+ [],
+ []],
+
+ [['src/test/test-libudev.c'],
+ [libshared],
+ []],
+
+ [['src/test/test-udev.c'],
+ [libudev_core,
+ libudev_internal,
+ libsystemd_network,
+ libshared],
+ [threads,
+ librt,
+ libblkid,
+ libkmod,
+ libacl],
+ '', 'manual'],
+
+ [['src/test/test-id128.c'],
+ [],
+ []],
+
+ [['src/test/test-hash.c'],
+ [],
+ []],
+
+ [['src/test/test-nss.c'],
+ [],
+ [libdl],
+ '', 'manual'],
+]
+
+############################################################
+
+# define some tests here, because the link_with deps were not defined earlier
+
+tests += [
+ [['src/journal/test-journal.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-send.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-syslog.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4,
+ libselinux]],
+
+ [['src/journal/test-journal-match.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-enum.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-stream.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-flush.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-init.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-verify.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-journal-interleaving.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-mmap-cache.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4]],
+
+ [['src/journal/test-catalog.c'],
+ [libjournal_core,
+ libshared],
+ [threads,
+ libxz,
+ liblz4],
+ '', '', '-DCATALOG_DIR="@0@"'.format(build_catalog_dir)],
+
+ [['src/journal/test-compress.c'],
+ [libjournal_core,
+ libshared],
+ [liblz4,
+ libxz]],
+
+ [['src/journal/test-compress-benchmark.c'],
+ [libjournal_core,
+ libshared],
+ [liblz4,
+ libxz],
+ '', 'timeout=90'],
+
+ [['src/journal/test-audit-type.c'],
+ [libjournal_core,
+ libshared],
+ [liblz4,
+ libxz]],
+]
+
+############################################################
+
+tests += [
+ [['src/libsystemd/sd-bus/test-bus-marshal.c'],
+ [],
+ [threads,
+ libglib,
+ libgobject,
+ libgio,
+ libdbus]],
+
+ [['src/libsystemd/sd-bus/test-bus-signature.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-chat.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-cleanup.c'],
+ [],
+ [threads,
+ libseccomp]],
+
+ [['src/libsystemd/sd-bus/test-bus-error.c'],
+ [libshared_static,
+ libsystemd_internal],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-track.c'],
+ [],
+ [libseccomp]],
+
+ [['src/libsystemd/sd-bus/test-bus-server.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-objects.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-vtable.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-gvariant.c'],
+ [],
+ [libglib,
+ libgobject,
+ libgio]],
+
+ [['src/libsystemd/sd-bus/test-bus-creds.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-match.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-kernel.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-kernel-bloom.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-benchmark.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-bus/test-bus-zero-copy.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-bus/test-bus-introspect.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-event/test-event.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-netlink/test-netlink.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-netlink/test-local-addresses.c'],
+ [],
+ []],
+
+ [['src/libsystemd/sd-resolve/test-resolve.c'],
+ [],
+ [threads]],
+
+ [['src/libsystemd/sd-login/test-login.c'],
+ [],
+ []],
+]
+
+if cxx.found()
+ tests += [
+ [['src/libsystemd/sd-bus/test-bus-vtable-cc.cc'],
+ [],
+ []]
+ ]
+endif
+
+############################################################
+
+tests += [
+ [['src/libsystemd-network/test-dhcp-option.c',
+ 'src/libsystemd-network/dhcp-protocol.h',
+ 'src/libsystemd-network/dhcp-internal.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-sd-dhcp-lease.c',
+ 'src/libsystemd-network/dhcp-lease-internal.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-dhcp-client.c',
+ 'src/libsystemd-network/dhcp-protocol.h',
+ 'src/libsystemd-network/dhcp-internal.h',
+ 'src/systemd/sd-dhcp-client.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-dhcp-server.c'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-ipv4ll.c',
+ 'src/libsystemd-network/arp-util.h',
+ 'src/systemd/sd-ipv4ll.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-ipv4ll-manual.c',
+ 'src/systemd/sd-ipv4ll.h'],
+ [libshared,
+ libsystemd_network],
+ [],
+ '', 'manual'],
+
+ [['src/libsystemd-network/test-acd.c',
+ 'src/systemd/sd-ipv4acd.h'],
+ [libshared,
+ libsystemd_network],
+ [],
+ '', 'manual'],
+
+ [['src/libsystemd-network/test-ndisc-rs.c',
+ 'src/libsystemd-network/dhcp-identifier.h',
+ 'src/libsystemd-network/dhcp-identifier.c',
+ 'src/libsystemd-network/icmp6-util.h',
+ 'src/systemd/sd-dhcp6-client.h',
+ 'src/systemd/sd-ndisc.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-ndisc-ra.c',
+ 'src/libsystemd-network/icmp6-util.h',
+ 'src/systemd/sd-ndisc.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-dhcp6-client.c',
+ 'src/libsystemd-network/dhcp-identifier.h',
+ 'src/libsystemd-network/dhcp-identifier.c',
+ 'src/libsystemd-network/dhcp6-internal.h',
+ 'src/systemd/sd-dhcp6-client.h'],
+ [libshared,
+ libsystemd_network],
+ []],
+
+ [['src/libsystemd-network/test-lldp.c'],
+ [libshared,
+ libsystemd_network],
+ []],
+]
+
+############################################################
+
+tests += [
+ [['src/login/test-login-shared.c'],
+ [],
+ []],
+
+ [['src/login/test-inhibit.c'],
+ [],
+ [],
+ '', 'manual'],
+
+ [['src/login/test-login-tables.c'],
+ [liblogind_core,
+ libshared],
+ [threads]],
+]
#include "string-util.h"
#include "util.h"
-_unused_ \
+_unused_
static const struct af_name* lookup_af(register const char *str, register GPERF_LEN_TYPE len);
#include "af-from-name.h"
test_one("*:20..39/5", "*-*-* *:20..35/5:00");
test_one("00:00:20..40/1", "*-*-* 00:00:20..40");
test_one("*~03/1,03..05", "*-*~03/1,03..05 00:00:00");
+ /* UNIX timestamps are always UTC */
+ test_one("@1493187147", "2017-04-26 06:12:27 UTC");
+ test_one("@1493187147 UTC", "2017-04-26 06:12:27 UTC");
+ test_one("@0", "1970-01-01 00:00:00 UTC");
+ test_one("@0 UTC", "1970-01-01 00:00:00 UTC");
test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000);
test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
#include "sd-id128.h"
#include "alloc-util.h"
#include "strv.h"
#include "virt.h"
#include "util.h"
+#include "user-util.h"
static void test_condition_test_path(void) {
Condition *condition;
condition = condition_new(CONDITION_SECURITY, "selinux", false, true);
assert_se(condition);
- assert_se(condition_test(condition) != mac_selinux_have());
+ assert_se(condition_test(condition) != mac_selinux_use());
condition_free(condition);
condition = condition_new(CONDITION_SECURITY, "ima", false, false);
}
}
+static void test_condition_test_user(void) {
+ Condition *condition;
+ char* uid;
+ char* username;
+ int r;
+
+ condition = condition_new(CONDITION_USER, "garbage oifdsjfoidsjoj", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=garbage → %i", r);
+ assert_se(r == 0);
+ condition_free(condition);
+
+ assert_se(asprintf(&uid, "%"PRIu32, UINT32_C(0xFFFF)) > 0);
+ condition = condition_new(CONDITION_USER, uid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", uid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(uid);
+
+ assert_se(asprintf(&uid, "%u", (unsigned)getuid()) > 0);
+ condition = condition_new(CONDITION_USER, uid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", uid, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(uid);
+
+ assert_se(asprintf(&uid, "%u", (unsigned)getuid()+1) > 0);
+ condition = condition_new(CONDITION_USER, uid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", uid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(uid);
+
+ username = getusername_malloc();
+ assert_se(username);
+ condition = condition_new(CONDITION_USER, username, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", username, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(username);
+
+ username = (char*)(geteuid() == 0 ? NOBODY_USER_NAME : "root");
+ condition = condition_new(CONDITION_USER, username, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=%s → %i", username, r);
+ assert_se(r == 0);
+ condition_free(condition);
+
+ condition = condition_new(CONDITION_USER, "@system", false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionUser=@system → %i", r);
+ if (geteuid() == 0)
+ assert_se(r > 0);
+ else
+ assert_se(r == 0);
+ condition_free(condition);
+}
+
+static void test_condition_test_group(void) {
+ Condition *condition;
+ char* gid;
+ char* groupname;
+ gid_t *gids, max_gid;
+ int ngroups_max, r, i;
+
+ assert_se(0 < asprintf(&gid, "%u", UINT32_C(0xFFFF)));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(gid);
+
+ assert_se(0 < asprintf(&gid, "%u", getgid()));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(gid);
+
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ assert(ngroups_max > 0);
+
+ gids = alloca(sizeof(gid_t) * ngroups_max);
+
+ r = getgroups(ngroups_max, gids);
+ assert(r >= 0);
+
+ max_gid = getgid();
+ for (i = 0; i < r; i++) {
+ assert_se(0 < asprintf(&gid, "%u", gids[i]));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(gid);
+ max_gid = gids[i] > max_gid ? gids[i] : max_gid;
+
+ groupname = gid_to_name(gids[i]);
+ assert_se(groupname);
+ condition = condition_new(CONDITION_GROUP, groupname, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", groupname, r);
+ assert_se(r > 0);
+ condition_free(condition);
+ free(groupname);
+ max_gid = gids[i] > max_gid ? gids[i] : max_gid;
+ }
+
+ assert_se(0 < asprintf(&gid, "%u", max_gid+1));
+ condition = condition_new(CONDITION_GROUP, gid, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", gid, r);
+ assert_se(r == 0);
+ condition_free(condition);
+ free(gid);
+
+ groupname = (char*)(geteuid() == 0 ? NOBODY_GROUP_NAME : "root");
+ condition = condition_new(CONDITION_GROUP, groupname, false, false);
+ assert_se(condition);
+ r = condition_test(condition);
+ log_info("ConditionGroup=%s → %i", groupname, r);
+ assert_se(r == 0);
+ condition_free(condition);
+}
+
int main(int argc, char *argv[]) {
log_set_max_level(LOG_DEBUG);
log_parse_environment();
test_condition_test_null();
test_condition_test_security();
test_condition_test_virtualization();
+ test_condition_test_user();
+ test_condition_test_group();
return 0;
}
test_config_parse_path_one("/path", "/path");
test_config_parse_path_one("/path//////////", "/path");
test_config_parse_path_one("///path/foo///bar////bar//", "/path/foo/bar/bar");
+ test_config_parse_path_one("/path/\xc3\x80", "/path/\xc3\x80");
test_config_parse_path_one("not_absolute/path", NULL);
+ test_config_parse_path_one("/path/\xc3\x7f", NULL);
}
static void test_config_parse_log_level(void) {
test_config_parse_strv_one("foo", STRV_MAKE("foo"));
test_config_parse_strv_one("foo bar foo", STRV_MAKE("foo", "bar", "foo"));
test_config_parse_strv_one("\"foo bar\" foo", STRV_MAKE("foo bar", "foo"));
+ test_config_parse_strv_one("\xc3\x80", STRV_MAKE("\xc3\x80"));
+ test_config_parse_strv_one("\xc3\x7f", STRV_MAKE_EMPTY);
}
static void test_config_parse_mode(void) {
static void test_should_pass(const char *p) {
usec_t t, q;
- char buf[FORMAT_TIMESTAMP_MAX], buf_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *sp;
+ char buf[FORMAT_TIMESTAMP_MAX], buf_relative[FORMAT_TIMESTAMP_RELATIVE_MAX];
+ log_info("Test: %s", p);
assert_se(parse_timestamp(p, &t) >= 0);
- format_timestamp_us(buf, sizeof(buf), t);
- log_info("%s", buf);
-
- /* Chop off timezone */
- sp = strrchr(buf, ' ');
- assert_se(sp);
- *sp = 0;
+ assert_se(format_timestamp_us(buf, sizeof(buf), t));
+ log_info("\"%s\" → \"%s\"", p, buf);
assert_se(parse_timestamp(buf, &q) >= 0);
assert_se(q == t);
- format_timestamp_relative(buf_relative, sizeof(buf_relative), t);
+ assert_se(format_timestamp_relative(buf_relative, sizeof(buf_relative), t));
log_info("%s", strna(buf_relative));
- assert_se(parse_timestamp(buf, &q) >= 0);
}
static void test_should_parse(const char *p) {
usec_t t;
+ log_info("Test: %s", p);
assert_se(parse_timestamp(p, &t) >= 0);
+ log_info("\"%s\" → \"@%" PRI_USEC "\"", p, t);
}
static void test_should_fail(const char *p) {
usec_t t;
+ int r;
- assert_se(parse_timestamp(p, &t) < 0);
+ log_info("Test: %s", p);
+ r = parse_timestamp(p, &t);
+ if (r >= 0)
+ log_info("\"%s\" → \"@%" PRI_USEC "\" (unexpected)", p, t);
+ else
+ log_info("parse_timestamp() returns %d (expected)", r);
+ assert_se(r < 0);
}
static void test_one(const char *p) {
_cleanup_free_ char *with_utc;
- log_info("Test: %s", p);
with_utc = strjoin(p, " UTC");
test_should_pass(p);
test_should_pass(with_utc);
static void test_one_noutc(const char *p) {
_cleanup_free_ char *with_utc;
- log_info("Test: %s", p);
with_utc = strjoin(p, " UTC");
test_should_pass(p);
test_should_fail(with_utc);
test_one("2012-12-30 18:42");
test_one("2012-10-02");
test_one("Tue 2012-10-02");
- test_one_noutc("now");
test_one("yesterday");
test_one("today");
test_one("tomorrow");
+ test_one_noutc("now");
test_one_noutc("+2d");
test_one_noutc("+2y 4d");
test_one_noutc("5months ago");
test_one_noutc("@1395716396");
- test_should_parse("today UTC");
- test_should_fail("today UTC UTC");
test_should_parse("1970-1-1 UTC");
- test_should_fail("1969-1-1 UTC");
+ test_should_pass("1970-1-1 00:00:01 UTC");
+ test_should_fail("1969-12-31 UTC");
+ test_should_fail("-100y");
+ test_should_fail("today UTC UTC");
#if SIZEOF_TIME_T == 8
- test_should_parse("9999-12-30 23:59:59 UTC");
+ test_should_pass("9999-12-30 23:59:59 UTC");
test_should_fail("9999-12-31 00:00:00 UTC");
test_should_fail("10000-01-01 00:00:00 UTC");
#elif SIZEOF_TIME_T == 4
- test_should_parse("2038-01-19 03:14:07 UTC");
- test_should_fail( "2038-01-19 03:14:08 UTC");
+ test_should_pass("2038-01-19 03:14:07 UTC");
+ test_should_fail("2038-01-19 03:14:08 UTC");
#endif
return 0;
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include "macro.h"
+
+int main(int argc, char **argv) {
+ void *handle;
+
+ assert_se((handle = dlopen(argv[1], RTLD_NOW)));
+ assert_se(dlclose(handle) == 0);
+
+ return EXIT_SUCCESS;
+}
test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
}
-static void test_dns_name_apply_idna_one(const char *s, const char *result) {
-#ifdef HAVE_LIBIDN
+static void test_dns_name_apply_idna_one(const char *s, int expected, const char *result) {
_cleanup_free_ char *buf = NULL;
- assert_se(dns_name_apply_idna(s, &buf) >= 0);
- assert_se(dns_name_equal(buf, result) > 0);
-#endif
+ int r;
+
+ r = dns_name_apply_idna(s, &buf);
+ log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
+ s, r, strnull(buf), expected, strnull(result));
+
+ assert_se(r == expected);
+ if (expected == 1)
+ assert_se(dns_name_equal(buf, result) == 1);
}
static void test_dns_name_apply_idna(void) {
- test_dns_name_apply_idna_one("", "");
- test_dns_name_apply_idna_one("foo", "foo");
- test_dns_name_apply_idna_one("foo.", "foo");
- test_dns_name_apply_idna_one("foo.bar", "foo.bar");
- test_dns_name_apply_idna_one("foo.bar.", "foo.bar");
- test_dns_name_apply_idna_one("föö", "xn--f-1gaa");
- test_dns_name_apply_idna_one("föö.", "xn--f-1gaa");
- test_dns_name_apply_idna_one("föö.bär", "xn--f-1gaa.xn--br-via");
- test_dns_name_apply_idna_one("föö.bär.", "xn--f-1gaa.xn--br-via");
+#if defined HAVE_LIBIDN2 || defined HAVE_LIBIDN
+ const int ret = 1;
+#else
+ const int ret = 0;
+#endif
+
+ /* IDNA2008 forbids names with hyphens in third and fourth positions
+ * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
+ * IDNA2003 does not have this restriction
+ * (https://tools.ietf.org/html/rfc3490#section-5).
+ * This means that when using libidn we will transform and test more
+ * labels. If registrars follow IDNA2008 we'll just be performing a
+ * useless lookup.
+ */
+#if defined HAVE_LIBIDN
+ const int ret2 = 1;
+#else
+ const int ret2 = 0;
+#endif
+
+ test_dns_name_apply_idna_one("", ret, "");
+ test_dns_name_apply_idna_one("foo", ret, "foo");
+ test_dns_name_apply_idna_one("foo.", ret, "foo");
+ test_dns_name_apply_idna_one("foo.bar", ret, "foo.bar");
+ test_dns_name_apply_idna_one("foo.bar.", ret, "foo.bar");
+ test_dns_name_apply_idna_one("föö", ret, "xn--f-1gaa");
+ test_dns_name_apply_idna_one("föö.", ret, "xn--f-1gaa");
+ test_dns_name_apply_idna_one("föö.bär", ret, "xn--f-1gaa.xn--br-via");
+ test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
+ test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
+
+ test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2,
+ ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : "");
}
static void test_dns_name_is_valid_or_address(void) {
}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
test_dns_label_unescape();
test_dns_label_unescape_suffix();
#include <string.h>
#include "env-util.h"
+#include "fd-util.h"
+#include "fileio.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
}
+static void test_deserialize_environment(void) {
+ _cleanup_strv_free_ char **env = strv_new("A=1", NULL);
+
+ assert_se(deserialize_environment(&env, "env=test") < 0);
+ assert_se(deserialize_environment(&env, "env=B=2") >= 0);
+
+ assert_se(strv_equal(env, STRV_MAKE("A=1", "B=2")));
+}
+
+static void test_serialize_environment(void) {
+ char fn[] = "/tmp/test-env-util.XXXXXXX";
+ int fd, r;
+ _cleanup_fclose_ FILE *f = NULL;
+
+ _cleanup_strv_free_ char **env = strv_new("A=1",
+ "B=2",
+ "C=ąęółń",
+ "D=D=a\\x0Ab",
+ NULL);
+ _cleanup_strv_free_ char **env2 = NULL;
+
+ fd = mkostemp_safe(fn);
+ assert_se(fd >= 0);
+
+ assert_se(f = fdopen(fd, "r+"));
+
+ assert_se(serialize_environment(f, env) == 0);
+ assert_se(fflush_and_check(f) == 0);
+
+ rewind(f);
+
+ for (;;) {
+ char line[LINE_MAX];
+ const char *l;
+
+ if (!fgets(line, sizeof line, f))
+ break;
+
+ char_array_0(line);
+ l = strstrip(line);
+
+ r = deserialize_environment(&env2, l);
+ assert_se(r == 1);
+ }
+ assert_se(feof(f));
+
+ assert_se(strv_equal(env, env2));
+
+ unlink(fn);
+}
+
int main(int argc, char *argv[]) {
test_strv_env_delete();
test_strv_env_get();
test_env_name_is_valid();
test_env_value_is_valid();
test_env_assignment_is_valid();
+ test_deserialize_environment();
+ test_serialize_environment();
return 0;
}
assert_se(cunescape("\\073", 0, &unescaped) >= 0);
assert_se(streq_ptr(unescaped, ";"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("A=A\\\\x0aB", 0, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
+ unescaped = mfree(unescaped);
+
+ assert_se(cunescape("A=A\\\\x0aB", UNESCAPE_RELAX, &unescaped) >= 0);
+ assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
}
static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
test_shell_escape_one("foo:bar,baz", ",:", "foo\\:bar\\,baz");
}
-static void test_shell_maybe_quote_one(const char *s, const char *expected) {
- _cleanup_free_ char *r;
+static void test_shell_maybe_quote_one(const char *s,
+ EscapeStyle style,
+ const char *expected) {
+ _cleanup_free_ char *ret = NULL;
- assert_se(r = shell_maybe_quote(s));
- assert_se(streq(r, expected));
+ assert_se(ret = shell_maybe_quote(s, style));
+ log_debug("[%s] → [%s] (%s)", s, ret, expected);
+ assert_se(streq(ret, expected));
}
static void test_shell_maybe_quote(void) {
- test_shell_maybe_quote_one("", "");
- test_shell_maybe_quote_one("\\", "\"\\\\\"");
- test_shell_maybe_quote_one("\"", "\"\\\"\"");
- test_shell_maybe_quote_one("foobar", "foobar");
- test_shell_maybe_quote_one("foo bar", "\"foo bar\"");
- test_shell_maybe_quote_one("foo \"bar\" waldo", "\"foo \\\"bar\\\" waldo\"");
- test_shell_maybe_quote_one("foo$bar", "\"foo\\$bar\"");
+ test_shell_maybe_quote_one("", ESCAPE_BACKSLASH, "");
+ test_shell_maybe_quote_one("", ESCAPE_POSIX, "");
+ test_shell_maybe_quote_one("\\", ESCAPE_BACKSLASH, "\"\\\\\"");
+ test_shell_maybe_quote_one("\\", ESCAPE_POSIX, "$'\\\\'");
+ test_shell_maybe_quote_one("\"", ESCAPE_BACKSLASH, "\"\\\"\"");
+ test_shell_maybe_quote_one("\"", ESCAPE_POSIX, "$'\"'");
+ test_shell_maybe_quote_one("foobar", ESCAPE_BACKSLASH, "foobar");
+ test_shell_maybe_quote_one("foobar", ESCAPE_POSIX, "foobar");
+ test_shell_maybe_quote_one("foo bar", ESCAPE_BACKSLASH, "\"foo bar\"");
+ test_shell_maybe_quote_one("foo bar", ESCAPE_POSIX, "$'foo bar'");
+ test_shell_maybe_quote_one("foo\tbar", ESCAPE_BACKSLASH, "\"foo\tbar\"");
+ test_shell_maybe_quote_one("foo\tbar", ESCAPE_POSIX, "$'foo\\tbar'");
+ test_shell_maybe_quote_one("foo\nbar", ESCAPE_BACKSLASH, "\"foo\nbar\"");
+ test_shell_maybe_quote_one("foo\nbar", ESCAPE_POSIX, "$'foo\\nbar'");
+ test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_BACKSLASH, "\"foo \\\"bar\\\" waldo\"");
+ test_shell_maybe_quote_one("foo \"bar\" waldo", ESCAPE_POSIX, "$'foo \"bar\" waldo'");
+ test_shell_maybe_quote_one("foo$bar", ESCAPE_BACKSLASH, "\"foo\\$bar\"");
+ test_shell_maybe_quote_one("foo$bar", ESCAPE_POSIX, "$'foo$bar'");
+
+ /* Note that current users disallow control characters, so this "test"
+ * is here merely to establish current behaviour. If control characters
+ * were allowed, they should be quoted, i.e. \001 should become \\001. */
+ test_shell_maybe_quote_one("a\nb\001", ESCAPE_BACKSLASH, "\"a\nb\001\"");
+ test_shell_maybe_quote_one("a\nb\001", ESCAPE_POSIX, "$'a\\nb\001'");
+
+ test_shell_maybe_quote_one("foo!bar", ESCAPE_BACKSLASH, "\"foo!bar\"");
+ test_shell_maybe_quote_one("foo!bar", ESCAPE_POSIX, "$'foo!bar'");
}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_cescape();
test_cunescape();
test_shell_escape();
return 0;
}
-const gather_stdout_callback_t const gather_stdout[] = {
+const gather_stdout_callback_t gather_stdout[] = {
gather_stdout_one,
gather_stdout_two,
gather_stdout_three,
test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
}
+static void test_exec_inaccessiblepaths_proc(Manager *m) {
+ if (!is_inaccessible_available()) {
+ log_notice("testing without inaccessible, skipping %s", __func__);
+ return;
+ }
+
+ test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
+}
+
static void test_exec_systemcallfilter(Manager *m) {
#ifdef HAVE_SECCOMP
if (!is_seccomp_available())
test_exec_readonlypaths,
test_exec_readwritepaths,
test_exec_inaccessiblepaths,
+ test_exec_inaccessiblepaths_proc,
test_exec_privatenetwork,
test_exec_systemcallfilter,
test_exec_systemcallerrornumber,
int main(int argc, char *argv[]) {
test_unlink_noerrno();
- test_readlink_and_make_absolute();
test_get_files_in_directory();
+ test_readlink_and_make_absolute();
test_var_tmp();
test_chase_symlinks();
test_dot_or_dot_dot();
***/
#include <fcntl.h>
+#include <glob.h>
+#include <sys/stat.h>
#include <unistd.h>
#include "alloc-util.h"
+#include "dirent-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "glob-util.h"
#include "macro.h"
+#include "rm-rf.h"
static void test_glob_exists(void) {
char name[] = "/tmp/test-glob_exists.XXXXXX";
assert_se(r == 0);
}
+static void test_glob_no_dot(void) {
+ char template[] = "/tmp/test-glob-util.XXXXXXX";
+ const char *fn;
+
+ _cleanup_globfree_ glob_t g = {
+ .gl_closedir = (void (*)(void *)) closedir,
+ .gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot,
+ .gl_opendir = (void *(*)(const char *)) opendir,
+ .gl_lstat = lstat,
+ .gl_stat = stat,
+ };
+
+ int r;
+
+ assert_se(mkdtemp(template));
+
+ fn = strjoina(template, "/*");
+ r = glob(fn, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
+ assert_se(r == GLOB_NOMATCH);
+
+ fn = strjoina(template, "/.*");
+ r = glob(fn, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
+ assert_se(r == GLOB_NOMATCH);
+
+ (void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static void test_safe_glob(void) {
+ char template[] = "/tmp/test-glob-util.XXXXXXX";
+ const char *fn, *fn2, *fname;
+
+ _cleanup_globfree_ glob_t g = {};
+ int r;
+
+ assert_se(mkdtemp(template));
+
+ fn = strjoina(template, "/*");
+ r = safe_glob(fn, 0, &g);
+ assert_se(r == -ENOENT);
+
+ fn2 = strjoina(template, "/.*");
+ r = safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &g);
+ assert_se(r == -ENOENT);
+
+ fname = strjoina(template, "/.foobar");
+ assert_se(touch(fname) == 0);
+
+ r = safe_glob(fn, 0, &g);
+ assert_se(r == -ENOENT);
+
+ r = safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &g);
+ assert_se(r == 0);
+ assert_se(g.gl_pathc == 1);
+ assert_se(streq(g.gl_pathv[0], fname));
+ assert_se(g.gl_pathv[1] == NULL);
+
+ (void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
int main(void) {
test_glob_exists();
+ test_glob_no_dot();
+ test_safe_glob();
return 0;
}
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <stdio.h>
+
#include "alloc-util.h"
#include "log.h"
#include "string-util.h"
int main(int argc, char *argv[]) {
_cleanup_(khash_unrefp) khash *h = NULL, *copy = NULL;
_cleanup_free_ char *s = NULL;
+ int r;
log_set_max_level(LOG_DEBUG);
assert_se(khash_new(&h, NULL) == -EINVAL);
assert_se(khash_new(&h, "") == -EINVAL);
- assert_se(khash_new(&h, "foobar") == -EOPNOTSUPP);
+ r = khash_new(&h, "foobar");
+ if (r == -EAFNOSUPPORT) {
+ puts("khash not supported on this kernel, skipping");
+ return EXIT_TEST_SKIP;
+ }
+ assert_se(r == -EOPNOTSUPP);
assert_se(khash_new(&h, "sha256") >= 0);
assert_se(khash_get_size(h) == 32);
--- /dev/null
+BEGIN {
+ print "/* GENERATED FILE */";
+ print "#define ORDERED"
+}
+{
+ if (!match($0, "^#include"))
+ gsub(/hashmap/, "ordered_hashmap");
+ gsub(/HASHMAP/, "ORDERED_HASHMAP");
+ gsub(/Hashmap/, "OrderedHashmap");
+ print
+}
assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
- assert_se(!sd_id128_equal(id, id2));
+ r = sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id);
+ if (r == -EAFNOSUPPORT) {
+ log_info("khash not supported on this kernel, skipping sd_id128_get_machine_app_specific() checks");
+ } else {
+ assert_se(r >= 0);
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
+ assert_se(sd_id128_equal(id, id2));
+ assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
+ assert_se(!sd_id128_equal(id, id2));
+ }
/* Query the invocation ID */
r = sd_id128_get_invocation(&id);
return EXIT_SUCCESS;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return EXIT_SUCCESS;
case 'm':
#include "log.h"
#include "util.h"
+assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_FTP | LOG_DEBUG))
+ == LOG_REALM_SYSTEMD);
+assert_cc(LOG_REALM_REMOVE_LEVEL(LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_LOCAL7 | LOG_DEBUG))
+ == LOG_REALM_UDEV);
+assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_SYSTEMD, LOG_LOCAL3 | LOG_DEBUG) & LOG_FACMASK)
+ == LOG_LOCAL3);
+assert_cc((LOG_REALM_PLUS_LEVEL(LOG_REALM_UDEV, LOG_USER | LOG_INFO) & LOG_PRIMASK)
+ == LOG_INFO);
+
int main(int argc, char* argv[]) {
log_set_target(LOG_TARGET_CONSOLE);
int r;
log_open();
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
r = loopback_setup();
if (r < 0)
- log_error("loopback: %m");
+ log_error_errno(r, "loopback: %m");
return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
const char *path;
void *handle;
- if (dir)
- path = strjoina(dir, "/.libs/libnss_", module, ".so.2");
- else
+ if (dir) {
+ path = strjoina(dir, "/libnss_", module, ".so.2");
+ if (access(path, F_OK) < 0)
+ path = strjoina(dir, "/.libs/libnss_", module, ".so.2");
+ } else
path = strjoina("libnss_", module, ".so.2");
handle = dlopen(path, flags);
goto numerical_index;
if (if_indextoname(it->scopeid, ifname) == NULL) {
- log_warning("if_indextoname(%d) failed: %m", it->scopeid);
+ log_warning_errno(errno, "if_indextoname(%d) failed: %m", it->scopeid);
numerical_index:
xsprintf(ifname, "%i", it->scopeid);
};
r = safe_atou16("junk", &l);
assert_se(r == -EINVAL);
+
+ r = safe_atou16("123x", &l);
+ assert_se(r == -EINVAL);
}
static void test_safe_atoi16(void) {
r = safe_atoi16("junk", &l);
assert_se(r == -EINVAL);
+
+ r = safe_atoi16("123x", &l);
+ assert_se(r == -EINVAL);
+}
+
+static void test_safe_atou64(void) {
+ int r;
+ uint64_t l;
+
+ r = safe_atou64("12345", &l);
+ assert_se(r == 0);
+ assert_se(l == 12345);
+
+ r = safe_atou64(" 12345", &l);
+ assert_se(r == 0);
+ assert_se(l == 12345);
+
+ r = safe_atou64("18446744073709551617", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atou64("-1", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atou64(" -1", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atou64("junk", &l);
+ assert_se(r == -EINVAL);
+
+ r = safe_atou64("123x", &l);
+ assert_se(r == -EINVAL);
+}
+
+static void test_safe_atoi64(void) {
+ int r;
+ int64_t l;
+
+ r = safe_atoi64("-12345", &l);
+ assert_se(r == 0);
+ assert_se(l == -12345);
+
+ r = safe_atoi64(" -12345", &l);
+ assert_se(r == 0);
+ assert_se(l == -12345);
+
+ r = safe_atoi64("32767", &l);
+ assert_se(r == 0);
+ assert_se(l == 32767);
+
+ r = safe_atoi64(" 32767", &l);
+ assert_se(r == 0);
+ assert_se(l == 32767);
+
+ r = safe_atoi64("9223372036854775813", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atoi64("-9223372036854775813", &l);
+ assert_se(r == -ERANGE);
+
+ r = safe_atoi64("junk", &l);
+ assert_se(r == -EINVAL);
+
+ r = safe_atoi64("123x", &l);
+ assert_se(r == -EINVAL);
}
static void test_safe_atod(void) {
assert_se(parse_nice("+20", &n) == -ERANGE);
}
+static void test_parse_dev(void) {
+ dev_t dev;
+
+ assert_se(parse_dev("0", &dev) == -EINVAL);
+ assert_se(parse_dev("5", &dev) == -EINVAL);
+ assert_se(parse_dev("5:", &dev) == -EINVAL);
+ assert_se(parse_dev(":5", &dev) == -EINVAL);
+#if SIZEOF_DEV_T < 8
+ assert_se(parse_dev("4294967295:4294967295", &dev) == -EINVAL);
+#endif
+ assert_se(parse_dev("8:11", &dev) >= 0 && major(dev) == 8 && minor(dev) == 11);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
test_safe_atolli();
test_safe_atou16();
test_safe_atoi16();
+ test_safe_atou64();
+ test_safe_atoi64();
test_safe_atod();
test_parse_percent();
test_parse_percent_unbounded();
test_parse_nice();
+ test_parse_dev();
return 0;
}
#include "mount-util.h"
#include "path-util.h"
#include "rm-rf.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
assert_se(!path_equal_ptr(NULL, "/a"));
}
+static void test_path_equal_root(void) {
+ /* Nail down the details of how path_equal("/", ...) works. */
+
+ assert_se(path_equal("/", "/"));
+ assert_se(path_equal("/", "//"));
+
+ assert_se(!path_equal("/", "/./"));
+ assert_se(!path_equal("/", "/../"));
+
+ assert_se(!path_equal("/", "/.../"));
+
+ /* Make sure that files_same works as expected. */
+
+ assert_se(files_same("/", "/", 0) > 0);
+ assert_se(files_same("/", "/", AT_SYMLINK_NOFOLLOW) > 0);
+ assert_se(files_same("/", "//", 0) > 0);
+ assert_se(files_same("/", "//", AT_SYMLINK_NOFOLLOW) > 0);
+
+ assert_se(files_same("/", "/./", 0) > 0);
+ assert_se(files_same("/", "/./", AT_SYMLINK_NOFOLLOW) > 0);
+ assert_se(files_same("/", "/../", 0) > 0);
+ assert_se(files_same("/", "/../", AT_SYMLINK_NOFOLLOW) > 0);
+
+ assert_se(files_same("/", "/.../", 0) == -ENOENT);
+ assert_se(files_same("/", "/.../", AT_SYMLINK_NOFOLLOW) == -ENOENT);
+
+ /* The same for path_equal_or_files_same. */
+
+ assert_se(path_equal_or_files_same("/", "/", 0));
+ assert_se(path_equal_or_files_same("/", "/", AT_SYMLINK_NOFOLLOW));
+ assert_se(path_equal_or_files_same("/", "//", 0));
+ assert_se(path_equal_or_files_same("/", "//", AT_SYMLINK_NOFOLLOW));
+
+ assert_se(path_equal_or_files_same("/", "/./", 0));
+ assert_se(path_equal_or_files_same("/", "/./", AT_SYMLINK_NOFOLLOW));
+ assert_se(path_equal_or_files_same("/", "/../", 0));
+ assert_se(path_equal_or_files_same("/", "/../", AT_SYMLINK_NOFOLLOW));
+
+ assert_se(!path_equal_or_files_same("/", "/.../", 0));
+ assert_se(!path_equal_or_files_same("/", "/.../", AT_SYMLINK_NOFOLLOW));
+}
+
static void test_find_binary(const char *self) {
char *p;
log_open();
test_path();
+ test_path_equal_root();
test_find_binary(argv[0]);
test_prefixes();
test_path_join();
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "hexdecoct.h"
+#include "random-util.h"
+#include "log.h"
+
+static void test_acquire_random_bytes(bool high_quality_required) {
+ uint8_t buf[16] = {};
+ unsigned i;
+
+ log_info("/* %s */", __func__);
+
+ for (i = 1; i < sizeof buf; i++) {
+ assert_se(acquire_random_bytes(buf, i, high_quality_required) == 0);
+ if (i + 1 < sizeof buf)
+ assert_se(buf[i] == 0);
+
+ hexdump(stdout, buf, i);
+ }
+}
+
+static void test_pseudorandom_bytes(void) {
+ uint8_t buf[16] = {};
+ unsigned i;
+
+ log_info("/* %s */", __func__);
+
+ for (i = 1; i < sizeof buf; i++) {
+ pseudorandom_bytes(buf, i);
+ if (i + 1 < sizeof buf)
+ assert_se(buf[i] == 0);
+
+ hexdump(stdout, buf, i);
+ }
+}
+
+int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_acquire_random_bytes(false);
+ test_acquire_random_bytes(true);
+
+ test_pseudorandom_bytes();
+
+ return 0;
+}
#include <stdlib.h>
#include <sys/eventfd.h>
#include <sys/mman.h>
-#include <unistd.h>
#include <sys/poll.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "alloc-util.h"
#include "fd-util.h"
#include "util.h"
#include "virt.h"
+#if SCMP_SYS(socket) < 0 || defined(__i386__) || defined(__s390x__) || defined(__s390__)
+/* On these archs, socket() is implemented via the socketcall() syscall multiplexer,
+ * and we can't restrict it hence via seccomp. */
+# define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1
+#else
+# define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0
+#endif
+
+
static void test_seccomp_arch_to_string(void) {
uint32_t a, b;
const char *name;
assert_se(streq(s, "cgroup ipc net mnt pid user uts"));
assert_se(namespace_flag_from_string_many(s, &ul) == 0 && ul == NAMESPACE_FLAGS_ALL);
-#if SECCOMP_RESTRICT_NAMESPACES_BROKEN == 0
-
if (!is_seccomp_available())
return;
if (geteuid() != 0)
}
assert_se(wait_for_terminate_and_warn("nsseccomp", pid, true) == EXIT_SUCCESS);
-#endif
}
static void test_protect_sysctl(void) {
assert_se(fd >= 0);
safe_close(fd);
-#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
assert_se(fd >= 0);
safe_close(fd);
#else
- assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0);
+ assert_se(fd < 0);
assert_se(errno == EAFNOSUPPORT);
#endif
assert_se(fd >= 0);
safe_close(fd);
-#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
assert_se(fd >= 0);
safe_close(fd);
+#else
+ assert_se(fd < 0);
+ assert_se(errno == EAFNOSUPPORT);
+#endif
fd = socket(AF_NETLINK, SOCK_DGRAM, 0);
+#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN
assert_se(fd >= 0);
safe_close(fd);
#else
- assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0);
- assert_se(errno == EAFNOSUPPORT);
-
- assert_se(socket(AF_NETLINK, SOCK_DGRAM, 0) < 0);
+ assert_se(fd < 0);
assert_se(errno == EAFNOSUPPORT);
#endif
assert_se(wait_for_terminate_and_warn("realtimeseccomp", pid, true) == EXIT_SUCCESS);
}
-static void test_memory_deny_write_execute(void) {
+static void test_memory_deny_write_execute_mmap(void) {
pid_t pid;
if (!is_seccomp_available())
assert_se(seccomp_memory_deny_write_execute() >= 0);
-#if SECCOMP_MEMORY_DENY_WRITE_EXECUTE_BROKEN
- p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
- assert_se(p != MAP_FAILED);
- assert_se(munmap(p, page_size()) >= 0);
-#else
p = mmap(NULL, page_size(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
+#if defined(__x86_64__) || defined(__i386__) || defined(__powerpc64__) || defined(__arm__) || defined(__aarch64__)
assert_se(p == MAP_FAILED);
assert_se(errno == EPERM);
+#else /* unknown architectures */
+ assert_se(p != MAP_FAILED);
+ assert_se(munmap(p, page_size()) >= 0);
#endif
p = mmap(NULL, page_size(), PROT_WRITE|PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1,0);
_exit(EXIT_SUCCESS);
}
- assert_se(wait_for_terminate_and_warn("memoryseccomp", pid, true) == EXIT_SUCCESS);
+ assert_se(wait_for_terminate_and_warn("memoryseccomp-mmap", pid, true) == EXIT_SUCCESS);
+}
+
+static void test_memory_deny_write_execute_shmat(void) {
+ int shmid;
+ pid_t pid;
+
+ if (!is_seccomp_available())
+ return;
+ if (geteuid() != 0)
+ return;
+
+ shmid = shmget(IPC_PRIVATE, page_size(), 0);
+ assert_se(shmid >= 0);
+
+ pid = fork();
+ assert_se(pid >= 0);
+
+ if (pid == 0) {
+ void *p;
+
+ p = shmat(shmid, NULL, 0);
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+
+ p = shmat(shmid, NULL, SHM_EXEC);
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+
+ assert_se(seccomp_memory_deny_write_execute() >= 0);
+
+ p = shmat(shmid, NULL, SHM_EXEC);
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
+ assert_se(p == MAP_FAILED);
+ assert_se(errno == EPERM);
+#else /* __i386__, __powerpc64__, and "unknown" architectures */
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+#endif
+
+ p = shmat(shmid, NULL, 0);
+ assert_se(p != MAP_FAILED);
+ assert_se(shmdt(p) == 0);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ assert_se(wait_for_terminate_and_warn("memoryseccomp-shmat", pid, true) == EXIT_SUCCESS);
}
static void test_restrict_archs(void) {
test_protect_sysctl();
test_restrict_address_families();
test_restrict_realtime();
- test_memory_deny_write_execute();
+ test_memory_deny_write_execute_mmap();
+ test_memory_deny_write_execute_shmat();
test_restrict_archs();
test_load_syscall_filter_set_raw();
b = mac_selinux_use();
log_info("mac_selinux_use → %s", yes_no(b));
- b = mac_selinux_have();
- log_info("mac_selinux_have → %s", yes_no(b));
+ b = mac_selinux_use();
+ log_info("mac_selinux_use → %s", yes_no(b));
mac_selinux_retest();
b = mac_selinux_use();
log_info("mac_selinux_use → %s", yes_no(b));
- b = mac_selinux_have();
- log_info("mac_selinux_have → %s", yes_no(b));
+ b = mac_selinux_use();
+ log_info("mac_selinux_use → %s", yes_no(b));
}
static void test_loading(void) {
#include "fd-util.h"
#include "sigbus.h"
#include "util.h"
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
int main(int argc, char *argv[]) {
_cleanup_close_ int fd = -1;
void *addr = NULL;
uint8_t *p;
+#ifdef HAVE_VALGRIND_VALGRIND_H
+ if (RUNNING_ON_VALGRIND)
+ return EXIT_TEST_SKIP;
+#endif
+
#ifdef __SANITIZE_ADDRESS__
return EXIT_TEST_SKIP;
#endif
assert_se((fd = mkostemp(template, O_RDWR|O_CREAT|O_EXCL)) >= 0);
assert_se(unlink(template) >= 0);
- assert_se(fallocate(fd, 0, 0, page_size() * 8) >= 0);
+ assert_se(posix_fallocate(fd, 0, page_size() * 8) >= 0);
p = mmap(NULL, page_size() * 16, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
assert_se(p != MAP_FAILED);
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "log.h"
+#include <stdio.h>
+
#include "time-util.h"
/* Print information about various types. Useful when diagnosing
#pragma GCC diagnostic ignored "-Wtype-limits"
#define info(t) \
- log_info("%s → %zu bits%s", STRINGIFY(t), \
- sizeof(t)*CHAR_BIT, \
- strstr(STRINGIFY(t), "signed") ? "" : \
- ((t)-1 < (t)0 ? ", signed" : ", unsigned"));
+ printf("%s → %zu bits%s\n", STRINGIFY(t), \
+ sizeof(t)*CHAR_BIT, \
+ strstr(STRINGIFY(t), "signed") ? "" : \
+ ((t)-1 < (t)0 ? ", signed" : ", unsigned"));
+
+enum Enum {
+ enum_value,
+};
+
+enum BigEnum {
+ big_enum_value = UINT64_C(-1),
+};
int main(void) {
info(char);
info(unsigned);
info(long unsigned);
info(long long unsigned);
+ info(__syscall_ulong_t);
+ info(__syscall_slong_t);
info(float);
info(double);
info(ssize_t);
info(time_t);
info(usec_t);
+ info(__time_t);
+
+ info(enum Enum);
+ info(enum BigEnum);
return 0;
}
assert_se(fd >= 0);
assert_se(symlink(name, name_alias) >= 0);
- assert_se(files_same(name, name));
- assert_se(files_same(name, name_alias));
+ assert_se(files_same(name, name, 0));
+ assert_se(files_same(name, name, AT_SYMLINK_NOFOLLOW));
+ assert_se(files_same(name, name_alias, 0));
+ assert_se(!files_same(name, name_alias, AT_SYMLINK_NOFOLLOW));
unlink(name);
unlink(name_alias);
assert_se(streq(target, "space left: 25. foobar"));
assert_se(space_left == 3);
+
+ /* test overflow */
+ s = target;
+ space_left = strpcpyf(&s, 12, "00 left: %i. ", 999);
+ assert_se(streq(target, "00 left: 99"));
+ assert_se(space_left == 0);
+ assert_se(target[12] == '2');
}
static void test_strpcpyl(void) {
assert_se(parse_sec(".3 infinity", &u) < 0);
}
+static void test_parse_sec_fix_0(void) {
+ usec_t u;
+
+ assert_se(parse_sec_fix_0("5s", &u) >= 0);
+ assert_se(u == 5 * USEC_PER_SEC);
+ assert_se(parse_sec_fix_0("0s", &u) >= 0);
+ assert_se(u == 0 * USEC_PER_SEC);
+ assert_se(parse_sec_fix_0("0", &u) >= 0);
+ assert_se(u == USEC_INFINITY);
+ assert_se(parse_sec_fix_0(" 0", &u) >= 0);
+ assert_se(u == USEC_INFINITY);
+}
+
static void test_parse_time(void) {
usec_t u;
assert_se(usec_add(USEC_INFINITY, 2) == USEC_INFINITY);
}
-static void test_usec_sub(void) {
- assert_se(usec_sub(0, 0) == 0);
- assert_se(usec_sub(4, 1) == 3);
- assert_se(usec_sub(4, 4) == 0);
- assert_se(usec_sub(4, 5) == 0);
- assert_se(usec_sub(USEC_INFINITY-3, -3) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY-3, -3) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY-3, -4) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY-3, -5) == USEC_INFINITY);
- assert_se(usec_sub(USEC_INFINITY, 5) == USEC_INFINITY);
+static void test_usec_sub_unsigned(void) {
+ assert_se(usec_sub_unsigned(0, 0) == 0);
+ assert_se(usec_sub_unsigned(0, 2) == 0);
+ assert_se(usec_sub_unsigned(0, USEC_INFINITY) == 0);
+ assert_se(usec_sub_unsigned(1, 0) == 1);
+ assert_se(usec_sub_unsigned(1, 1) == 0);
+ assert_se(usec_sub_unsigned(1, 2) == 0);
+ assert_se(usec_sub_unsigned(1, 3) == 0);
+ assert_se(usec_sub_unsigned(1, USEC_INFINITY) == 0);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, 0) == USEC_INFINITY-1);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, 1) == USEC_INFINITY-2);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, 2) == USEC_INFINITY-3);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, USEC_INFINITY-2) == 1);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, USEC_INFINITY-1) == 0);
+ assert_se(usec_sub_unsigned(USEC_INFINITY-1, USEC_INFINITY) == 0);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, 0) == USEC_INFINITY);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, 1) == USEC_INFINITY);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, 2) == USEC_INFINITY);
+ assert_se(usec_sub_unsigned(USEC_INFINITY, USEC_INFINITY) == USEC_INFINITY);
+}
+
+static void test_usec_sub_signed(void) {
+ assert_se(usec_sub_signed(0, 0) == 0);
+ assert_se(usec_sub_signed(4, 1) == 3);
+ assert_se(usec_sub_signed(4, 4) == 0);
+ assert_se(usec_sub_signed(4, 5) == 0);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -3) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -3) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -4) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY-3, -5) == USEC_INFINITY);
+ assert_se(usec_sub_signed(USEC_INFINITY, 5) == USEC_INFINITY);
}
static void test_format_timestamp(void) {
test_format_timestamp_utc_one(USEC_INFINITY, NULL);
}
+static void test_dual_timestamp_deserialize(void) {
+ int r;
+ dual_timestamp t;
+
+ r = dual_timestamp_deserialize("1234 5678", &t);
+ assert_se(r == 0);
+ assert_se(t.realtime == 1234);
+ assert_se(t.monotonic == 5678);
+
+ r = dual_timestamp_deserialize("1234x 5678", &t);
+ assert_se(r == -EINVAL);
+
+ r = dual_timestamp_deserialize("1234 5678y", &t);
+ assert_se(r == -EINVAL);
+
+ r = dual_timestamp_deserialize("-1234 5678", &t);
+ assert_se(r == -EINVAL);
+
+ r = dual_timestamp_deserialize("1234 -5678", &t);
+ assert_se(r == -EINVAL);
+
+ /* Check that output wasn't modified. */
+ assert_se(t.realtime == 1234);
+ assert_se(t.monotonic == 5678);
+
+ r = dual_timestamp_deserialize("+123 567", &t);
+ assert_se(r == 0);
+ assert_se(t.realtime == 123);
+ assert_se(t.monotonic == 567);
+
+ /* Check that we get "infinity" on overflow. */
+ r = dual_timestamp_deserialize("18446744073709551617 0", &t);
+ assert_se(r == 0);
+ assert_se(t.realtime == USEC_INFINITY);
+ assert_se(t.monotonic == 0);
+}
+
+static void assert_similar(usec_t a, usec_t b) {
+ usec_t d;
+
+ if (a > b)
+ d = a - b;
+ else
+ d = b - a;
+
+ assert(d < 10*USEC_PER_SEC);
+}
+
+static void test_usec_shift_clock(void) {
+ usec_t rt, mn, bt;
+
+ rt = now(CLOCK_REALTIME);
+ mn = now(CLOCK_MONOTONIC);
+ bt = now(clock_boottime_or_monotonic());
+
+ assert_se(usec_shift_clock(USEC_INFINITY, CLOCK_REALTIME, CLOCK_MONOTONIC) == USEC_INFINITY);
+
+ assert_similar(usec_shift_clock(rt + USEC_PER_HOUR, CLOCK_REALTIME, CLOCK_MONOTONIC), mn + USEC_PER_HOUR);
+ assert_similar(usec_shift_clock(rt + 2*USEC_PER_HOUR, CLOCK_REALTIME, clock_boottime_or_monotonic()), bt + 2*USEC_PER_HOUR);
+ assert_se(usec_shift_clock(rt + 3*USEC_PER_HOUR, CLOCK_REALTIME, CLOCK_REALTIME_ALARM) == rt + 3*USEC_PER_HOUR);
+
+ assert_similar(usec_shift_clock(mn + 4*USEC_PER_HOUR, CLOCK_MONOTONIC, CLOCK_REALTIME_ALARM), rt + 4*USEC_PER_HOUR);
+ assert_similar(usec_shift_clock(mn + 5*USEC_PER_HOUR, CLOCK_MONOTONIC, clock_boottime_or_monotonic()), bt + 5*USEC_PER_HOUR);
+ assert_se(usec_shift_clock(mn + 6*USEC_PER_HOUR, CLOCK_MONOTONIC, CLOCK_MONOTONIC) == mn + 6*USEC_PER_HOUR);
+
+ assert_similar(usec_shift_clock(bt + 7*USEC_PER_HOUR, clock_boottime_or_monotonic(), CLOCK_MONOTONIC), mn + 7*USEC_PER_HOUR);
+ assert_similar(usec_shift_clock(bt + 8*USEC_PER_HOUR, clock_boottime_or_monotonic(), CLOCK_REALTIME_ALARM), rt + 8*USEC_PER_HOUR);
+ assert_se(usec_shift_clock(bt + 9*USEC_PER_HOUR, clock_boottime_or_monotonic(), clock_boottime_or_monotonic()) == bt + 9*USEC_PER_HOUR);
+
+ if (mn > USEC_PER_MINUTE) {
+ assert_similar(usec_shift_clock(rt - 30 * USEC_PER_SEC, CLOCK_REALTIME_ALARM, CLOCK_MONOTONIC), mn - 30 * USEC_PER_SEC);
+ assert_similar(usec_shift_clock(rt - 50 * USEC_PER_SEC, CLOCK_REALTIME, clock_boottime_or_monotonic()), bt - 50 * USEC_PER_SEC);
+ }
+}
+
int main(int argc, char *argv[]) {
uintmax_t x;
+ log_info("realtime=" USEC_FMT "\n"
+ "monotonic=" USEC_FMT "\n"
+ "boottime=" USEC_FMT "\n",
+ now(CLOCK_REALTIME),
+ now(CLOCK_MONOTONIC),
+ now(clock_boottime_or_monotonic()));
+
test_parse_sec();
+ test_parse_sec_fix_0();
test_parse_time();
test_parse_nsec();
test_format_timespan(1);
test_timezone_is_valid();
test_get_timezones();
test_usec_add();
- test_usec_sub();
+ test_usec_sub_signed();
+ test_usec_sub_unsigned();
test_format_timestamp();
test_format_timestamp_utc();
+ test_dual_timestamp_deserialize();
+ test_usec_shift_clock();
/* Ensure time_t is signed */
assert_cc((time_t) -1 < (time_t) 1);
if (udev == NULL)
return EXIT_FAILURE;
- log_debug("version %s", VERSION);
+ log_debug("version %s", PACKAGE_VERSION);
mac_selinux_init();
action = argv[1];
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/RValue/ argv0 r1",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* honour_argv0 */");
r = config_parse_exec(NULL, "fake", 3, "section", 1,
"LValue", 0, "@/RValue",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* no command, whitespace only, reset */");
"-@/RValue argv0 r1 ; ; "
"/goo/goo boo",
&c, u);
- assert_se(r >= 0);
+ assert_se(r == -ENOEXEC);
c1 = c1->command_next;
check_execcommand(c1, "/RValue", "argv0", "r1", NULL, true);
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, path,
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
}
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/path\\",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* missing ending ' */");
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/path 'foo",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* missing ending ' with trailing backslash */");
r = config_parse_exec(NULL, "fake", 4, "section", 1,
"LValue", 0, "/path 'foo\\",
&c, u);
- assert_se(r == 0);
+ assert_se(r == -ENOEXEC);
assert_se(c1->command_next == NULL);
log_info("/* invalid space between modifiers */");
--- /dev/null
+if conf.get('ENABLE_TIMEDATED', false)
+ install_data('org.freedesktop.timedate1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.timedate1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.timedate1.policy',
+ input : 'org.freedesktop.timedate1.policy.in',
+ output : 'org.freedesktop.timedate1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+endif
--- /dev/null
+systemd_timesyncd_sources = files('''
+ timesyncd.c
+ timesyncd-manager.c
+ timesyncd-manager.h
+ timesyncd-conf.c
+ timesyncd-conf.h
+ timesyncd-server.c
+ timesyncd-server.h
+'''.split())
+
+timesyncd_gperf_c = custom_target(
+ 'timesyncd-gperf.c',
+ input : 'timesyncd-gperf.gperf',
+ output : 'timesyncd-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+systemd_timesyncd_sources += [timesyncd_gperf_c]
+
+if conf.get('ENABLE_TIMESYNCD', false)
+ timesyncd_conf = configure_file(
+ input : 'timesyncd.conf.in',
+ output : 'timesyncd.conf',
+ configuration : substs)
+ install_data(timesyncd_conf,
+ install_dir : pkgsysconfdir)
+endif
+
+############################################################
+
+tests += [
+ [['src/timesync/test-timesync.c',
+ 'src/timesync/timesyncd-manager.c',
+ 'src/timesync/timesyncd-manager.h',
+ 'src/timesync/timesyncd-conf.c',
+ 'src/timesync/timesyncd-conf.h',
+ 'src/timesync/timesyncd-server.c',
+ 'src/timesync/timesyncd-server.h',
+ timesyncd_gperf_c],
+ [libshared],
+ [libm],
+ 'ENABLE_TIMESYNCD'],
+]
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+/* Some unit tests for the helper functions in timesyncd. */
+
+#include "log.h"
+#include "macro.h"
+#include "timesyncd-conf.h"
+
+static void test_manager_parse_string(void) {
+ /* Make sure that NTP_SERVERS is configured to something
+ * that we can actually parse successfully. */
+
+ _cleanup_(manager_freep) Manager *m = NULL;
+
+ assert_se(manager_new(&m) == 0);
+
+ assert_se(!m->have_fallbacks);
+ assert_se(manager_parse_server_string(m, SERVER_FALLBACK, NTP_SERVERS) == 0);
+ assert_se(m->have_fallbacks);
+ assert_se(manager_parse_fallback_string(m, NTP_SERVERS) == 0);
+
+ assert_se(manager_parse_server_string(m, SERVER_SYSTEM, "time1.foobar.com time2.foobar.com") == 0);
+ assert_se(manager_parse_server_string(m, SERVER_FALLBACK, "time1.foobar.com time2.foobar.com") == 0);
+ assert_se(manager_parse_server_string(m, SERVER_LINK, "time1.foobar.com time2.foobar.com") == 0);
+}
+
+int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
+ test_manager_parse_string();
+
+ return 0;
+}
first = type == SERVER_FALLBACK ? m->fallback_servers : m->system_servers;
+ if (type == SERVER_FALLBACK)
+ m->have_fallbacks = true;
+
for (;;) {
_cleanup_free_ char *word = NULL;
bool found = false;
return 0;
}
+int manager_parse_fallback_string(Manager *m, const char *string) {
+ if (m->have_fallbacks)
+ return 0;
+
+ return manager_parse_server_string(m, SERVER_FALLBACK, string);
+}
+
int config_parse_servers(
const char *unit,
const char *filename,
assert(m);
return config_parse_many_nulstr(PKGSYSCONFDIR "/timesyncd.conf",
- CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
- "Time\0",
- config_item_perf_lookup, timesyncd_gperf_lookup,
- false, m);
+ CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
+ "Time\0",
+ config_item_perf_lookup, timesyncd_gperf_lookup,
+ false, m);
}
int config_parse_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int manager_parse_config_file(Manager *m);
+int manager_parse_fallback_string(Manager *m, const char *string);
m->drift_ppm = tmx.freq / 65536;
log_debug(" status : %04i %s\n"
- " time now : %li.%03"PRI_USEC"\n"
- " constant : %li\n"
+ " time now : %"PRI_TIME".%03"PRI_USEC"\n"
+ " constant : %"PRI_TIMEX"\n"
" offset : %+.3f sec\n"
- " freq offset : %+li (%i ppm)\n",
+ " freq offset : %+"PRI_TIMEX" (%i ppm)\n",
tmx.status, tmx.status & STA_UNSYNC ? "unsync" : "sync",
tmx.time.tv_sec, tmx.time.tv_usec / NSEC_PER_MSEC,
tmx.constant,
RATELIMIT_INIT(m->ratelimit, RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST);
- r = manager_parse_server_string(m, SERVER_FALLBACK, NTP_SERVERS);
- if (r < 0)
- return r;
-
r = sd_event_default(&m->event);
if (r < 0)
return r;
LIST_HEAD(ServerName, link_servers);
LIST_HEAD(ServerName, fallback_servers);
+ bool have_fallbacks:1;
+
RateLimit ratelimit;
bool exhausted_servers;
if (r < 0)
log_warning_errno(r, "Failed to parse configuration file: %m");
+ r = manager_parse_fallback_string(m, NTP_SERVERS);
+ if (r < 0) {
+ log_error_errno(r, "Failed to parse fallback server strings: %m");
+ goto finish;
+ }
+
log_debug("systemd-timesyncd running as pid " PID_FMT, getpid());
sd_notify(false,
"READY=1\n"
n = strlen(*value);
log_debug("Setting extended attribute '%s=%s' on %s.", *name, *value, path);
- if (lsetxattr(path, *name, *value, n, 0) < 0) {
- log_error("Setting extended attribute %s=%s on %s failed: %m", *name, *value, path);
- return -errno;
- }
+ if (lsetxattr(path, *name, *value, n, 0) < 0)
+ return log_error_errno(errno, "Setting extended attribute %s=%s on %s failed: %m",
+ *name, *value, path);
}
return 0;
}
r = chattr_fd(fd, f, item->attribute_mask);
if (r < 0)
- log_full_errno(r == -ENOTTY ? LOG_DEBUG : LOG_WARNING,
+ log_full_errno(r == -ENOTTY || r == -EOPNOTSUPP ? LOG_DEBUG : LOG_WARNING,
r,
"Cannot set file attribute for '%s', value=0x%08x, mask=0x%08x: %m",
path, item->attribute_value, item->attribute_mask);
static int glob_item(Item *i, action_t action, bool recursive) {
_cleanup_globfree_ glob_t g = {
- .gl_closedir = (void (*)(void *)) closedir,
- .gl_readdir = (struct dirent *(*)(void *)) readdir,
.gl_opendir = (void *(*)(const char *)) opendir_nomod,
- .gl_lstat = lstat,
- .gl_stat = stat,
};
int r = 0, k;
char **fn;
- errno = 0;
- k = glob(i->path, GLOB_NOSORT|GLOB_BRACE|GLOB_ALTDIRFUNC, NULL, &g);
- if (k != 0 && k != GLOB_NOMATCH)
- return log_error_errno(errno ?: EIO, "glob(%s) failed: %m", i->path);
+ k = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (k < 0 && k != -ENOENT)
+ return log_error_errno(k, "glob(%s) failed: %m", i->path);
STRV_FOREACH(fn, g.gl_pathv) {
k = action(i, *fn);
{}
};
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
#include "libudev-private.h"
#include "random-util.h"
+#include "udev-util.h"
/* device info */
static unsigned int cd_cd_rom;
return 0;
}
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
struct udev *udev;
static const struct option options[] = {
{ "lock-media", no_argument, NULL, 'l' },
int cnt;
int rc = 0;
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
#include "macro.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "udev-util.h"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
}
}
-int main(int argc, char **argv)
-{
- struct udev *udev;
+int main(int argc, char **argv) {
static const struct option options[] = {
{ "add", no_argument, NULL, 'a' },
{ "remove", no_argument, NULL, 'r' },
int prune = 0;
char tmpdir[UTIL_PATH_SIZE];
- udev = udev_new();
- if (udev == NULL) {
- ret = EXIT_FAILURE;
- goto exit;
- }
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
+ log_parse_environment();
+ log_open();
for (;;) {
int option;
break;
case 'h':
usage();
- goto exit;
+ return 0;
default:
- ret = 1;
- goto exit;
+ return 1;
}
}
argi = optind;
if (argi + 2 > argc) {
printf("Missing parameter(s)\n");
- ret = 1;
- goto exit;
+ return 1;
}
checkpoint = argv[argi++];
us = argv[argi++];
if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
fprintf(stderr, "Cannot set SIGALRM: %m\n");
- ret = 2;
- goto exit;
+ return 2;
}
udev_list_node_init(&bunch);
everybody();
if (ret >= 0)
printf("COLLECT_%s=%d\n", checkpoint, ret);
-exit:
- udev_unref(udev);
return ret;
}
--- /dev/null
+#!/bin/sh -eu
+awk ' BEGIN {
+ print "struct key_name { const char* name; unsigned short id; };"
+ print "%null-strings"
+ print "%%"
+ }
+
+ /^KEY_/ { print tolower(substr($1 ,5)) ", " $1 }
+ { print tolower($1) ", " $1 }
+' < "$1"
--- /dev/null
+#!/bin/sh -eu
+
+$1 -dM -include linux/input.h - </dev/null | awk '
+ /\<(KEY_(MAX|MIN_INTERESTING))|(BTN_(MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI|WHEEL|TRIGGER_HAPPY))\>/ { next }
+ /^#define[ \t]+(KEY|BTN)_[^ ]+[ \t]+[0-9BK]/ { print $2 }
+'
--- /dev/null
+udevadm_sources = files('''
+ udevadm.c
+ udevadm-info.c
+ udevadm-control.c
+ udevadm-monitor.c
+ udevadm-hwdb.c
+ udevadm-settle.c
+ udevadm-trigger.c
+ udevadm-test.c
+ udevadm-test-builtin.c
+ udevadm-util.c
+ udevadm-util.h
+'''.split())
+
+systemd_udevd_sources = files('udevd.c')
+
+libudev_core_sources = '''
+ udev.h
+ udev-event.c
+ udev-watch.c
+ udev-node.c
+ udev-rules.c
+ udev-ctrl.c
+ udev-builtin.c
+ udev-builtin-btrfs.c
+ udev-builtin-hwdb.c
+ udev-builtin-input_id.c
+ udev-builtin-keyboard.c
+ udev-builtin-net_id.c
+ udev-builtin-net_setup_link.c
+ udev-builtin-path_id.c
+ udev-builtin-usb_id.c
+ net/link-config.c
+ net/link-config.h
+ net/ethtool-util.c
+ net/ethtool-util.h
+'''.split()
+
+if conf.get('HAVE_KMOD', false)
+ libudev_core_sources += ['udev-builtin-kmod.c']
+endif
+
+if conf.get('HAVE_BLKID', false)
+ libudev_core_sources += ['udev-builtin-blkid.c']
+endif
+
+if conf.get('HAVE_ACL', false)
+ libudev_core_sources += ['udev-builtin-uaccess.c',
+ logind_acl_c,
+ sd_login_c]
+endif
+
+############################################################
+
+generate_keyboard_keys_list = find_program('generate-keyboard-keys-list.sh')
+keyboard_keys_list_txt = custom_target(
+ 'keyboard-keys-list.txt',
+ output : 'keyboard-keys-list.txt',
+ command : [generate_keyboard_keys_list, cpp],
+ capture : true)
+
+generate_keyboard_keys_gperf = find_program('generate-keyboard-keys-gperf.sh')
+fname = 'keyboard-keys-from-name.gperf'
+gperf_file = custom_target(
+ fname,
+ input : keyboard_keys_list_txt,
+ output : fname,
+ command : [generate_keyboard_keys_gperf, '@INPUT@'],
+ capture : true)
+
+fname = 'keyboard-keys-from-name.h'
+keyboard_keys_from_name_h = custom_target(
+ fname,
+ input : gperf_file,
+ output : fname,
+ command : [gperf,
+ '-L', 'ANSI-C', '-t',
+ '-N', 'keyboard_lookup_key',
+ '-H', 'hash_key_name',
+ '-p', '-C',
+ '@INPUT@'],
+ capture : true)
+
+############################################################
+
+link_config_gperf_c = custom_target(
+ 'link-config-gperf.c',
+ input : 'net/link-config-gperf.gperf',
+ output : 'link-config-gperf.c',
+ command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
+
+############################################################
+
+if get_option('link-udev-shared')
+ udev_link_with = [libshared]
+ udev_rpath = rootlibexecdir
+else
+ udev_link_with = [libshared_static,
+ libsystemd_internal]
+ udev_rpath = ''
+endif
+
+libudev_internal = static_library(
+ 'udev',
+ libudev_sources,
+ include_directories : includes,
+ link_with : udev_link_with)
+
+libudev_core_includes = [includes, include_directories('net')]
+libudev_core = static_library(
+ 'udev-core',
+ libudev_core_sources,
+ link_config_gperf_c,
+ keyboard_keys_from_name_h,
+ include_directories : libudev_core_includes,
+ link_with : udev_link_with,
+ dependencies : [libblkid, libkmod])
+
+foreach prog : [['ata_id/ata_id.c'],
+ ['cdrom_id/cdrom_id.c'],
+ ['collect/collect.c'],
+ ['scsi_id/scsi_id.c',
+ 'scsi_id/scsi_id.h',
+ 'scsi_id/scsi_serial.c',
+ 'scsi_id/scsi.h'],
+ ['v4l_id/v4l_id.c'],
+ ['mtd_probe/mtd_probe.c',
+ 'mtd_probe/mtd_probe.h',
+ 'mtd_probe/probe_smartmedia.c']]
+
+ executable(prog[0].split('/')[0],
+ prog,
+ include_directories : includes,
+ c_args : ['-DLOG_REALM=LOG_REALM_UDEV'],
+ link_with : [libudev_internal],
+ install_rpath : udev_rpath,
+ install : true,
+ install_dir : udevlibexecdir)
+endforeach
+
+install_data('udev.conf',
+ install_dir : join_paths(sysconfdir, 'udev'))
+
+udev_pc = configure_file(
+ input : 'udev.pc.in',
+ output : 'udev.pc',
+ configuration : substs)
+install_data(udev_pc,
+ install_dir : pkgconfigdatadir)
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'udev/rules.d')))
#include "conf-parser.h"
#include "ethtool-util.h"
#include "log.h"
+#include "link-config.h"
#include "socket-util.h"
#include "string-table.h"
#include "strxcpyx.h"
DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan);
DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting");
+static const char* const port_table[_NET_DEV_PORT_MAX] = {
+ [NET_DEV_PORT_TP] = "tp",
+ [NET_DEV_PORT_AUI] = "aui",
+ [NET_DEV_PORT_MII] = "mii",
+ [NET_DEV_PORT_FIBRE] = "fibre",
+ [NET_DEV_PORT_BNC] = "bnc"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
+
static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
[NET_DEV_FEAT_GSO] = "tx-generic-segmentation",
[NET_DEV_FEAT_GRO] = "rx-gro",
* enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
*/
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autonegotiation) {
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link) {
_cleanup_free_ struct ethtool_link_usettings *u = NULL;
struct ifreq ifr = {};
int r;
- if (autonegotiation != 0) {
+ if (link->autonegotiation != 0) {
log_info("link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.");
return 0;
}
return log_warning_errno(r, "link_config: Cannot get device settings for %s : %m", ifname);
}
- if (speed)
- u->base.speed = speed;
+ if (link->speed)
+ u->base.speed = DIV_ROUND_UP(link->speed, 1000000);
+
+ if (link->duplex != _DUP_INVALID)
+ u->base.duplex = link->duplex;
- if (duplex != _DUP_INVALID)
- u->base.duplex = duplex;
+ if (link->port != _NET_DEV_PORT_INVALID)
+ u->base.port = link->port;
- u->base.autoneg = autonegotiation;
+ u->base.autoneg = link->autonegotiation;
if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
r = set_slinksettings(fd, &ifr, u);
#include "missing.h"
+struct link_config;
+
/* we can't use DUPLEX_ prefix, as it
* clashes with <linux/ethtool.h> */
typedef enum Duplex {
- DUP_FULL,
- DUP_HALF,
+ DUP_HALF = DUPLEX_HALF,
+ DUP_FULL = DUPLEX_FULL,
_DUP_MAX,
_DUP_INVALID = -1
} Duplex;
_NET_DEV_FEAT_INVALID = -1
} NetDevFeature;
+typedef enum NetDevPort {
+ NET_DEV_PORT_TP = 0x00,
+ NET_DEV_PORT_AUI = 0x01,
+ NET_DEV_PORT_MII = 0x02,
+ NET_DEV_PORT_FIBRE = 0x03,
+ NET_DEV_PORT_BNC = 0x04,
+ NET_DEV_PORT_DA = 0x05,
+ NET_DEV_PORT_NONE = 0xef,
+ NET_DEV_PORT_OTHER = 0xff,
+ _NET_DEV_PORT_MAX,
+ _NET_DEV_PORT_INVALID = -1
+} NetDevPort;
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 (SCHAR_MAX)
int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autoneg);
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
const char *wol_to_string(WakeOnLan wol) _const_;
WakeOnLan wol_from_string(const char *wol) _pure_;
+const char *port_to_string(NetDevPort port) _const_;
+NetDevPort port_from_string(const char *port) _pure_;
+
int config_parse_duplex(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);
int config_parse_wol(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);
+int config_parse_port(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);
Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
+Link.Port, config_parse_port, 0, offsetof(link_config, port)
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO])
Link.UDPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_UFO])
link->mac_policy = _MACPOLICY_INVALID;
link->wol = _WOL_INVALID;
link->duplex = _DUP_INVALID;
+ link->port = _NET_DEV_PORT_INVALID;
link->autonegotiation = -1;
memset(&link->features, -1, sizeof(link->features));
if (!old_name)
return -EINVAL;
-
- speed = DIV_ROUND_UP(config->speed, 1000000);
-
- r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, speed, config->duplex, config->autonegotiation);
+ r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, config);
if (r < 0) {
+ if (config->port != _NET_DEV_PORT_INVALID)
+ log_warning_errno(r, "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
+
+ speed = DIV_ROUND_UP(config->speed, 1000000);
if (r == -EOPNOTSUPP)
r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
Duplex duplex;
int autonegotiation;
WakeOnLan wol;
+ NetDevPort port;
NetDevFeature features[_NET_DEV_FEAT_MAX];
LIST_FIELDS(link_config, links);
break;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
exit(0);
case 'x':
int newargc;
char **newargv = NULL;
+ log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <blkid/blkid.h>
+#include <blkid.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include "sd-id128.h"
#include "alloc-util.h"
+#include "blkid-util.h"
#include "efivars.h"
#include "fd-util.h"
#include "gpt.h"
int64_t offset = 0;
bool noraid = false;
_cleanup_close_ int fd = -1;
- blkid_probe pr;
+ _cleanup_blkid_free_probe_ blkid_probe pr = NULL;
const char *data;
const char *name;
- const char *prtype = NULL;
int nvals;
int i;
int err = 0;
blkid_probe_set_superblocks_flags(pr,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
- BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION |
- BLKID_SUBLKS_BADCSUM);
+ BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
if (noraid)
blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
err = probe_superblocks(pr);
if (err < 0)
goto out;
- if (blkid_probe_has_value(pr, "SBBADCSUM")) {
- if (!blkid_probe_lookup_value(pr, "TYPE", &prtype, NULL))
- log_warning("incorrect %s checksum on %s",
- prtype, udev_device_get_devnode(dev));
- else
- log_warning("incorrect checksum on %s",
- udev_device_get_devnode(dev));
- goto out;
- }
/* If we are a partition then our parent passed on the root
* partition UUID to us */
if (is_gpt)
find_gpt_root(dev, pr, test);
- blkid_free_probe(pr);
out:
if (err < 0)
return EXIT_FAILURE;
#include <linux/input.h>
#include "fd-util.h"
+#include "missing.h"
#include "stdio-util.h"
#include "string-util.h"
#include "udev.h"
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+struct range {
+ unsigned start;
+ unsigned end;
+};
+
+/* key code ranges above BTN_MISC (start is inclusive, stop is exclusive)*/
+static const struct range high_key_blocks[] = {
+ { KEY_OK, BTN_DPAD_UP },
+ { KEY_ALS_TOGGLE, BTN_TRIGGER_HAPPY }
+};
+
static inline int abs_size_mm(const struct input_absinfo *absinfo) {
/* Resolution is defined to be in units/mm for ABS_X/Y */
return (absinfo->maximum - absinfo->minimum) / absinfo->resolution;
const unsigned long* bitmask_rel,
const unsigned long* bitmask_props,
bool test) {
+ int button, axis;
bool has_abs_coordinates = false;
bool has_rel_coordinates = false;
bool has_mt_coordinates = false;
is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
- has_mouse_button = test_bit(BTN_LEFT, bitmask_key);
+ for (button = BTN_MOUSE; button < BTN_JOYSTICK && !has_mouse_button; button++)
+ has_mouse_button = test_bit(button, bitmask_key);
has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
has_touch = test_bit(BTN_TOUCH, bitmask_key);
/* joysticks don't necessarily have buttons; e. g.
* rudders/pedals are joystick-like, but buttonless; they have
- * other fancy axes */
- has_joystick_axes_or_buttons = test_bit(BTN_TRIGGER, bitmask_key) ||
- test_bit(BTN_A, bitmask_key) ||
- test_bit(BTN_1, bitmask_key) ||
- test_bit(ABS_RX, bitmask_abs) ||
- test_bit(ABS_RY, bitmask_abs) ||
- test_bit(ABS_RZ, bitmask_abs) ||
- test_bit(ABS_THROTTLE, bitmask_abs) ||
- test_bit(ABS_RUDDER, bitmask_abs) ||
- test_bit(ABS_WHEEL, bitmask_abs) ||
- test_bit(ABS_GAS, bitmask_abs) ||
- test_bit(ABS_BRAKE, bitmask_abs);
+ * other fancy axes. Others have buttons only but no axes. */
+ for (button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (axis = ABS_RX; axis < ABS_PRESSURE && !has_joystick_axes_or_buttons; axis++)
+ has_joystick_axes_or_buttons = test_bit(axis, bitmask_abs);
if (has_abs_coordinates) {
if (stylus_or_pen)
is_touchscreen = true;
else if (has_joystick_axes_or_buttons)
is_joystick = true;
+ } else if (has_joystick_axes_or_buttons) {
+ is_joystick = true;
}
+
if (has_mt_coordinates) {
if (stylus_or_pen)
is_tablet = true;
is_touchscreen = true;
}
- if (has_rel_coordinates && has_mouse_button)
+ if (has_mouse_button &&
+ (has_rel_coordinates ||
+ !has_abs_coordinates)) /* mouse buttons and no axis */
is_mouse = true;
if (is_pointing_stick)
found |= bitmask_key[i];
log_debug("test_key: checking bit block %lu for any keys; found=%i", (unsigned long)i*BITS_PER_LONG, found > 0);
}
- /* If there are no keys in the lower block, check the higher block */
+ /* If there are no keys in the lower block, check the higher blocks */
if (!found) {
- for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) {
- if (test_bit(i, bitmask_key)) {
- log_debug("test_key: Found key %x in high block", i);
- found = 1;
- break;
+ unsigned block;
+ for (block = 0; block < (sizeof(high_key_blocks) / sizeof(struct range)); ++block) {
+ for (i = high_key_blocks[block].start; i < high_key_blocks[block].end; ++i) {
+ if (test_bit(i, bitmask_key)) {
+ log_debug("test_key: Found key %x in high block", i);
+ found = 1;
+ break;
+ }
}
}
}
#include "string-util.h"
#include "udev.h"
-static const struct key *keyboard_lookup_key(const char *str, GPERF_LEN_TYPE len);
+static const struct key_name *keyboard_lookup_key(const char *str, GPERF_LEN_TYPE len);
#include "keyboard-keys-from-name.h"
static int install_force_release(struct udev_device *dev, const unsigned *release, unsigned release_count) {
unsigned key;
} map;
char *endptr;
- const struct key *k;
+ const struct key_name *k;
unsigned keycode_num;
/* translate identifier to key code */
if (r < 0) {
log_error("Unable to parse POINTINGSTICK_SENSITIVITY '%s' for '%s'", value, udev_device_get_devnode(dev));
return;
+ } else if (val_i < 0 || val_i > 255) {
+ log_error("POINTINGSTICK_SENSITIVITY %d outside range [0..255] for '%s' ", val_i, udev_device_get_devnode(dev));
+ return;
}
xsprintf(val_s, "%d", val_i);
unsigned release_count = 0;
_cleanup_close_ int fd = -1;
const char *node;
+ int has_abs = -1;
node = udev_device_get_devnode(dev);
if (!node) {
return EXIT_FAILURE;
}
+ if (has_abs == -1) {
+ unsigned long bits;
+ int rc;
+
+ rc = ioctl(fd, EVIOCGBIT(0, sizeof(bits)), &bits);
+ if (rc < 0) {
+ log_error_errno(errno, "Unable to EVIOCGBIT device \"%s\"", node);
+ return EXIT_FAILURE;
+ }
+
+ has_abs = !!(bits & (1 << EV_ABS));
+ if (!has_abs)
+ log_warning("EVDEV_ABS override set but no EV_ABS present on device \"%s\"", node);
+ }
+
+ if (!has_abs)
+ continue;
+
override_abs(fd, node, evcode, udev_list_entry_get_value(entry));
} else if (streq(key, "POINTINGSTICK_SENSITIVITY"))
set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry));
* — PCI geographical location
* [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
* — USB port number chain
+ * v<slot> - VIO slot number (IBM PowerVM)
+ * a<vendor><model>i<instance> — Platform bus ACPI instance id
*
* All multi-function PCI devices will carry the [f<function>] number in the
* device name, including the function 0 device.
NET_BCMA,
NET_VIRTIO,
NET_CCW,
+ NET_VIO,
+ NET_PLATFORM,
};
struct netnames {
char usb_ports[IFNAMSIZ];
char bcma_core[IFNAMSIZ];
char ccw_busid[IFNAMSIZ];
+ char vio_slot[IFNAMSIZ];
+ char platform_path[IFNAMSIZ];
};
/* skip intermediate virtio devices */
return err;
}
+static int names_vio(struct udev_device *dev, struct netnames *names) {
+ struct udev_device *parent;
+ unsigned busid, slotid, ethid;
+ const char *syspath;
+
+ /* check if our direct parent is a VIO device with no other bus in-between */
+ parent = udev_device_get_parent(dev);
+ if (!parent)
+ return -ENOENT;
+
+ if (!streq_ptr("vio", udev_device_get_subsystem(parent)))
+ return -ENOENT;
+
+ /* The devices' $DEVPATH number is tied to (virtual) hardware (slot id
+ * selected in the HMC), thus this provides a reliable naming (e.g.
+ * "/devices/vio/30000002/net/eth1"); we ignore the bus number, as
+ * there should only ever be one bus, and then remove leading zeros. */
+ syspath = udev_device_get_syspath(dev);
+
+ if (sscanf(syspath, "/sys/devices/vio/%4x%4x/net/eth%u", &busid, &slotid, ðid) != 3)
+ return -EINVAL;
+
+ xsprintf(names->vio_slot, "v%u", slotid);
+ names->type = NET_VIO;
+ return 0;
+}
+
+#define _PLATFORM_TEST "/sys/devices/platform/vvvvPPPP"
+#define _PLATFORM_PATTERN4 "/sys/devices/platform/%4s%4x:%2x/net/eth%u"
+#define _PLATFORM_PATTERN3 "/sys/devices/platform/%3s%4x:%2x/net/eth%u"
+
+static int names_platform(struct udev_device *dev, struct netnames *names, bool test) {
+ struct udev_device *parent;
+ char vendor[5];
+ unsigned model, instance, ethid;
+ const char *syspath, *pattern, *validchars;
+
+ /* check if our direct parent is a platform device with no other bus in-between */
+ parent = udev_device_get_parent(dev);
+ if (!parent)
+ return -ENOENT;
+
+ if (!streq_ptr("platform", udev_device_get_subsystem(parent)))
+ return -ENOENT;
+
+ syspath = udev_device_get_syspath(dev);
+
+ /* syspath is too short, to have a valid ACPI instance */
+ if (strlen(syspath) < sizeof _PLATFORM_TEST)
+ return -EINVAL;
+
+ /* Vendor ID can be either PNP ID (3 chars A-Z) or ACPI ID (4 chars A-Z and numerals) */
+ if (syspath[sizeof _PLATFORM_TEST - 1] == ':') {
+ pattern = _PLATFORM_PATTERN4;
+ validchars = UPPERCASE_LETTERS DIGITS;
+ } else {
+ pattern = _PLATFORM_PATTERN3;
+ validchars = UPPERCASE_LETTERS;
+ }
+
+ /* Platform devices are named after ACPI table match, and instance id
+ * eg. "/sys/devices/platform/HISI00C2:00");
+ * The Vendor (3 or 4 char), followed by hexdecimal model number : instance id.
+ */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ if (sscanf(syspath, pattern, vendor, &model, &instance, ðid) != 4)
+ return -EINVAL;
+#pragma GCC diagnostic pop
+
+ if (!in_charset(vendor, validchars))
+ return -ENOENT;
+
+ ascii_strlower(vendor);
+
+ xsprintf(names->platform_path, "a%s%xi%u", vendor, model, instance);
+ names->type = NET_PLATFORM;
+ return 0;
+}
+
static int names_pci(struct udev_device *dev, struct netnames *names) {
struct udev_device *parent;
goto out;
}
+ /* get ibmveth/ibmvnic slot-based names. */
+ err = names_vio(dev, &names);
+ if (err >= 0 && names.type == NET_VIO) {
+ char str[IFNAMSIZ];
+
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.vio_slot) < (int)sizeof(str))
+ udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+ goto out;
+ }
+
+ /* get ACPI path names for ARM64 platform devices */
+ err = names_platform(dev, &names, test);
+ if (err >= 0 && names.type == NET_PLATFORM) {
+ char str[IFNAMSIZ];
+
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.platform_path) < (int)sizeof(str))
+ udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+ goto out;
+ }
+
/* get PCI based path names, we compose only PCI based paths */
err = names_pci(dev, &names);
if (err < 0)
int err = 0;
memzero(&ctrl_msg_wire, sizeof(struct udev_ctrl_msg_wire));
- strcpy(ctrl_msg_wire.version, "udev-" VERSION);
+ strcpy(ctrl_msg_wire.version, "udev-" PACKAGE_VERSION);
ctrl_msg_wire.magic = UDEV_CTRL_MAGIC;
ctrl_msg_wire.type = type;
event->udev = udev;
udev_list_init(udev, &event->run_list, false);
udev_list_init(udev, &event->seclabel_list, false);
- event->birth_usec = clock_boottime_or_monotonic();
+ event->birth_usec = now(CLOCK_MONOTONIC);
return event;
}
if (timeout_usec > 0) {
usec_t age_usec;
- age_usec = clock_boottime_or_monotonic() - event->birth_usec;
+ age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
if (age_usec >= timeout_usec) {
log_error("timeout '%s'", cmd);
return;
if (timeout_usec > 0) {
usec_t usec, age_usec;
- usec = now(clock_boottime_or_monotonic());
+ usec = now(CLOCK_MONOTONIC);
age_usec = usec - event->birth_usec;
if (age_usec < timeout_usec) {
if (timeout_warn_usec > 0 && timeout_warn_usec < timeout_usec && age_usec < timeout_warn_usec) {
spawn.timeout_warn = timeout_warn_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
usec + spawn.timeout_warn, USEC_PER_SEC,
on_spawn_timeout_warning, &spawn);
if (r < 0)
spawn.timeout = timeout_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
usec + spawn.timeout, USEC_PER_SEC, on_spawn_timeout, &spawn);
if (r < 0)
return r;
return 0;
}
+static void log_unknown_owner(int error, const char *entity, const char *owner) {
+ if (IN_SET(abs(error), ENOENT, ESRCH))
+ log_error("Specified %s '%s' unknown", entity, owner);
+ else
+ log_error_errno(error, "Error resolving %s '%s': %m", entity, owner);
+}
+
static uid_t add_uid(struct udev_rules *rules, const char *owner) {
unsigned int i;
uid_t uid = 0;
}
}
r = get_user_creds(&owner, &uid, NULL, NULL, NULL);
- if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified user '%s' unknown", owner);
- else
- log_error_errno(r, "error resolving user '%s': %m", owner);
- }
+ if (r < 0)
+ log_unknown_owner(r, "user", owner);
/* grow buffer if needed */
if (rules->uids_cur+1 >= rules->uids_max) {
}
}
r = get_group_creds(&group, &gid);
- if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified group '%s' unknown", group);
- else
- log_error_errno(r, "error resolving group '%s': %m", group);
- }
+ if (r < 0)
+ log_unknown_owner(r, "group", group);
/* grow buffer if needed */
if (rules->gids_cur+1 >= rules->gids_max) {
attr++;
pos = strchr(attr, '}');
if (pos == NULL) {
- log_error("missing closing brace for format");
+ log_error("Missing closing brace for format");
return NULL;
}
pos[0] = '\0';
event->owner_set = true;
r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified user '%s' unknown", owner);
- else
- log_error_errno(r, "error resolving user '%s': %m", owner);
-
+ log_unknown_owner(r, "user", owner);
event->uid = 0;
}
log_debug("OWNER %u %s:%u",
event->group_set = true;
r = get_group_creds(&gr, &event->gid);
if (r < 0) {
- if (r == -ENOENT || r == -ESRCH)
- log_error("specified group '%s' unknown", group);
- else
- log_error_errno(r, "error resolving group '%s': %m", group);
-
+ log_unknown_owner(r, "group", group);
event->gid = 0;
}
log_debug("GROUP %u %s:%u",
}
if (mode != (stats.st_mode & 01777)) {
r = chmod(device_node, mode);
- if (r < 0) {
- log_error("failed to chmod '%s' %#o", device_node, mode);
- return -errno;
- } else
+ if (r < 0)
+ return log_error_errno(errno, "Failed to chmod '%s' %#o: %m",
+ device_node, mode);
+ else
log_debug("chmod '%s' %#o", device_node, mode);
}
if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) {
r = chown(device_node, uid, gid);
- if (r < 0) {
- log_error("failed to chown '%s' %u %u ", device_node, uid, gid);
- return -errno;
- } else
+ if (r < 0)
+ return log_error_errno(errno, "Failed to chown '%s' %u %u: %m",
+ device_node, uid, gid);
+ else
log_debug("chown '%s' %u %u", device_node, uid, gid);
}
Name: udev
Description: udev
-Version: @VERSION@
+Version: @PACKAGE_VERSION@
udevdir=@udevlibexecdir@
int64_t size;
struct trie_header_f h = {
.signature = HWDB_SIG,
- .tool_version = htole64(atoi(VERSION)),
+ .tool_version = htole64(atoi(PACKAGE_VERSION)),
.header_size = htole64(sizeof(struct trie_header_f)),
.node_size = htole64(sizeof(struct trie_node_f)),
.child_entry_size = htole64(sizeof(struct trie_child_entry_f)),
export_prefix = optarg;
break;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return 0;
case 'h':
help();
struct timespec ts;
assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
- printf("%-6s[%"PRI_TIME".%06ld] %-8s %s (%s)\n",
+ printf("%-6s[%"PRI_TIME".%06"PRI_NSEC"] %-8s %s (%s)\n",
source,
- ts.tv_sec, ts.tv_nsec/1000,
+ ts.tv_sec, (nsec_t)ts.tv_nsec/1000,
udev_device_get_action(device),
udev_device_get_devpath(device),
udev_device_get_subsystem(device));
{}
};
- log_debug("version %s", VERSION);
+ log_debug("version %s", PACKAGE_VERSION);
while ((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
switch (c) {
#include "selinux-util.h"
#include "string-util.h"
#include "udev.h"
+#include "udev-util.h"
static int adm_version(struct udev *udev, int argc, char *argv[]) {
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return 0;
}
unsigned int i;
int rc = 1, c;
- udev = udev_new();
- if (udev == NULL)
- goto out;
-
+ udev_parse_config();
log_parse_environment();
log_open();
+
mac_selinux_init();
+ udev = udev_new();
+ if (udev == NULL)
+ goto out;
+
while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
switch (c) {
e = worker->manager->event;
- assert_se(sd_event_now(e, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(e, CLOCK_MONOTONIC, &usec) >= 0);
- (void) sd_event_add_time(e, &event->timeout_warning, clock_boottime_or_monotonic(),
+ (void) sd_event_add_time(e, &event->timeout_warning, CLOCK_MONOTONIC,
usec + arg_event_timeout_warn_usec, USEC_PER_SEC, on_event_timeout_warning, event);
- (void) sd_event_add_time(e, &event->timeout, clock_boottime_or_monotonic(),
+ (void) sd_event_add_time(e, &event->timeout, CLOCK_MONOTONIC,
usec + arg_event_timeout_usec, USEC_PER_SEC, on_event_timeout, event);
}
event_queue_cleanup(manager, EVENT_QUEUED);
manager_kill_workers(manager);
- assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0);
- r = sd_event_add_time(manager->event, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(manager->event, NULL, CLOCK_MONOTONIC,
usec + 30 * USEC_PER_SEC, USEC_PER_SEC, on_exit_timeout, manager);
if (r < 0)
return;
manager->exit || manager->stop_exec_queue)
return;
- assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0);
/* check for changed config, every 3 seconds at most */
if (manager->last_usec == 0 ||
(usec - manager->last_usec) > 3 * USEC_PER_SEC) {
help();
return 0;
case 'V':
- printf("%s\n", VERSION);
+ printf("%s\n", PACKAGE_VERSION);
return 0;
case '?':
return -EINVAL;
int r;
log_set_target(LOG_TARGET_AUTO);
+ udev_parse_config();
log_parse_environment();
log_open();
if (arg_daemonize) {
pid_t pid;
- log_info("starting version " VERSION);
+ log_info("starting version " PACKAGE_VERSION);
/* connect /dev/null to stdin, stdout, stderr */
if (log_get_max_level() < LOG_DEBUG) {
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "fd-util.h"
-#include "fileio.h"
-#include "io-util.h"
+#include "alloc-util.h"
+#include "fileio-label.h"
#include "selinux-util.h"
#include "util.h"
"# was updated. See man:systemd-update-done.service(8).\n"
static int apply_timestamp(const char *path, struct timespec *ts) {
- struct timespec twice[2] = {
- *ts,
- *ts
- };
- _cleanup_fclose_ FILE *f = NULL;
- int fd = -1;
+ _cleanup_free_ char *message = NULL;
int r;
- assert(path);
- assert(ts);
-
/*
* We store the timestamp both as mtime of the file and in the file itself,
* to support filesystems which cannot store nanosecond-precision timestamps.
- * Hence, don't bother updating the file, let's just rewrite it.
*/
- r = mac_selinux_create_file_prepare(path, S_IFREG);
- if (r < 0)
- return log_error_errno(r, "Failed to set SELinux context for %s: %m", path);
-
- fd = open(path, O_CREAT|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
- mac_selinux_create_file_clear();
-
- if (fd < 0) {
- if (errno == EROFS)
- return log_debug("Can't create timestamp file %s, file system is read-only.", path);
-
- return log_error_errno(errno, "Failed to create/open timestamp file %s: %m", path);
- }
+ if (asprintf(&message,
+ MESSAGE
+ "TIMESTAMP_NSEC=" NSEC_FMT "\n",
+ timespec_load_nsec(ts)) < 0)
+ return log_oom();
- f = fdopen(fd, "we");
- if (!f) {
- safe_close(fd);
- return log_error_errno(errno, "Failed to fdopen() timestamp file %s: %m", path);
- }
-
- (void) fprintf(f,
- MESSAGE
- "TIMESTAMP_NSEC=" NSEC_FMT "\n",
- timespec_load_nsec(ts));
-
- r = fflush_and_check(f);
+ r = write_string_file_atomic_label_ts(path, message, ts);
+ if (r == -EROFS)
+ return log_debug("Cannot create \"%s\", file system is read-only.", path);
if (r < 0)
- return log_error_errno(r, "Failed to write timestamp file: %m");
-
- if (futimens(fd, twice) < 0)
- return log_error_errno(errno, "Failed to update timestamp on %s: %m", path);
-
+ return log_error_errno(r, "Failed to write \"%s\": %m", path);
return 0;
}
--- /dev/null
+if conf.get('ENABLE_VCONSOLE', false)
+ vconsole_rules = configure_file(
+ input : '90-vconsole.rules.in',
+ output : '90-vconsole.rules',
+ configuration : substs)
+ install_data(vconsole_rules,
+ install_dir : udevrulesdir)
+endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
+#include <sysexits.h>
#include <termios.h>
#include <unistd.h>
#include "signal-util.h"
#include "stdio-util.h"
#include "string-util.h"
+#include "strv.h"
#include "terminal-util.h"
#include "util.h"
#include "virt.h"
-static bool is_vconsole(int fd) {
+static int verify_vc_device(int fd) {
unsigned char data[1];
+ int r;
data[0] = TIOCL_GETFGCONSOLE;
- return ioctl(fd, TIOCLINUX, data) >= 0;
+ r = ioctl(fd, TIOCLINUX, data);
+ return r < 0 ? -errno : r;
}
-static bool is_allocated(unsigned int idx) {
- char vcname[strlen("/dev/vcs") + DECIMAL_STR_MAX(int)];
+static int verify_vc_allocation(unsigned idx) {
+ char vcname[sizeof("/dev/vcs") + DECIMAL_STR_MAX(unsigned) - 2];
+ int r;
- xsprintf(vcname, "/dev/vcs%i", idx);
- return access(vcname, F_OK) == 0;
+ xsprintf(vcname, "/dev/vcs%u", idx);
+ r = access(vcname, F_OK);
+ return r < 0 ? -errno : r;
}
-static bool is_allocated_byfd(int fd) {
+static int verify_vc_allocation_byfd(int fd) {
struct vt_stat vcs = {};
+ int r;
- if (ioctl(fd, VT_GETSTATE, &vcs) < 0) {
- log_warning_errno(errno, "VT_GETSTATE failed: %m");
- return false;
- }
- return is_allocated(vcs.v_active);
+ r = ioctl(fd, VT_GETSTATE, &vcs);
+ return r < 0 ? -errno : verify_vc_allocation(vcs.v_active);
}
-static bool is_settable(int fd) {
+static int verify_vc_kbmode(int fd) {
int r, curr_mode;
r = ioctl(fd, KDGKBMODE, &curr_mode);
*
* http://lists.freedesktop.org/archives/systemd-devel/2013-February/008573.html
*/
- return r == 0 && IN_SET(curr_mode, K_XLATE, K_UNICODE);
+ if (r < 0)
+ return -errno;
+
+ return IN_SET(curr_mode, K_XLATE, K_UNICODE) ? 0 : -EBUSY;
}
static int toggle_utf8(const char *name, int fd, bool utf8) {
r = tcgetattr(fd, &tc);
if (r >= 0) {
- if (utf8)
- tc.c_iflag |= IUTF8;
- else
- tc.c_iflag &= ~IUTF8;
+ SET_FLAG(tc.c_iflag, IUTF8, utf8);
r = tcsetattr(fd, TCSANOW, &tc);
}
if (r < 0)
}
static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) {
+ _cleanup_free_ char *cmd = NULL;
const char *args[8];
- int i = 0;
+ unsigned i = 0;
pid_t pid;
/* An empty map means kernel map */
args[i++] = map_toggle;
args[i++] = NULL;
+ log_debug("Executing \"%s\"...",
+ strnull((cmd = strv_join((char**) args, " "))));
+
pid = fork();
if (pid < 0)
return log_error_errno(errno, "Failed to fork: %m");
}
static int font_load_and_wait(const char *vc, const char *font, const char *map, const char *unimap) {
+ _cleanup_free_ char *cmd = NULL;
const char *args[9];
- int i = 0;
+ unsigned i = 0;
pid_t pid;
/* Any part can be set independently */
args[i++] = font;
args[i++] = NULL;
+ log_debug("Executing \"%s\"...",
+ strnull((cmd = strv_join((char**) args, " "))));
+
pid = fork();
if (pid < 0)
return log_error_errno(errno, "Failed to fork: %m");
}
/*
- * A newly allocated VT uses the font from the active VT. Here
+ * A newly allocated VT uses the font from the source VT. Here
* we update all possibly already allocated VTs with the configured
* font. It also allows to restart systemd-vconsole-setup.service,
* to apply a new font to all VTs.
* We also setup per-console utf8 related stuff: kbdmode, term
* processing, stty iutf8.
*/
-static void setup_remaining_vcs(int fd, bool utf8) {
+static void setup_remaining_vcs(int src_fd, unsigned src_idx, bool utf8) {
struct console_font_op cfo = {
.op = KD_FONT_OP_GET,
.width = UINT_MAX, .height = UINT_MAX,
.charcount = UINT_MAX,
};
- struct vt_stat vcs = {};
struct unimapinit adv = {};
struct unimapdesc unimapd;
_cleanup_free_ struct unipair* unipairs = NULL;
_cleanup_free_ void *fontbuf = NULL;
- int i, r;
+ unsigned i;
+ int r;
unipairs = new(struct unipair, USHRT_MAX);
if (!unipairs) {
return;
}
- /* get active, and 16 bit mask of used VT numbers */
- r = ioctl(fd, VT_GETSTATE, &vcs);
- if (r < 0) {
- log_warning_errno(errno, "VT_GETSTATE failed, ignoring remaining consoles: %m");
- return;
- }
-
/* get metadata of the current font (width, height, count) */
- r = ioctl(fd, KDFONTOP, &cfo);
+ r = ioctl(src_fd, KDFONTOP, &cfo);
if (r < 0)
log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to get the font metadata: %m");
else {
log_oom();
return;
}
- /* get fonts from source console */
+ /* get fonts from the source console */
cfo.data = fontbuf;
- r = ioctl(fd, KDFONTOP, &cfo);
+ r = ioctl(src_fd, KDFONTOP, &cfo);
if (r < 0)
log_warning_errno(errno, "KD_FONT_OP_GET failed while trying to read the font data: %m");
else {
unimapd.entries = unipairs;
unimapd.entry_ct = USHRT_MAX;
- r = ioctl(fd, GIO_UNIMAP, &unimapd);
+ r = ioctl(src_fd, GIO_UNIMAP, &unimapd);
if (r < 0)
log_warning_errno(errno, "GIO_UNIMAP failed while trying to read unicode mappings: %m");
else
log_warning("Fonts will not be copied to remaining consoles");
for (i = 1; i <= 63; i++) {
- char ttyname[strlen("/dev/tty") + DECIMAL_STR_MAX(int)];
+ char ttyname[sizeof("/dev/tty63")];
_cleanup_close_ int fd_d = -1;
- if (i == vcs.v_active || !is_allocated(i))
+ if (i == src_idx || verify_vc_allocation(i) < 0)
continue;
/* try to open terminal */
- xsprintf(ttyname, "/dev/tty%i", i);
- fd_d = open_terminal(ttyname, O_RDWR|O_CLOEXEC);
+ xsprintf(ttyname, "/dev/tty%u", i);
+ fd_d = open_terminal(ttyname, O_RDWR|O_CLOEXEC|O_NOCTTY);
if (fd_d < 0) {
- log_warning_errno(fd_d, "Unable to open tty%i, fonts will not be copied: %m", i);
+ log_warning_errno(fd_d, "Unable to open tty%u, fonts will not be copied: %m", i);
continue;
}
- if (!is_settable(fd_d))
+ if (verify_vc_kbmode(fd_d) < 0)
continue;
toggle_utf8(ttyname, fd_d, utf8);
r = ioctl(fd_d, KDFONTOP, &cfo);
if (r < 0) {
- log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%i: %m", i);
+ log_warning_errno(errno, "KD_FONT_OP_SET failed, fonts will not be copied to tty%u: %m", i);
continue;
}
- /* copy unicode translation table */
- /* unimapd is a ushort count and a pointer to an
- array of struct unipair { ushort, ushort } */
+ /*
+ * copy unicode translation table
+ * unimapd is a ushort count and a pointer to an
+ * array of struct unipair { ushort, ushort }
+ */
r = ioctl(fd_d, PIO_UNIMAPCLR, &adv);
if (r < 0) {
- log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%i: %m", i);
+ log_warning_errno(errno, "PIO_UNIMAPCLR failed, unimaps might be incorrect for tty%u: %m", i);
continue;
}
r = ioctl(fd_d, PIO_UNIMAP, &unimapd);
if (r < 0) {
- log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%i: %m", i);
+ log_warning_errno(errno, "PIO_UNIMAP failed, unimaps might be incorrect for tty%u: %m", i);
continue;
}
}
}
+static int find_source_vc(char **ret_path, unsigned *ret_idx) {
+ _cleanup_free_ char *path = NULL;
+ unsigned i;
+ int ret_fd, r, err = 0;
+
+ path = new(char, sizeof("/dev/tty63"));
+ if (path == NULL)
+ return log_oom();
+
+ for (i = 1; i <= 63; i++) {
+ _cleanup_close_ int fd = -1;
+
+ r = verify_vc_allocation(i);
+ if (r < 0) {
+ if (!err)
+ err = -r;
+ continue;
+ }
+
+ sprintf(path, "/dev/tty%u", i);
+ fd = open_terminal(path, O_RDWR|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0) {
+ if (!err)
+ err = -fd;
+ continue;
+ }
+ r = verify_vc_kbmode(fd);
+ if (r < 0) {
+ if (!err)
+ err = -r;
+ continue;
+ }
+
+ /* all checks passed, return this one as a source console */
+ *ret_idx = i;
+ *ret_path = path;
+ path = NULL;
+ ret_fd = fd;
+ fd = -1;
+ return ret_fd;
+ }
+
+ return log_error_errno(err, "No usable source console found: %m");
+}
+
+static int verify_source_vc(char **ret_path, const char *src_vc) {
+ char *path;
+ _cleanup_close_ int fd = -1;
+ int ret_fd, r;
+
+ fd = open_terminal(src_vc, O_RDWR|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open %s: %m", src_vc);
+
+ r = verify_vc_device(fd);
+ if (r < 0)
+ return log_error_errno(r, "Device %s is not a virtual console: %m", src_vc);
+
+ r = verify_vc_allocation_byfd(fd);
+ if (r < 0)
+ return log_error_errno(r, "Virtual console %s is not allocated: %m", src_vc);
+
+ r = verify_vc_kbmode(fd);
+ if (r < 0)
+ return log_error_errno(r, "Virtual console %s is not in K_XLATE or K_UNICODE: %m", src_vc);
+
+ path = strdup(src_vc);
+ if (path == NULL)
+ return log_oom();
+
+ *ret_path = path;
+ ret_fd = fd;
+ fd = -1;
+ return ret_fd;
+}
+
int main(int argc, char **argv) {
- const char *vc;
_cleanup_free_ char
+ *vc = NULL,
*vc_keymap = NULL, *vc_keymap_toggle = NULL,
*vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL;
_cleanup_close_ int fd = -1;
- bool utf8, font_copy = false, font_ok, keyboard_ok;
- int r = EXIT_FAILURE;
+ bool utf8, keyboard_ok;
+ unsigned idx = 0;
+ int r;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
umask(0022);
if (argv[1])
- vc = argv[1];
- else {
- vc = "/dev/tty0";
- font_copy = true;
- }
-
- fd = open_terminal(vc, O_RDWR|O_CLOEXEC);
- if (fd < 0) {
- log_error_errno(fd, "Failed to open %s: %m", vc);
- return EXIT_FAILURE;
- }
+ fd = verify_source_vc(&vc, argv[1]);
+ else
+ fd = find_source_vc(&vc, &idx);
- if (!is_vconsole(fd)) {
- log_error("Device %s is not a virtual console.", vc);
+ if (fd < 0)
return EXIT_FAILURE;
- }
-
- if (!is_allocated_byfd(fd)) {
- log_error("Virtual console %s is not allocated.", vc);
- return EXIT_FAILURE;
- }
-
- if (!is_settable(fd)) {
- log_error("Virtual console %s is not in K_XLATE or K_UNICODE.", vc);
- return EXIT_FAILURE;
- }
utf8 = is_locale_utf8();
"FONT_MAP", &vc_font_map,
"FONT_UNIMAP", &vc_font_unimap,
NULL);
-
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read /etc/vconsole.conf: %m");
"vconsole.font.map", &vc_font_map,
"vconsole.font.unimap", &vc_font_unimap,
NULL);
-
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read /proc/cmdline: %m");
}
toggle_utf8_sysfs(utf8);
toggle_utf8(vc, fd, utf8);
- font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) == 0;
+
+ r = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap);
keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) == 0;
- if (font_copy) {
- if (font_ok)
- setup_remaining_vcs(fd, utf8);
+ if (idx > 0) {
+ if (r == 0)
+ setup_remaining_vcs(fd, idx, utf8);
+ else if (r == EX_OSERR)
+ /* setfont returns EX_OSERR when ioctl(KDFONTOP/PIO_FONTX/PIO_FONTX) fails.
+ * This might mean various things, but in particular lack of a graphical
+ * console. Let's be generous and not treat this as an error. */
+ log_notice("Setting fonts failed with a \"system error\", ignoring.");
else
log_warning("Setting source virtual console failed, ignoring remaining ones");
}
- return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
+ return IN_SET(r, 0, EX_OSERR) && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
--- /dev/null
+install_data(
+ '50-default.conf',
+ install_dir : sysctldir)
+
+in_files = []
+
+if conf.get('ENABLE_COREDUMP', false)
+ in_files += ['50-coredump.conf']
+endif
+
+foreach file : in_files
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : sysctldir)
+endforeach
+
+meson.add_install_script('sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'sysctl.d')))
enable systemd-timesyncd.service
enable systemd-networkd.service
enable systemd-resolved.service
-enable systemd-networkd-wait-online.service
disable console-getty.service
disable debug-shell.service
g disk - - -
g input - - -
g lp - - -
+g kvm - - -
g tape - - -
g video - - -
--- /dev/null
+in_files = ['basic.conf']
+
+enable_sysusers = conf.get('ENABLE_SYSUSERS', false)
+
+foreach file : in_files
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ if enable_sysusers
+ install_data(gen,
+ install_dir : sysusersdir)
+ endif
+endforeach
+
+m4_files = ['systemd.conf']
+
+if conf.get('ENABLE_REMOTE', false) and conf.get('HAVE_MICROHTTPD', false)
+ m4_files += ['systemd-remote.conf']
+endif
+
+foreach file : m4_files
+ custom_target(
+ 'sysusers.d_' + file,
+ input : file + '.m4',
+ output: file,
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : enable_sysusers,
+ install_dir : sysusersdir)
+endforeach
To run the extended testsuite do the following:
-$ make all
+$ make all # Avoid the "sudo make" below building anything as root
$ cd test
$ sudo make clean check
...
systemctl start test.socket
systemctl is-active test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
-echo A | nc -U /run/test.socket
+echo A | nc -w1 -U /run/test.socket
mv $U ${U}.disabled
systemctl daemon-reload
systemctl is-active test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
-echo B | nc -U /run/test.socket && exit 1
+echo B | nc -w1 -U /run/test.socket && exit 1
mv ${U}.disabled $U
systemctl daemon-reload
systemctl is-active test.socket
-echo C | nc -U /run/test.socket && exit 1
+echo C | nc -w1 -U /run/test.socket && exit 1
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
systemctl restart test.socket
systemctl is-active test.socket
-echo D | nc -U /run/test.socket
+echo D | nc -w1 -U /run/test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
-#!/usr/bin/python3
+#!/usr/bin/env python3
-OUTFILE_HEADER = """#!/usr/bin/python3
+OUTFILE_HEADER = """#!/usr/bin/env python3
#
# create-sys-script.py
#
--- /dev/null
+test_data_files = '''
+ a.service
+ basic.target
+ b.service
+ c.service
+ daughter.service
+ d.service
+ end.service
+ e.service
+ f.service
+ grandchild.service
+ g.service
+ hello-after-sleep.target
+ hello.service
+ h.service
+ parent-deep.slice
+ parent.slice
+ sched_idle_bad.service
+ sched_idle_ok.service
+ sched_rr_bad.service
+ sched_rr_change.service
+ sched_rr_ok.service
+ shutdown.target
+ sleep.service
+ sockets.target
+ son.service
+ sysinit.target
+ testsuite.target
+ timers.target
+ unstoppable.service
+ test-path/paths.target
+ test-path/basic.target
+ test-path/sysinit.target
+ test-path/path-changed.service
+ test-path/path-directorynotempty.service
+ test-path/path-existsglob.service
+ test-path/path-exists.service
+ test-path/path-makedirectory.service
+ test-path/path-modified.service
+ test-path/path-mycustomunit.service
+ test-path/path-service.service
+ test-path/path-changed.path
+ test-path/path-directorynotempty.path
+ test-path/path-existsglob.path
+ test-path/path-exists.path
+ test-path/path-makedirectory.path
+ test-path/path-modified.path
+ test-path/path-unit.path
+ test-execute/exec-environment-empty.service
+ test-execute/exec-environment-multiple.service
+ test-execute/exec-environment.service
+ test-execute/exec-passenvironment-absent.service
+ test-execute/exec-passenvironment-empty.service
+ test-execute/exec-passenvironment-repeated.service
+ test-execute/exec-passenvironment.service
+ test-execute/exec-group.service
+ test-execute/exec-group-nfsnobody.service
+ test-execute/exec-supplementarygroups.service
+ test-execute/exec-supplementarygroups-single-group.service
+ test-execute/exec-supplementarygroups-single-group-user.service
+ test-execute/exec-supplementarygroups-multiple-groups-default-group-user.service
+ test-execute/exec-supplementarygroups-multiple-groups-withgid.service
+ test-execute/exec-supplementarygroups-multiple-groups-withuid.service
+ test-execute/exec-dynamicuser-fixeduser.service
+ test-execute/exec-dynamicuser-fixeduser-one-supplementarygroup.service
+ test-execute/exec-dynamicuser-supplementarygroups.service
+ test-execute/exec-ignoresigpipe-no.service
+ test-execute/exec-ignoresigpipe-yes.service
+ test-execute/exec-personality-x86-64.service
+ test-execute/exec-personality-x86.service
+ test-execute/exec-personality-s390.service
+ test-execute/exec-personality-ppc64.service
+ test-execute/exec-personality-ppc64le.service
+ test-execute/exec-personality-aarch64.service
+ test-execute/exec-privatedevices-no.service
+ test-execute/exec-privatedevices-yes.service
+ test-execute/exec-privatedevices-no-capability-mknod.service
+ test-execute/exec-privatedevices-yes-capability-mknod.service
+ test-execute/exec-protectkernelmodules-no-capabilities.service
+ test-execute/exec-protectkernelmodules-yes-capabilities.service
+ test-execute/exec-protectkernelmodules-yes-mount-propagation.service
+ test-execute/exec-privatetmp-no.service
+ test-execute/exec-privatetmp-yes.service
+ test-execute/exec-readonlypaths.service
+ test-execute/exec-readonlypaths-mount-propagation.service
+ test-execute/exec-readwritepaths-mount-propagation.service
+ test-execute/exec-inaccessiblepaths-mount-propagation.service
+ test-execute/exec-inaccessiblepaths-proc.service
+ test-execute/exec-spec-interpolation.service
+ test-execute/exec-systemcallerrornumber.service
+ test-execute/exec-systemcallfilter-failing2.service
+ test-execute/exec-systemcallfilter-failing.service
+ test-execute/exec-systemcallfilter-not-failing2.service
+ test-execute/exec-systemcallfilter-not-failing.service
+ test-execute/exec-systemcallfilter-system-user.service
+ test-execute/exec-systemcallfilter-system-user-nfsnobody.service
+ test-execute/exec-user.service
+ test-execute/exec-user-nfsnobody.service
+ test-execute/exec-workingdirectory.service
+ test-execute/exec-umask-0177.service
+ test-execute/exec-umask-default.service
+ test-execute/exec-privatenetwork-yes.service
+ test-execute/exec-environmentfile.service
+ test-execute/exec-oomscoreadjust-positive.service
+ test-execute/exec-oomscoreadjust-negative.service
+ test-execute/exec-ioschedulingclass-best-effort.service
+ test-execute/exec-ioschedulingclass-idle.service
+ test-execute/exec-ioschedulingclass-none.service
+ test-execute/exec-ioschedulingclass-realtime.service
+ test-execute/exec-capabilityboundingset-invert.service
+ test-execute/exec-capabilityboundingset-merge.service
+ test-execute/exec-capabilityboundingset-reset.service
+ test-execute/exec-capabilityboundingset-simple.service
+ test-execute/exec-capabilityambientset.service
+ test-execute/exec-capabilityambientset-nfsnobody.service
+ test-execute/exec-capabilityambientset-merge.service
+ test-execute/exec-capabilityambientset-merge-nfsnobody.service
+ test-execute/exec-runtimedirectory.service
+ test-execute/exec-runtimedirectory-mode.service
+ test-execute/exec-runtimedirectory-owner.service
+ test-execute/exec-runtimedirectory-owner-nfsnobody.service
+ test-execute/exec-restrict-namespaces-no.service
+ test-execute/exec-restrict-namespaces-yes.service
+ test-execute/exec-restrict-namespaces-mnt.service
+ test-execute/exec-restrict-namespaces-mnt-blacklist.service
+ test-execute/exec-read-only-path-succeed.service
+ test-execute/exec-privatedevices-yes-capability-sys-rawio.service
+ test-execute/exec-privatedevices-no-capability-sys-rawio.service
+ bus-policy/hello.conf
+ bus-policy/methods.conf
+ bus-policy/ownerships.conf
+ bus-policy/signals.conf
+ bus-policy/check-own-rules.conf
+ bus-policy/many-rules.conf
+ bus-policy/test.conf
+ hwdb/10-bad.hwdb
+ journal-data/journal-1.txt
+ journal-data/journal-2.txt
+'''.split()
+
+if conf.get('ENABLE_RESOLVED', false)
+ test_data_files += '''
+ test-resolve/_openpgpkey.fedoraproject.org.pkts
+ test-resolve/fedoraproject.org.pkts
+ test-resolve/gandi.net.pkts
+ test-resolve/google.com.pkts
+ test-resolve/root.pkts
+ test-resolve/sw1a1aa-sw1a2aa-sw1a2ab-sw1a2ac.find.me.uk.pkts
+ test-resolve/teamits.com.pkts
+ test-resolve/zbyszek@fedoraproject.org.pkts
+ test-resolve/_443._tcp.fedoraproject.org.pkts
+ test-resolve/kyhwana.org.pkts
+ test-resolve/fake-caa.pkts
+ '''.split()
+endif
+
+if install_tests
+ foreach file : test_data_files
+ subdir = file.split('/')[0]
+ if subdir == file
+ subdir = ''
+ endif
+
+ install_data(file,
+ install_dir : testsdir + '/testdata/' + subdir)
+ endforeach
+endif
dropin_path = os.path.join(dropin_dir, "%s.conf" % dropin_name)
os.makedirs(dropin_dir, exist_ok=True)
+ self.addCleanup(os.rmdir, dropin_dir)
with open(dropin_path, 'w') as dropin:
dropin.write(contents)
self.addCleanup(os.remove, dropin_path)
+ def read_attr(self, link, attribute):
+ """Read a link attributed from the sysfs."""
+ # Note we we don't want to check if interface `link' is managed, we
+ # want to evaluate link variable and pass the value of the link to
+ # assert_link_states e.g. eth0=managed.
+ self.assert_link_states(**{link:'managed'})
+ with open(os.path.join('/sys/class/net', link, attribute)) as f:
+ return f.readline().strip()
+
def assert_link_states(self, **kwargs):
"""Match networkctl link states to the given ones.
self.fail("Missing links in status output: %s" % interfaces)
+class BridgeTest(NetworkdTestingUtilities, unittest.TestCase):
+ """Provide common methods for testing networkd against servers."""
+
+ def setUp(self):
+ self.write_network('port1.netdev', '''\
+[NetDev]
+Name=port1
+Kind=dummy
+MACAddress=12:34:56:78:9a:bc''')
+ self.write_network('port2.netdev', '''\
+[NetDev]
+Name=port2
+Kind=dummy
+MACAddress=12:34:56:78:9a:bd''')
+ self.write_network('mybridge.netdev', '''\
+[NetDev]
+Name=mybridge
+Kind=bridge''')
+ self.write_network('port1.network', '''\
+[Match]
+Name=port1
+[Network]
+Bridge=mybridge''')
+ self.write_network('port2.network', '''\
+[Match]
+Name=port2
+[Network]
+Bridge=mybridge''')
+ self.write_network('mybridge.network', '''\
+[Match]
+Name=mybridge
+[Network]
+DNS=192.168.250.1
+Address=192.168.250.33/24
+Gateway=192.168.250.1''')
+ subprocess.check_call(['systemctl', 'start', 'systemd-networkd'])
+
+ def tearDown(self):
+ subprocess.check_call(['systemctl', 'stop', 'systemd-networkd'])
+ subprocess.check_call(['ip', 'link', 'del', 'mybridge'])
+ subprocess.check_call(['ip', 'link', 'del', 'port1'])
+ subprocess.check_call(['ip', 'link', 'del', 'port2'])
+
+ def test_bridge_init(self):
+ self.assert_link_states(
+ port1='managed',
+ port2='managed',
+ mybridge='managed')
+
+ def test_bridge_port_priority(self):
+ self.assertEqual(self.read_attr('port1', 'brport/priority'), '32')
+ self.write_network_dropin('port1.network', 'priority', '''\
+[Bridge]
+Priority=28
+''')
+ subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
+ self.assertEqual(self.read_attr('port1', 'brport/priority'), '28')
+
+ def test_bridge_port_priority_set_zero(self):
+ """It should be possible to set the bridge port priority to 0"""
+ self.assertEqual(self.read_attr('port2', 'brport/priority'), '32')
+ self.write_network_dropin('port2.network', 'priority', '''\
+[Bridge]
+Priority=0
+''')
+ subprocess.check_call(['systemctl', 'restart', 'systemd-networkd'])
+ self.assertEqual(self.read_attr('port2', 'brport/priority'), '0')
+
class ClientTestBase(NetworkdTestingUtilities):
"""Provide common methods for testing networkd against servers."""
-#!/usr/bin/python3
+#!/usr/bin/env python3
# Simple udev rules syntax checker
#
# (C) 2010 Canonical Ltd.
-#!/usr/bin/python3
+#!/usr/bin/env python3
#
# sys-script.py
#
-#!/usr/bin/python3
+#!/usr/bin/env python3
#
# systemd-sysv-generator integration test
#
#!/bin/bash -e
+out="$1"
+systemd_efi="$2"
+boot_stub="$3"
+splash_bmp="$4"
+if [ -z "$out" -o -z "$systemd_efi" -o -z "$boot_stub" -o -z "$splash_bmp" ]; then
+ exit 1
+fi
+
# create GPT table with EFI System Partition
-rm -f test-efi-disk.img
-dd if=/dev/null of=test-efi-disk.img bs=1M seek=512 count=1
-parted --script test-efi-disk.img "mklabel gpt" "mkpart ESP fat32 1MiB 511MiB" "set 1 boot on"
+rm -f "$out"
+dd if=/dev/null of="$out" bs=1M seek=512 count=1 status=none
+parted --script "$out" "mklabel gpt" "mkpart ESP fat32 1MiB 511MiB" "set 1 boot on"
# create FAT32 file system
-LOOP=$(losetup --show -f -P test-efi-disk.img)
+LOOP=$(losetup --show -f -P "$out")
mkfs.vfat -F32 ${LOOP}p1
mkdir -p mnt
mount ${LOOP}p1 mnt
mkdir -p mnt/EFI/{BOOT,systemd}
-cp systemd-bootx64.efi mnt/EFI/BOOT/BOOTX64.efi
+cp "$systemd_efi" mnt/EFI/BOOT/BOOTX64.efi
[ -e /boot/shellx64.efi ] && cp /boot/shellx64.efi mnt/
mkdir mnt/EFI/Linux
-echo -n "foo=yes bar=no root=/dev/fakeroot debug rd.break=initqueue" > mnt/cmdline.txt
+echo -n "foo=yes bar=no root=/dev/fakeroot debug rd.break=initqueue" >mnt/cmdline.txt
objcopy \
- --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
- --add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \
- --add-section .splash=test/splash.bmp --change-section-vma .splash=0x40000 \
- --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x2000000 \
- --add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \
- linuxx64.efi.stub mnt/EFI/Linux/linux-test.efi
+ --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
+ --add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \
+ --add-section .splash="$splash_bmp" --change-section-vma .splash=0x40000 \
+ --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x2000000 \
+ --add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \
+ "$boot_stub" mnt/EFI/Linux/linux-test.efi
# install entries
mkdir -p mnt/loader/entries
--- /dev/null
+#!/usr/bin/env python3
+
+#
+# Copyright 2017 Michal Sekletar <msekleta@redhat.com>
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# systemd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with systemd; If not, see <http://www.gnu.org/licenses/>.
+
+# ATTENTION: This uses the *installed* systemd, not the one from the built
+# source tree.
+
+import unittest
+import time
+import os
+import tempfile
+import subprocess
+
+from enum import Enum
+
+class UnitFileChange(Enum):
+ NO_CHANGE = 0
+ LINES_SWAPPED = 1
+ COMMAND_ADDED_BEFORE = 2
+ COMMAND_ADDED_AFTER = 3
+ COMMAND_INTERLEAVED = 4
+ REMOVAL = 5
+
+class ExecutionResumeTest(unittest.TestCase):
+ def setUp(self):
+ self.unit = 'test-issue-518.service'
+ self.unitfile_path = '/run/systemd/system/{0}'.format(self.unit)
+ self.output_file = tempfile.mktemp()
+ self.unit_files = {}
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.NO_CHANGE] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ ExecStart=/bin/sleep 2
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.LINES_SWAPPED] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.COMMAND_ADDED_BEFORE] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.COMMAND_ADDED_AFTER] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo baz >> {0}"
+ ExecStart=/bin/sleep 2
+ ExecStart=/bin/bash -c "echo foo >> {0}"
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.COMMAND_INTERLEAVED] = unit_file_content
+
+ unit_file_content = '''
+ [Service]
+ Type=oneshot
+ ExecStart=/bin/bash -c "echo bar >> {0}"
+ ExecStart=/bin/bash -c "echo baz >> {0}"
+ '''.format(self.output_file)
+ self.unit_files[UnitFileChange.REMOVAL] = unit_file_content
+
+ def reload(self):
+ subprocess.check_call(['systemctl', 'daemon-reload'])
+
+ def write_unit_file(self, unit_file_change):
+ if not isinstance(unit_file_change, UnitFileChange):
+ raise ValueError('Unknown unit file change')
+
+ content = self.unit_files[unit_file_change]
+
+ with open(self.unitfile_path, 'w') as f:
+ f.write(content)
+
+ self.reload()
+
+ def check_output(self, expected_output):
+ try:
+ with open(self.output_file, 'r') as log:
+ output = log.read()
+ except IOError:
+ self.fail()
+
+ self.assertEqual(output, expected_output)
+
+ def setup_unit(self):
+ self.write_unit_file(UnitFileChange.NO_CHANGE)
+ subprocess.check_call(['systemctl', '--job-mode=replace', '--no-block', 'start', self.unit])
+
+ def test_no_change(self):
+ expected_output = 'foo\n'
+
+ self.setup_unit()
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_swapped(self):
+ expected_output = ''
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.LINES_SWAPPED)
+ self.reload()
+ time.sleep(4)
+
+ self.assertTrue(not os.path.exists(self.output_file))
+
+ def test_added_before(self):
+ expected_output = 'foo\n'
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.COMMAND_ADDED_BEFORE)
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_added_after(self):
+ expected_output = 'foo\nbar\n'
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.COMMAND_ADDED_AFTER)
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_interleaved(self):
+ expected_output = 'foo\nbar\n'
+
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.COMMAND_INTERLEAVED)
+ self.reload()
+ time.sleep(4)
+
+ self.check_output(expected_output)
+
+ def test_removal(self):
+ self.setup_unit()
+ self.write_unit_file(UnitFileChange.REMOVAL)
+ self.reload()
+ time.sleep(4)
+
+ self.assertTrue(not os.path.exists(self.output_file))
+
+ def tearDown(self):
+ for f in [self.output_file, self.unitfile_path]:
+ try:
+ os.remove(f)
+ except OSError:
+ # ignore error if log file doesn't exist
+ pass
+
+ self.reload()
+
+if __name__ == '__main__':
+ unittest.main()
[Service]
InaccessiblePaths=-/i-dont-exist
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
--- /dev/null
+[Unit]
+Description=Test to make sure that mount namespace setup works properly with the 'InaccessiblePaths=/proc' option
+
+[Service]
+InaccessiblePaths=/proc
+ExecStart=/bin/sh -x -c 'test "$$(stat -c %%a /proc)" = "0"'
+Type=oneshot
[Service]
ProtectKernelModules=yes
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
[Service]
ReadOnlyPaths=-/i-dont-exist
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
[Service]
ReadWritePaths=-/i-dont-exist
-ExecStart=/bin/sh -x -c 'mkdir -p /TEST; mount -t tmpfs tmpfs /TEST; grep TEST /proc/self/mountinfo && ! grep TEST /proc/$${PPID}/mountinfo && ! grep TEST /proc/1/mountinfo'
+ExecStart=/bin/sh -x -c 'd=$$(mktemp -d -p /tmp); trap "umount \'$$d\' && rmdir \'$$d\'" EXIT; mount -t tmpfs tmpfs "$$d"; grep "$$d" /proc/self/mountinfo && ! grep "$$d" /proc/$${PPID}/mountinfo && ! grep "$$d" /proc/1/mountinfo'
Type=oneshot
LOOKS_LIKE_DEBIAN=$(source /etc/os-release && [[ "$ID" = "debian" || "$ID_LIKE" = "debian" ]] && echo yes)
LOOKS_LIKE_ARCH=$(source /etc/os-release && [[ "$ID" = "arch" ]] && echo yes)
+LOOKS_LIKE_SUSE=$(source /etc/os-release && [[ "$ID_LIKE" = "suse" ]] && echo yes)
KERNEL_VER=${KERNEL_VER-$(uname -r)}
KERNEL_MODS="/lib/modules/$KERNEL_VER/"
QEMU_TIMEOUT="${QEMU_TIMEOUT:-infinity}"
NSPAWN_TIMEOUT="${NSPAWN_TIMEOUT:-infinity}"
TIMED_OUT= # will be 1 after run_* if *_TIMEOUT is set and test timed out
-FSTYPE="${FSTYPE:-ext3}"
+[[ "$LOOKS_LIKE_SUSE" ]] && FSTYPE="${FSTYPE:-btrfs}" || FSTYPE="${FSTYPE:-ext3}"
UNIFIED_CGROUP_HIERARCHY="${UNIFIED_CGROUP_HIERARCHY:-default}"
if ! ROOTLIBDIR=$(pkg-config --variable=systemdutildir systemd); then
default_fedora_initrd=/boot/initramfs-${KERNEL_VER}.img
default_debian_initrd=/boot/initrd.img-${KERNEL_VER}
default_arch_initrd=/boot/initramfs-linux.img
+ default_suse_initrd=/boot/initrd-${KERNEL_VER}
if [[ ! "$INITRD" ]]; then
if [[ -e "$default_fedora_initrd" ]]; then
INITRD="$default_fedora_initrd"
INITRD="$default_debian_initrd"
elif [[ "$LOOKS_LIKE_ARCH" && -e "$default_arch_initrd" ]]; then
INITRD="$default_arch_initrd"
+ elif [[ "$LOOKS_LIKE_SUSE" && -e "$default_suse_initrd" ]]; then
+ INITRD="$default_suse_initrd"
fi
fi
exit 1
fi
- KERNEL_APPEND="root=/dev/sda1 \
+if [[ "$LOOKS_LIKE_SUSE" ]]; then
+ PARAMS+="rd.hostonly=0"
+else
+ PARAMS+="ro"
+fi
+
+KERNEL_APPEND="$PARAMS \
+root=/dev/sda1 \
raid=noautodetect \
loglevel=2 \
init=$ROOTLIBDIR/systemd \
-ro \
console=ttyS0 \
selinux=0 \
$_cgroup_args \
# and it could fill the available space
strip_binaries
+ [[ "$LOOKS_LIKE_SUSE" ]] && setup_suse
+
# enable debug logging in PID1
echo LogLevel=debug >> $initdir/etc/systemd/system.conf
}
# set the hostname
echo systemd-testsuite > $initdir/etc/hostname
# fstab
+ if [[ "$LOOKS_LIKE_SUSE" ]]; then
+ ROOTMOUNT="/dev/sda1 / ${FSTYPE} rw 0 1"
+ else
+ ROOTMOUNT="LABEL=systemd / ${FSTYPE} rw 0 1"
+ fi
+
cat >$initdir/etc/fstab <<EOF
-LABEL=systemd / ${FSTYPE} rw 0 1
+$ROOTMOUNT
EOF
}
fi
}
+setup_suse() {
+ ln -s ../usr/bin/systemctl $initdir/bin/systemctl
+ ln -s ../usr/lib/systemd $initdir/lib/systemd
+ inst_simple "/usr/lib/systemd/system/haveged.service"
+}
+
do_test() {
if [[ $UID != "0" ]]; then
echo "TEST: $TEST_DESCRIPTION [SKIPPED]: not root" >&2
/etc.conf
/systemd.conf
+/systemd-remote.conf
+/var.conf
--- /dev/null
+enable_tmpfiles = conf.get('ENABLE_TMPFILES', false)
+
+tmpfiles = [['home.conf', ''],
+ ['journal-nocow.conf', ''],
+ ['systemd-nologin.conf', ''],
+ ['systemd-nspawn.conf', ''],
+ ['tmp.conf', ''],
+ ['x11.conf', ''],
+ ['legacy.conf', 'HAVE_SYSV_COMPAT'],
+ ]
+
+foreach pair : tmpfiles
+ if not enable_tmpfiles
+ # do nothing
+ elif pair[1] == '' or conf.get(pair[1], false)
+ install_data(pair[0], install_dir : tmpfilesdir)
+ else
+ message('Not installing tmpfiles.d/@0@ because @1@ is @2@'
+ .format(pair[0], pair[1], conf.get(pair[1], 0)))
+ endif
+endforeach
+
+m4_files = [['etc.conf', ''],
+ ['systemd.conf', ''],
+ ['systemd-remote.conf', 'ENABLE_REMOTE'],
+ ['var.conf', ''],
+ ]
+
+foreach pair : m4_files
+ if not enable_tmpfiles
+ # do nothing
+ elif pair[1] == '' or conf.get(pair[1], false)
+ custom_target(
+ 'tmpfiles.d_' + pair[0],
+ input : pair[0] + '.m4',
+ output: pair[0],
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : true,
+ install_dir : tmpfilesdir)
+ else
+ message('Not installing tmpfiles.d/@0@.m4 because @1@ is @2@'
+ .format(pair[0], pair[1], conf.get(pair[1], 0)))
+ endif
+endforeach
+
+if enable_tmpfiles
+ meson.add_install_script(
+ 'sh', '-c',
+ mkdir_p.format(join_paths(sysconfdir, 'tmpfiles.d')))
+endif
+++ /dev/null
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-# See tmpfiles.d(5) for details
-
-d /var/lib/systemd/journal-upload 0755 systemd-journal-upload systemd-journal-upload - -
-
-z /var/log/journal/remote 2755 systemd-journal-remote systemd-journal-remote - -
-z /run/log/journal/remote 2755 systemd-journal-remote systemd-journal-remote - -
--- /dev/null
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+m4_ifdef(`HAVE_LIBCURL',
+
+d /var/lib/systemd/journal-upload 0755 systemd-journal-upload systemd-journal-upload - -
+)m4_dnl
+m4_ifdef(`HAVE_MICROHTTPD',
+
+z /var/log/journal/remote 2755 systemd-journal-remote systemd-journal-remote - -
+z /run/log/journal/remote 2755 systemd-journal-remote systemd-journal-remote - -
+)m4_dnl
+++ /dev/null
-# This file is part of systemd.
-#
-# systemd is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-
-# See tmpfiles.d(5) for details
-
-q /var 0755 - - -
-
-L /var/run - - - - ../run
-
-d /var/log 0755 - - -
-f /var/log/wtmp 0664 root utmp -
-f /var/log/btmp 0600 root utmp -
-
-d /var/cache 0755 - - -
-
-d /var/lib 0755 - - -
-
-d /var/spool 0755 - - -
--- /dev/null
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# See tmpfiles.d(5) for details
+
+q /var 0755 - - -
+
+L /var/run - - - - ../run
+
+d /var/log 0755 - - -
+m4_ifdef(`HAVE_UTMP',
+f /var/log/wtmp 0664 root utmp -
+f /var/log/btmp 0600 root utmp -
+f /var/log/lastlog 0664 root utmp -
+)m4_dnl
+
+d /var/cache 0755 - - -
+
+d /var/lib 0755 - - -
+
+d /var/spool 0755 - - -
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd. It is distrubuted under the MIT license, see
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
#
-# Copyright 2013 Zbigniew Jędrzejewski-Szmek
+# Copyright 2013, 2017 Zbigniew Jędrzejewski-Szmek
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
import collections
import sys
import os.path
+import pprint
from xml_helper import *
SECTION = '''\
{dist_files}
'''
+meson = False
+
def man(page, number):
- return 'man/{}.{}'.format(page, number)
+ return ('man/' if not meson else '') + '{}.{}'.format(page, number)
def xml(file):
- return 'man/{}'.format(os.path.basename(file))
+ return ('man/' if not meson else '') + os.path.basename(file)
def add_rules(rules, name):
xml = xml_parse(name)
for conditional,rulegroup in sorted(rules.items())
) + FOOTER.format(dist_files=mjoin(sorted(dist_files)))
+MESON_HEADER = '''\
+# Do not edit. Generated by make-man-rules.py.
+manpages = ['''
+
+MESON_FOOTER = '''\
+]
+# Really, do not edit.'''
+
+def make_mesonfile(rules, dist_files):
+ # reformat rules as
+ # grouped = [ [name, section, [alias...], condition], ...]
+ #
+ # but first create a dictionary like
+ # lists = { (name, condition) => [alias...]
+ grouped = collections.defaultdict(list)
+ for condition, items in rules.items():
+ for alias, name in items.items():
+ group = grouped[(name, condition)]
+ if name != alias:
+ group.append(alias)
+
+ lines = [ [p[0][:-2], p[0][-1], sorted(a[:-2] for a in aliases), p[1]]
+ for p, aliases in sorted(grouped.items()) ]
+ return '\n'.join((MESON_HEADER, pprint.pformat(lines)[1:-1], MESON_FOOTER))
+
if __name__ == '__main__':
- rules = create_rules(sys.argv[1:])
- dist_files = (xml(file) for file in sys.argv[1:]
+ meson = sys.argv[1] == '--meson'
+ pages = sys.argv[1+meson:]
+
+ rules = create_rules(pages)
+ dist_files = (xml(file) for file in pages
if not file.endswith(".directives.xml") and
not file.endswith(".index.xml"))
- print(make_makefile(rules, dist_files), end='')
+ if meson:
+ print(make_mesonfile(rules, dist_files))
+ else:
+ print(make_makefile(rules, dist_files), end='')
--- /dev/null
+#!/bin/sh -eu
+
+"$@" '-' -o/dev/null </dev/null
--- /dev/null
+#!/bin/sh -eu
+
+# output width
+if "$1" --help | grep -v 'default:' | grep -E -q '.{80}.'; then
+ echo "$(basename "$1") --help output is too wide:"
+ "$1" --help | awk 'length > 80' | grep -E --color=yes '.{80}'
+ exit 1
+fi
+
+# no --help output to stdout
+if "$1" --help 2>&1 1>/dev/null | grep .; then
+ echo "$(basename "$1") --help prints to stderr"
+ exit 2
+fi
+
+# error output to stderr
+if ! "$1" --no-such-parameter 2>&1 1>/dev/null | grep -q .; then
+ echo "$(basename "$1") with an unknown parameter does not print to stderr"
+ exit 3
+fi
--- /dev/null
+#!/bin/sh -eu
+
+git shortlog -s `git describe --abbrev=0`.. | \
+ cut -c8- | \
+ sed 's/ / /g' | \
+ awk '{ print $$0 "," }' | \
+ sed -e 's/ / /g' | \
+ sort -u
--- /dev/null
+#!/bin/sh -eu
+
+cd "$1"
+
+curl -L -o usb.ids 'http://www.linux-usb.org/usb.ids'
+curl -L -o pci.ids 'http://pci-ids.ucw.cz/v2.2/pci.ids'
+curl -L -o ma-large.txt 'http://standards-oui.ieee.org/oui/oui.txt'
+curl -L -o ma-medium.txt 'http://standards-oui.ieee.org/oui28/mam.txt'
+curl -L -o ma-small.txt 'http://standards-oui.ieee.org/oui36/oui36.txt'
+curl -L -o pnp_id_registry.html 'http://www.uefi.org/uefi-pnp-export'
+curl -L -o acpi_id_registry.html 'http://www.uefi.org/uefi-acpi-export'
+./ids-update.pl
+./acpi-update.py > 20-acpi-vendor.hwdb.base
+patch -p0 -o- 20-acpi-vendor.hwdb.base <20-acpi-vendor.hwdb.patch >20-acpi-vendor.hwdb
+diff -u 20-acpi-vendor.hwdb.base 20-acpi-vendor.hwdb >20-acpi-vendor.hwdb.patch
--- /dev/null
+int main(void) {return 0;}
--- /dev/null
+#!/bin/sh -eu
+
+# this is needed mostly because $DESTDIR is provided as a variable,
+# and we need to create the target directory...
+
+mkdir -vp "$(dirname "${DESTDIR:-}$2")"
+if [ "$(dirname $1)" = . ]; then
+ ln -vfs -T "$1" "${DESTDIR:-}$2"
+else
+ ln -vfs -T --relative "${DESTDIR:-}$1" "${DESTDIR:-}$2"
+fi
-#!/usr/bin/python3
+#!/usr/bin/env python3
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
#
# This file is part of systemd.
Before=getty.target
[Service]
-ExecStart=-/sbin/agetty --noclear --keep-baud console 115200,38400,9600 $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear --keep-baud console 115200,38400,9600 $TERM
Type=idle
Restart=always
RestartSec=0
ConditionPathExists=/dev/pts/%I
[Service]
-ExecStart=-/sbin/agetty --noclear --keep-baud pts/%I 115200,38400,9600 $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear --keep-baud pts/%I 115200,38400,9600 $TERM
Type=idle
Restart=always
RestartSec=0
[Unit]
Description=Huge Pages File System
Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/sys/kernel/mm/hugepages
[Unit]
Description=POSIX Message Queue File System
Documentation=man:mq_overview(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/mqueue
[Service]
Environment=HOME=/root
WorkingDirectory=-/root
-ExecStartPre=-/bin/plymouth --wait quit
-ExecStartPre=-/bin/echo -e 'You are in emergency mode. After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\ntry again to boot into default mode.'
-ExecStart=-/bin/sh -c "@SULOGIN@; @SYSTEMCTL@ --job-mode=fail --no-block default"
+ExecStart=-@rootlibexecdir@/systemd-sulogin-shell emergency
Type=idle
StandardInput=tty-force
StandardOutput=inherit
[Service]
# the VT is cleared by TTYVTDisallocate
-ExecStart=-/sbin/agetty --noclear %I $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM
Type=idle
Restart=always
RestartSec=0
--- /dev/null
+#!/bin/sh -eu
+
+unitdir="$1"
+target="$2"
+unit="$3"
+
+case "$target" in
+ */?*) # a path, but not just a slash at the end
+ dir="${DESTDIR:-}${target}"
+ ;;
+ *)
+ dir="${DESTDIR:-}${unitdir}/${target}"
+ ;;
+esac
+
+unitpath="${DESTDIR:-}${unitdir}/${unit}"
+
+case "$target" in
+ */)
+ mkdir -p -m 0755 "$dir"
+ ;;
+ *)
+ mkdir -p -m 0755 "$(basename "$dir")"
+ ;;
+esac
+
+ln -vfs --relative "$unitpath" "$dir"
--- /dev/null
+units = [
+ ['basic.target', ''],
+ ['bluetooth.target', ''],
+ ['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
+ ['cryptsetup.target', 'HAVE_LIBCRYPTSETUP',
+ 'sysinit.target.wants/'],
+ ['dev-hugepages.mount', '',
+ 'sysinit.target.wants/'],
+ ['dev-mqueue.mount', '',
+ 'sysinit.target.wants/'],
+ ['emergency.target', ''],
+ ['exit.target', ''],
+ ['final.target', ''],
+ ['getty.target', '',
+ 'multi-user.target.wants/'],
+ ['graphical.target', '',
+ 'runlevel5.target default.target'],
+ ['halt.target', ''],
+ ['hibernate.target', 'ENABLE_HIBERNATE'],
+ ['hybrid-sleep.target', 'ENABLE_HIBERNATE'],
+ ['initrd-fs.target', ''],
+ ['initrd-root-device.target', ''],
+ ['initrd-root-fs.target', ''],
+ ['initrd-switch-root.target', ''],
+ ['initrd.target', ''],
+ ['kexec.target', ''],
+ ['ldconfig.service', 'ENABLE_LDCONFIG',
+ 'sysinit.target.wants/'],
+ ['local-fs-pre.target', ''],
+ ['local-fs.target', ''],
+ ['machine.slice', 'ENABLE_MACHINED'],
+ ['machines.target', 'ENABLE_MACHINED',
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['multi-user.target', '',
+ 'runlevel2.target runlevel3.target runlevel4.target'],
+ ['network-online.target', ''],
+ ['network-pre.target', ''],
+ ['network.target', ''],
+ ['nss-lookup.target', ''],
+ ['nss-user-lookup.target', ''],
+ ['paths.target', ''],
+ ['poweroff.target', '',
+ 'runlevel0.target'],
+ ['printer.target', ''],
+ ['proc-sys-fs-binfmt_misc.automount', 'ENABLE_BINFMT',
+ 'sysinit.target.wants/'],
+ ['proc-sys-fs-binfmt_misc.mount', 'ENABLE_BINFMT'],
+ ['reboot.target', '',
+ 'runlevel6.target ctrl-alt-del.target'],
+ ['remote-fs-pre.target', ''],
+ ['remote-fs.target', '',
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['rescue.target', '',
+ 'runlevel1.target'],
+ ['rpcbind.target', ''],
+ ['shutdown.target', ''],
+ ['sigpwr.target', ''],
+ ['sleep.target', ''],
+ ['slices.target', ''],
+ ['smartcard.target', ''],
+ ['sockets.target', ''],
+ ['sound.target', ''],
+ ['suspend.target', ''],
+ ['swap.target', ''],
+ ['sys-fs-fuse-connections.mount', '',
+ 'sysinit.target.wants/'],
+ ['sys-kernel-config.mount', '',
+ 'sysinit.target.wants/'],
+ ['sys-kernel-debug.mount', '',
+ 'sysinit.target.wants/'],
+ ['sysinit.target', ''],
+ ['syslog.socket', ''],
+ ['system-update.target', ''],
+ ['system.slice', ''],
+ ['systemd-ask-password-console.path', '',
+ 'sysinit.target.wants/'],
+ ['systemd-ask-password-wall.path', '',
+ 'multi-user.target.wants/'],
+ ['systemd-coredump.socket', 'ENABLE_COREDUMP',
+ 'sockets.target.wants/'],
+ ['systemd-initctl.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journal-remote.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journald-audit.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-journald-dev-log.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-journald.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-networkd.socket', '',
+ join_paths(pkgsysconfdir, 'system/sockets.target.wants/')],
+ ['systemd-rfkill.socket', 'ENABLE_RFKILL'],
+ ['systemd-tmpfiles-clean.timer', '',
+ 'timers.target.wants/'],
+ ['systemd-udevd-control.socket', '',
+ 'sockets.target.wants/'],
+ ['systemd-udevd-kernel.socket', '',
+ 'sockets.target.wants/'],
+ ['time-sync.target', ''],
+ ['timers.target', ''],
+ ['umount.target', ''],
+ ['user.slice', ''],
+ ['var-lib-machines.mount', 'ENABLE_MACHINED',
+ 'remote-fs.target.wants/ machines.target.wants/'],
+]
+
+in_units = [
+ ['debug-shell.service', ''],
+ ['emergency.service', ''],
+ ['halt-local.service', 'HAVE_SYSV_COMPAT'],
+ ['initrd-cleanup.service', ''],
+ ['initrd-parse-etc.service', ''],
+ ['initrd-switch-root.service', ''],
+ ['initrd-udevadm-cleanup-db.service', ''],
+ ['kmod-static-nodes.service', 'HAVE_KMOD ENABLE_TMPFILES',
+ 'sysinit.target.wants/'],
+ ['quotaon.service', 'ENABLE_QUOTACHECK'],
+ ['rc-local.service', 'HAVE_SYSV_COMPAT'],
+ ['rescue.service', ''],
+ ['system-update-cleanup.service', ''],
+ ['systemd-ask-password-console.service', ''],
+ ['systemd-ask-password-wall.service', ''],
+ ['systemd-backlight@.service', 'ENABLE_BACKLIGHT'],
+ ['systemd-binfmt.service', 'ENABLE_BINFMT',
+ 'sysinit.target.wants/'],
+ ['systemd-coredump@.service', 'ENABLE_COREDUMP'],
+ ['systemd-exit.service', ''],
+ ['systemd-firstboot.service', 'ENABLE_FIRSTBOOT',
+ 'sysinit.target.wants/'],
+ ['systemd-fsck-root.service', ''],
+ ['systemd-fsck@.service', ''],
+ ['systemd-halt.service', ''],
+ ['systemd-hibernate-resume@.service', 'ENABLE_HIBERNATE'],
+ ['systemd-hibernate.service', 'ENABLE_HIBERNATE'],
+ ['systemd-hybrid-sleep.service', 'ENABLE_HIBERNATE'],
+ ['systemd-hostnamed.service', 'ENABLE_HOSTNAMED',
+ 'dbus-org.freedesktop.hostname1.service'],
+ ['systemd-hwdb-update.service', 'ENABLE_HWDB',
+ 'sysinit.target.wants/'],
+ ['systemd-importd.service', 'ENABLE_IMPORTD',
+ 'dbus-org.freedesktop.import1.service'],
+ ['systemd-initctl.service', ''],
+ ['systemd-journal-catalog-update.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-journal-flush.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-journal-gatewayd.service', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journal-remote.service', 'ENABLE_REMOTE HAVE_MICROHTTPD'],
+ ['systemd-journal-upload.service', 'ENABLE_REMOTE HAVE_LIBCURL'],
+ ['systemd-journald.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-kexec.service', ''],
+ ['systemd-localed.service', 'ENABLE_LOCALED',
+ 'dbus-org.freedesktop.locale1.service'],
+ ['systemd-logind.service', 'ENABLE_LOGIND',
+ 'multi-user.target.wants/ dbus-org.freedesktop.login1.service'],
+ ['systemd-machine-id-commit.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-machined.service', 'ENABLE_MACHINED',
+ 'dbus-org.freedesktop.machine1.service'],
+ ['systemd-modules-load.service', 'HAVE_KMOD',
+ 'sysinit.target.wants/'],
+ ['systemd-networkd-wait-online.service', 'ENABLE_NETWORKD',
+ join_paths(pkgsysconfdir, 'system/network-online.target.wants/')],
+ ['systemd-nspawn@.service', ''],
+ ['systemd-poweroff.service', ''],
+ ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'],
+ ['systemd-random-seed.service', 'ENABLE_RANDOMSEED',
+ 'sysinit.target.wants/'],
+ ['systemd-reboot.service', ''],
+ ['systemd-remount-fs.service', '',
+ 'local-fs.target.wants/'],
+ ['systemd-rfkill.service', 'ENABLE_RFKILL'],
+ ['systemd-suspend.service', ''],
+ ['systemd-sysctl.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-sysusers.service', 'ENABLE_SYSUSERS',
+ 'sysinit.target.wants/'],
+ ['systemd-timedated.service', 'ENABLE_TIMEDATED',
+ 'dbus-org.freedesktop.timedate1.service'],
+ ['systemd-timesyncd.service', 'ENABLE_TIMESYNCD',
+ join_paths(pkgsysconfdir, 'system/sysinit.target.wants/')],
+ ['systemd-tmpfiles-clean.service', 'ENABLE_TMPFILES'],
+ ['systemd-tmpfiles-setup-dev.service', 'ENABLE_TMPFILES',
+ 'sysinit.target.wants/'],
+ ['systemd-tmpfiles-setup.service', 'ENABLE_TMPFILES',
+ 'sysinit.target.wants/'],
+ ['systemd-udev-settle.service', ''],
+ ['systemd-udev-trigger.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-udevd.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-update-done.service', '',
+ 'sysinit.target.wants/'],
+ ['systemd-update-utmp-runlevel.service', 'HAVE_UTMP HAVE_SYSV_COMPAT',
+ 'multi-user.target.wants/ graphical.target.wants/ rescue.target.wants/'],
+ ['systemd-update-utmp.service', 'HAVE_UTMP',
+ 'sysinit.target.wants/'],
+ ['systemd-user-sessions.service', '',
+ 'multi-user.target.wants/'],
+ ['systemd-vconsole-setup.service', 'ENABLE_VCONSOLE'],
+ ['systemd-volatile-root.service', ''],
+]
+
+m4_units = [
+ ['getty@.service', '',
+ 'autovt@.service ' +
+ join_paths(pkgsysconfdir, 'system/getty.target.wants/getty@tty1.service')],
+ ['serial-getty@.service', ''],
+ ['tmp.mount', '',
+ 'local-fs.target.wants/'],
+]
+
+m4_in_units = [
+ ['console-getty.service', ''],
+ ['container-getty@.service', ''],
+ ['systemd-networkd.service', 'ENABLE_NETWORKD',
+ join_paths(pkgsysconfdir, 'system/dbus-org.freedesktop.network1.service') + ' ' +
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['systemd-resolved.service', 'ENABLE_RESOLVED',
+ join_paths(pkgsysconfdir, 'system/dbus-org.freedesktop.resolve1.service') + ' ' +
+ join_paths(pkgsysconfdir, 'system/multi-user.target.wants/')],
+ ['user@.service', ''],
+]
+
+foreach tuple : m4_in_units
+ file = tuple[0]
+
+ gen = configure_file(
+ input : file + '.m4.in',
+ output : file + '.m4',
+ configuration : substs)
+
+ m4_units += [[file, tuple.get(1, ''), tuple.get(2, ''), gen]]
+endforeach
+
+foreach tuple : in_units
+ file = tuple[0]
+
+ # we do this here because install_data does not accept custom_target output
+ conds = tuple[1].split(' ')
+ install = ((conds.get(0, '') == '' or conf.get(conds[0], false)) and
+ (conds.get(1, '') == '' or conf.get(conds[1], false)))
+
+ gen1 = configure_file(
+ input : file + '.in',
+ output : file + '.tmp',
+ configuration : substs)
+ gen2 = custom_target(
+ file,
+ input : gen1,
+ output : file,
+ command : [sed, '/^## /d', '@INPUT@'],
+ capture : true,
+ install : install,
+ install_dir : systemunitdir)
+
+ if install and tuple.length() > 2
+ foreach target : tuple[2].split()
+ meson.add_install_script('meson-add-wants.sh', systemunitdir, target, file)
+ endforeach
+ endif
+endforeach
+
+foreach tuple : m4_units
+ file = tuple[0]
+ input = tuple.get(3, file + '.m4')
+
+ # we do this here because install_data does not accept custom_target output
+ conds = tuple[1].split(' ')
+ install = ((conds.get(0, '') == '' or conf.get(conds[0], false)) and
+ (conds.get(1, '') == '' or conf.get(conds[1], false)))
+
+ custom_target(
+ file,
+ input : input,
+ output: file,
+ command : [m4, '-P'] + m4_defines + ['@INPUT@'],
+ capture : true,
+ install : install,
+ install_dir : systemunitdir)
+
+ if tuple.length() > 2 and install
+ foreach target : tuple[2].split()
+ meson.add_install_script('meson-add-wants.sh', systemunitdir, target, file)
+ endforeach
+ endif
+endforeach
+
+foreach tuple : units
+ file = tuple[0]
+ input = tuple.get(3, file)
+
+ conds = tuple[1].split(' ')
+ install = ((conds.get(0, '') == '' or conf.get(conds[0], false)) and
+ (conds.get(1, '') == '' or conf.get(conds[1], false)))
+
+ if install
+ install_data(input,
+ install_dir : systemunitdir)
+
+ if tuple.length() > 2
+ foreach target : tuple[2].split()
+ meson.add_install_script(
+ 'meson-add-wants.sh', systemunitdir, target, file)
+ endforeach
+ endif
+ endif
+endforeach
+
+############################################################
+
+meson.add_install_script(meson_make_symlink,
+ join_paths(pkgsysconfdir, 'user'),
+ join_paths(sysconfdir, 'xdg/systemd/user'))
+meson.add_install_script(meson_make_symlink,
+ join_paths(dbussystemservicedir, 'org.freedesktop.systemd1.service'),
+ join_paths(dbussessionservicedir, 'org.freedesktop.systemd1.service'))
+if conf.get('HAVE_SYSV_COMPAT', false)
+ foreach i : [1, 2, 3, 4, 5]
+ meson.add_install_script(
+ 'sh', '-c',
+ mkdir_p
+ .format(join_paths(systemunitdir, 'runlevel@0@.target.wants'.format(i))))
+ endforeach
+endif
+
+subdir('user')
[Unit]
Description=Network is Online
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
After=network.target
[Unit]
Description=Network (Pre)
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
RefuseManualStart=yes
[Unit]
Description=Network
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
After=network-pre.target
RefuseManualStart=yes
[Unit]
Description=Hostname Service Bus Name
Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/hostnamed
[BusName]
Service=systemd-hostnamed.service
[Unit]
Description=Locale Service Bus Name
Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/localed
[BusName]
Service=systemd-localed.service
[Unit]
Description=Login Service Bus Name
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
[BusName]
Service=systemd-logind.service
[Unit]
Description=Virtual Machine and Container Registration Service Bus Name
Documentation=man:systemd-machined.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
[BusName]
Service=systemd-machined.service
[Unit]
Description=Network Name Resolution Service Bus Name
Documentation=man:systemd-resolved.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
# This is pulled in by systemd-resolved.service, since it cannot run
# without its policy set. However, let's conditionalize this unit on
[Unit]
Description=System and Service Manager Bus Name
Documentation=man:systemd(1)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd
+Documentation=https://www.freedesktop.org/wiki/Software/systemd
[BusName]
Activating=no
[Unit]
Description=Time & Date Service Bus Name
Documentation=man:systemd-timedated.service(8) man:localtime(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/timedated
[BusName]
Service=systemd-timedated.service
[Unit]
Description=Arbitrary Executable File Formats File System Automount Point
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/binfmt_misc/
[Unit]
Description=Arbitrary Executable File Formats File System
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
[Mount]
Documentation=man:quotaon(8)
DefaultDependencies=no
After=systemd-quotacheck.service
-Before=local-fs.target shutdown.target
+Before=remote-fs.target shutdown.target
ConditionPathExists=@QUOTAON@
[Service]
[Service]
Environment=HOME=/root
WorkingDirectory=-/root
-ExecStartPre=-/bin/plymouth --wait quit
-ExecStartPre=-/bin/echo -e 'You are in rescue mode. After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\nboot into default mode.'
-ExecStart=-/bin/sh -c "@SULOGIN@; @SYSTEMCTL@ --job-mode=fail --no-block default"
+ExecStart=-@rootlibexecdir@/systemd-sulogin-shell rescue
Type=idle
StandardInput=tty-force
StandardOutput=inherit
Before=getty.target
IgnoreOnIsolate=yes
+# IgnoreOnIsolate causes issues with sulogin, if someone isolates
+# rescue.target or starts rescue.service from multi-user.target or
+# graphical.target.
+Conflicts=rescue.service
+Before=rescue.service
+
[Service]
-ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM
+# The '-o' option value tells agetty to replace 'login' arguments with an
+# option to preserve environment (-p), followed by '--' for safety, and then
+# the entered username.
+ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud 115200,38400,9600 %I $TERM
Type=idle
Restart=always
UtmpIdentifier=%I
[Unit]
Description=FUSE Control File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/fuse.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/fs/fuse/connections
ConditionCapability=CAP_SYS_ADMIN
# (at your option) any later version.
[Unit]
-Description=Configuration File System
+Description=Kernel Configuration File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/kernel/config
ConditionCapability=CAP_SYS_RAWIO
# (at your option) any later version.
[Unit]
-Description=Debug File System
+Description=Kernel Debug File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/kernel/debug
ConditionCapability=CAP_SYS_RAWIO
[Unit]
Description=Syslog Socket
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/syslog
DefaultDependencies=no
Before=sockets.target shutdown.target
# [Install]
# Alias=syslog.service
#
-# See http://www.freedesktop.org/wiki/Software/systemd/syslog for details.
+# See https://www.freedesktop.org/wiki/Software/systemd/syslog for details.
[Service]
ExecStart=@rootbindir@/systemd-tty-ask-password-agent --watch --console
+SystemCallArchitectures=native
[Service]
ExecStartPre=-@SYSTEMCTL@ stop systemd-ask-password-console.path systemd-ask-password-console.service systemd-ask-password-plymouth.path systemd-ask-password-plymouth.service
ExecStart=@rootbindir@/systemd-tty-ask-password-agent --wall
+SystemCallArchitectures=native
ExecStart=-@rootlibexecdir@/systemd-coredump
Nice=9
OOMScoreAdjust=500
-PrivateNetwork=yes
-ProtectSystem=full
RuntimeMaxSec=5min
+PrivateTmp=yes
+PrivateDevices=yes
+PrivateNetwork=yes
+ProtectSystem=strict
+ProtectHome=yes
+ProtectControlGroups=yes
+ProtectKernelTunables=yes
+ProtectKernelModules=yes
+MemoryDenyWriteExecute=yes
+RestrictRealtime=yes
+RestrictNamespaces=yes
+RestrictAddressFamilies=AF_UNIX
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/var/lib/systemd/coredump
[Unit]
Description=Hostname Service
Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/hostnamed
[Service]
ExecStart=@rootlibexecdir@/systemd-hostnamed
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=yes
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/etc
[Unit]
Description=Virtual Machine and Container Download Service
Documentation=man:systemd-importd.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/importd
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/importd
[Service]
ExecStart=@rootlibexecdir@/systemd-importd
NoNewPrivileges=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=net
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
DefaultDependencies=no
[Service]
-ExecStart=@rootlibexecdir@/systemd-initctl
NotifyAccess=all
+ExecStart=@rootlibexecdir@/systemd-initctl
+SystemCallArchitectures=native
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallArchitectures=native
# If there are many split upjournal files we need a lot of fds to
# access them all and combine
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallArchitectures=native
+ReadWritePaths=/var/log/journal/remote
[Install]
Also=systemd-journal-remote.socket
WatchdogSec=3min
PrivateTmp=yes
PrivateDevices=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+SystemCallArchitectures=native
+ReadWritePaths=/var/lib/systemd/journal-upload
# If there are many split up journal files we need a lot of fds to
# access them all and combine
ExecStart=@rootlibexecdir@/systemd-journald
Restart=always
RestartSec=0
-NotifyAccess=all
StandardOutput=null
WatchdogSec=3min
FileDescriptorStoreMax=1024
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_CHOWN CAP_DAC_READ_SEARCH CAP_FOWNER CAP_SETUID CAP_SETGID CAP_MAC_OVERRIDE
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
# Increase the default a bit in order to allow many simultaneous
# services being run since we keep one fd open per service. Also, when
[Unit]
Description=Locale Service
Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/localed
[Service]
ExecStart=@rootlibexecdir@/systemd-localed
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
-ProtectSystem=yes
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/etc
[Unit]
Description=Login Service
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
Wants=user.slice
After=nss-user-lookup.target user.slice
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_MAC_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+FileDescriptorStoreMax=512
# Increase the default a bit in order to allow many simultaneous
# logins since we keep one fd open per session.
[Unit]
Description=Virtual Machine and Container Registration Service
Documentation=man:systemd-machined.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
Wants=machine.slice
After=machine.slice
+RequiresMountsFor=/var/lib/machines
[Service]
ExecStart=@rootlibexecdir@/systemd-machined
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
# Note that machined cannot be placed in a mount namespace, since it
# needs access to the host's mount namespace in order to implement the
Documentation=man:systemd-networkd-wait-online.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
-Requisite=systemd-networkd.service
+Requires=systemd-networkd.service
After=systemd-networkd.service
Before=network-online.target
ExecStart=@rootlibexecdir@/systemd-networkd
WatchdogSec=3min
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/run/systemd
[Install]
WantedBy=multi-user.target
Also=systemd-networkd.socket
+Alias=dbus-org.freedesktop.network1.service
+
+# We want to enable systemd-networkd-wait-online.service whenever this service
+# is enabled. systemd-networkd-wait-online.service has
+# WantedBy=network-online.target, so enabling it only has an effect if
+# network-online.target itself is enabled or pulled in by some other unit.
+Also=systemd-networkd-wait-online.service
PartOf=machines.target
Before=machines.target
After=network.target systemd-resolved.service
+RequiresMountsFor=/var/lib/machines
[Service]
ExecStart=@bindir@/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-veth -U --settings=override --machine=%i
Documentation=man:systemd-quotacheck.service(8)
DefaultDependencies=no
After=systemd-remount-fs.service
-Before=local-fs.target shutdown.target
+Before=remote-fs.target shutdown.target
ConditionPathExists=@QUOTACHECK@
[Service]
[Unit]
Description=Remount Root and Kernel File Systems
Documentation=man:systemd-remount-fs.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-fsck-root.service
[Unit]
Description=Network Name Resolution
Documentation=man:systemd-resolved.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
After=systemd-networkd.service network.target
+Before=network-online.target nss-lookup.target
+Wants=nss-lookup.target
# On kdbus systems we pull in the busname explicitly, because it
# carries policy that allows the daemon to acquire its name.
CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER CAP_NET_RAW CAP_NET_BIND_SERVICE
PrivateTmp=yes
PrivateDevices=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
-SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/run/systemd
[Install]
WantedBy=multi-user.target
[Unit]
Description=Time & Date Service
Documentation=man:systemd-timedated.service(8) man:localtime(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/timedated
[Service]
ExecStart=@rootlibexecdir@/systemd-timedated
WatchdogSec=3min
CapabilityBoundingSet=CAP_SYS_TIME
PrivateTmp=yes
-ProtectSystem=yes
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX
-SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/etc
CapabilityBoundingSet=CAP_SYS_TIME CAP_SETUID CAP_SETGID CAP_SETPCAP CAP_CHOWN CAP_DAC_OVERRIDE CAP_FOWNER
PrivateTmp=yes
PrivateDevices=yes
-ProtectSystem=full
+ProtectSystem=strict
ProtectHome=yes
ProtectControlGroups=yes
ProtectKernelTunables=yes
+ProtectKernelModules=yes
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
+RestrictNamespaces=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
-SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
+SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @swap
+SystemCallArchitectures=native
+ReadWritePaths=/var/lib/systemd
[Install]
WantedBy=sysinit.target
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
+SystemCallArchitectures=native
# (at your option) any later version.
[Unit]
-Description=Temporary Directory
+Description=Temporary Directory (/tmp)
Documentation=man:hier(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
ConditionPathIsSymbolicLink=!/tmp
DefaultDependencies=no
Conflicts=umount.target
--- /dev/null
+units = [
+ 'basic.target',
+ 'bluetooth.target',
+ 'default.target',
+ 'exit.target',
+ 'graphical-session-pre.target',
+ 'graphical-session.target',
+ 'paths.target',
+ 'printer.target',
+ 'shutdown.target',
+ 'smartcard.target',
+ 'sockets.target',
+ 'sound.target',
+ 'timers.target',
+]
+
+foreach file : units
+ install_data(file,
+ install_dir : userunitdir)
+endforeach
+
+in_units = [
+ 'systemd-exit.service',
+]
+
+foreach file : in_units
+ gen = configure_file(
+ input : file + '.in',
+ output : file,
+ configuration : substs)
+ install_data(gen,
+ install_dir : userunitdir)
+endforeach