summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CONTRIBUTING.md26
-rw-r--r--.github/RELEASE.md12
-rw-r--r--.gitignore1
-rw-r--r--CODING_STYLE7
-rw-r--r--Makefile-man.am8
-rw-r--r--Makefile.am49
-rw-r--r--TODO7
-rwxr-xr-xautogen.sh12
-rw-r--r--coccinelle/htonl.cocci20
-rw-r--r--configure.ac13
-rw-r--r--hwdb/.gitignore7
-rw-r--r--hwdb/20-acpi-vendor.hwdb904
-rw-r--r--hwdb/20-acpi-vendor.hwdb.patch492
-rw-r--r--hwdb/60-evdev.hwdb7
-rw-r--r--hwdb/70-mouse.hwdb6
-rwxr-xr-xhwdb/acpi-update.py79
-rw-r--r--man/kernel-command-line.xml4
-rw-r--r--man/sd_bus_add_match.xml119
-rw-r--r--man/sd_bus_get_fd.xml101
-rw-r--r--man/sd_bus_message_read_basic.xml113
-rw-r--r--man/sd_bus_process.xml111
-rw-r--r--man/systemd.exec.xml58
-rw-r--r--man/systemd.netdev.xml40
-rw-r--r--man/systemd.network.xml17
-rw-r--r--man/systemd.resource-control.xml48
-rw-r--r--man/systemd.special.xml4
-rw-r--r--man/systemd.xml14
-rw-r--r--man/udevadm.xml2
-rw-r--r--src/basic/formats-util.h16
-rw-r--r--src/basic/missing.h7
-rw-r--r--src/basic/parse-util.c19
-rw-r--r--src/basic/parse-util.h2
-rw-r--r--src/basic/proc-cmdline.c18
-rw-r--r--src/basic/process-util.c95
-rw-r--r--src/basic/socket-util.c24
-rw-r--r--src/basic/unit-name.h1
-rw-r--r--src/basic/util.c80
-rw-r--r--src/basic/util.h2
-rw-r--r--src/core/busname.c7
-rw-r--r--src/core/cgroup.c2
-rw-r--r--src/core/dbus-cgroup.c60
-rw-r--r--src/core/execute.c72
-rw-r--r--src/core/kmod-setup.c3
-rw-r--r--src/core/load-fragment.c41
-rw-r--r--src/core/main.c2
-rw-r--r--src/core/manager.c39
-rw-r--r--src/core/mount-setup.c2
-rw-r--r--src/core/scope.c5
-rw-r--r--src/core/service.c22
-rw-r--r--src/core/socket.c16
-rw-r--r--src/core/unit.c2
-rw-r--r--src/dbus1-generator/dbus1-generator.c331
-rw-r--r--src/libsystemd-network/arp-util.c10
-rw-r--r--src/libsystemd-network/dhcp-network.c4
-rw-r--r--src/libsystemd-network/lldp-network.c3
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c2
-rw-r--r--src/libsystemd-network/sd-ndisc.c2
-rw-r--r--src/libsystemd/sd-bus/busctl.c3
-rw-r--r--src/libsystemd/sd-daemon/sd-daemon.c4
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c8
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.h1
-rw-r--r--src/libudev/libudev-monitor.c14
-rw-r--r--src/locale/keymap-util.c724
-rw-r--r--src/locale/keymap-util.h46
-rw-r--r--src/locale/localectl.c3
-rw-r--r--src/locale/localed.c818
-rw-r--r--src/locale/test-keymap-util.c220
-rw-r--r--src/login/loginctl.c4
-rw-r--r--src/login/logind-user.c29
-rw-r--r--src/login/logind.c2
-rw-r--r--src/login/pam_systemd.c31
-rw-r--r--src/machine/machinectl.c3
-rw-r--r--src/network/networkd-ipv4ll.c2
-rw-r--r--src/network/networkd-link.c25
-rw-r--r--src/network/networkd-netdev-gperf.gperf5
-rw-r--r--src/network/networkd-netdev-tunnel.c79
-rw-r--r--src/network/networkd-netdev-tunnel.h9
-rw-r--r--src/network/networkd-netdev-vrf.c50
-rw-r--r--src/network/networkd-netdev-vrf.h33
-rw-r--r--src/network/networkd-netdev.c8
-rw-r--r--src/network/networkd-netdev.h1
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.c6
-rw-r--r--src/network/networkd-network.h1
-rw-r--r--src/network/networkd-route.c13
-rw-r--r--src/network/networkd.h1
-rw-r--r--src/nspawn/nspawn-seccomp.c78
-rw-r--r--src/nspawn/nspawn.c12
-rw-r--r--src/nss-myhostname/nss-myhostname.c10
-rw-r--r--src/resolve/resolve-tool.c31
-rw-r--r--src/resolve/resolved-bus.c11
-rw-r--r--src/resolve/resolved-dns-answer.c4
-rw-r--r--src/resolve/resolved-dns-answer.h2
-rw-r--r--src/resolve/resolved-dns-scope.c11
-rw-r--r--src/resolve/resolved-dns-scope.h2
-rw-r--r--src/resolve/resolved-dns-transaction.c31
-rw-r--r--src/resolve/resolved-dns-zone.c13
-rw-r--r--src/resolve/resolved-dns-zone.h2
-rw-r--r--src/resolve/resolved-manager.c3
-rw-r--r--src/shared/bus-unit-util.c61
-rw-r--r--src/shared/bus-util.c34
-rw-r--r--src/shared/bus-util.h3
-rw-r--r--src/shared/install.c10
-rw-r--r--src/shared/seccomp-util.c55
-rw-r--r--src/systemctl/systemctl.c235
-rw-r--r--src/test/test-nss.c4
-rw-r--r--src/test/test-parse-util.c19
-rw-r--r--src/test/test-proc-cmdline.c11
-rw-r--r--src/test/test-process-util.c280
-rw-r--r--src/test/test-socket-util.c8
-rw-r--r--src/test/test-util.c50
-rw-r--r--src/timedate/timedatectl.c3
-rw-r--r--src/udev/udevadm-info.c12
-rw-r--r--units/emergency.service.in2
-rw-r--r--units/rescue.service.in2
-rw-r--r--units/systemd-hostnamed.service.in2
-rw-r--r--units/systemd-importd.service.in2
-rw-r--r--units/systemd-journald.service.in2
-rw-r--r--units/systemd-localed.service.in2
-rw-r--r--units/systemd-logind.service.in2
-rw-r--r--units/systemd-machined.service.in2
-rw-r--r--units/systemd-networkd.service.m4.in2
-rw-r--r--units/systemd-resolved.service.m4.in2
-rw-r--r--units/systemd-timedated.service.in2
-rw-r--r--units/systemd-timesyncd.service.in2
-rw-r--r--units/tmp.mount.m42
126 files changed, 4564 insertions, 1771 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 60f0fb9bef..4857e94733 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,34 +1,26 @@
# Contributing
-We welcome contributions from everyone. However, please follow the following guidelines when posting a GitHub Pull
-Request or filing a GitHub Issue on the systemd project:
+We welcome contributions from everyone. However, please follow the following guidelines when posting a GitHub Pull Request or filing a GitHub Issue on the systemd project:
## 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 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.
+* 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 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.
+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.
## Posting Pull Requests
* Make sure to post PRs only relative to a very recent git master.
-* Follow our [Coding Style](https://raw.githubusercontent.com/systemd/systemd/master/CODING_STYLE) when contributing
- code. This is a requirement for all code we merge.
-* Make sure to run "make check" locally, before posting your PR. We use a CI system, meaning we don't even look at your
- PR, if the build and tests don't pass.
+* Follow our [Coding Style](https://raw.githubusercontent.com/systemd/systemd/master/CODING_STYLE) when contributing code. This is a requirement for all code we merge.
+* Make sure to run "make check" locally, before posting your PR. We use a CI system, meaning we don't even look at your PR, if the build and tests don't pass.
* If you need to update the code in an existing PR, force-push into the same branch, overriding old commits with new versions.
+* After you have pushed a new version, try to remove the `reviewed/needs-rework` label. Also add a comment about the new version (no notification is sent just for the commits, so it's easy to miss the update without an explicit comment).
## Final Words
-We'd like to apologize in advance if we are not able to process and reply to your issue or PR right-away. We have a lot
-of work to do, but we are trying our best!
+We'd like to apologize in advance if we are not able to process and reply to your issue or PR right-away. We have a lot of work to do, but we are trying our best!
Thank you very much for your contributions!
diff --git a/.github/RELEASE.md b/.github/RELEASE.md
new file mode 100644
index 0000000000..2807667a30
--- /dev/null
+++ b/.github/RELEASE.md
@@ -0,0 +1,12 @@
+# Steps to a successful release
+
+1. Add all items to NEWS
+2. Update the contributors list in NEWS ("make git-contrib")
+3. Update the time and place in NEWS
+4. Update version in configure.ac and library numbers in Makefile.am
+5. Check that "make distcheck" works
+6. Tag the release ("make git-tag")
+7. Upload the documentation ("make doc-sync")
+8. Close the github milestone and open a new one (https://github.com/systemd/systemd/milestones)
+9. Send announcement to systemd-devel, with a copy&paste from NEWS
+10. Update IRC topic ("/msg chanserv TOPIC #systemd Version NNN released")
diff --git a/.gitignore b/.gitignore
index 091b400182..f7db68b4a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -217,6 +217,7 @@
/test-journal-stream
/test-journal-syslog
/test-journal-verify
+/test-keymap-util
/test-libsystemd-sym*
/test-libudev
/test-libudev-sym*
diff --git a/CODING_STYLE b/CODING_STYLE
index e762d42edb..f31d76f8ce 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -399,3 +399,10 @@
least initially), but it needs to be there. This is particularly important
for objects that unprivileged users may allocate, but also matters for
everything else any user may allocated.
+
+- htonl()/ntohl() and htons()/ntohs() are weird. Please use htobe32() and
+ htobe16() instead, it's much more descriptive, and actually says what really
+ is happening, after all htonl() and htons() don't operation on longs and
+ shorts as their name would suggest, but on uint32_t and uint16_t. Also,
+ "network byte order" is just a weird name for "big endian", hence we might
+ want to call it "big endian" right-away.
diff --git a/Makefile-man.am b/Makefile-man.am
index d5b328d267..cd7583bed7 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -31,11 +31,13 @@ MANPAGES += \
man/sd-id128.3 \
man/sd-journal.3 \
man/sd_booted.3 \
+ man/sd_bus_add_match.3 \
man/sd_bus_creds_get_pid.3 \
man/sd_bus_creds_new_from_pid.3 \
man/sd_bus_default.3 \
man/sd_bus_error.3 \
man/sd_bus_error_add_map.3 \
+ man/sd_bus_get_fd.3 \
man/sd_bus_message_append.3 \
man/sd_bus_message_append_array.3 \
man/sd_bus_message_append_basic.3 \
@@ -43,9 +45,11 @@ MANPAGES += \
man/sd_bus_message_append_strv.3 \
man/sd_bus_message_get_cookie.3 \
man/sd_bus_message_get_monotonic_usec.3 \
+ man/sd_bus_message_read_basic.3 \
man/sd_bus_negotiate_fds.3 \
man/sd_bus_new.3 \
man/sd_bus_path_encode.3 \
+ man/sd_bus_process.3 \
man/sd_bus_request_name.3 \
man/sd_event_add_child.3 \
man/sd_event_add_defer.3 \
@@ -2522,11 +2526,13 @@ EXTRA_DIST += \
man/sd-journal.xml \
man/sd-login.xml \
man/sd_booted.xml \
+ man/sd_bus_add_match.xml \
man/sd_bus_creds_get_pid.xml \
man/sd_bus_creds_new_from_pid.xml \
man/sd_bus_default.xml \
man/sd_bus_error.xml \
man/sd_bus_error_add_map.xml \
+ man/sd_bus_get_fd.xml \
man/sd_bus_message_append.xml \
man/sd_bus_message_append_array.xml \
man/sd_bus_message_append_basic.xml \
@@ -2534,9 +2540,11 @@ EXTRA_DIST += \
man/sd_bus_message_append_strv.xml \
man/sd_bus_message_get_cookie.xml \
man/sd_bus_message_get_monotonic_usec.xml \
+ man/sd_bus_message_read_basic.xml \
man/sd_bus_negotiate_fds.xml \
man/sd_bus_new.xml \
man/sd_bus_path_encode.xml \
+ man/sd_bus_process.xml \
man/sd_bus_request_name.xml \
man/sd_event_add_child.xml \
man/sd_event_add_defer.xml \
diff --git a/Makefile.am b/Makefile.am
index 528e0ced92..3c13acf28d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -141,6 +141,10 @@ else
noinst_PROGRAMS =
TESTS =
endif
+AM_TESTS_ENVIRONMENT = \
+ export SYSTEMD_KBD_MODEL_MAP=$(abs_top_srcdir)/src/locale/kbd-model-map; \
+ export SYSTEMD_LANGUAGE_FALLBACK_MAP=$(abs_top_srcdir)/src/locale/language-fallback-map;
+
if ENABLE_BASH_COMPLETION
dist_bashcompletion_DATA = $(dist_bashcompletion_data)
nodist_bashcompletion_DATA = $(nodist_bashcompletion_data)
@@ -213,6 +217,7 @@ AM_CPPFLAGS = \
-I $(top_srcdir)/src/shared \
-I $(top_builddir)/src/shared \
-I $(top_srcdir)/src/network \
+ -I $(top_srcdir)/src/locale \
-I $(top_srcdir)/src/login \
-I $(top_srcdir)/src/journal \
-I $(top_builddir)/src/journal \
@@ -2897,29 +2902,9 @@ systemd_gpt_auto_generator_CFLAGS = \
endif
# ------------------------------------------------------------------------------
-systemgenerator_PROGRAMS += \
- systemd-dbus1-generator
-
-systemd_dbus1_generator_SOURCES = \
- src/dbus1-generator/dbus1-generator.c
-
-systemd_dbus1_generator_LDADD = \
- libshared.la
-
-dbus1-generator-install-hook:
- $(AM_V_at)$(MKDIR_P) $(DESTDIR)$(usergeneratordir)
- $(AM_V_RM)rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
- $(AM_V_LN)$(LN_S) --relative -f $(DESTDIR)$(systemgeneratordir)/systemd-dbus1-generator $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
-
-dbus1-generator-uninstall-hook:
- rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
-
dist_xinitrc_SCRIPTS = \
xorg/50-systemd-user.sh
-INSTALL_EXEC_HOOKS += dbus1-generator-install-hook
-UNINSTALL_EXEC_HOOKS += dbus1-generator-uninstall-hook
-
# ------------------------------------------------------------------------------
systemd_sysv_generator_SOURCES = \
src/sysv-generator/sysv-generator.c
@@ -4746,7 +4731,9 @@ BUSNAMES_TARGET_WANTS += \
# ------------------------------------------------------------------------------
if ENABLE_LOCALED
systemd_localed_SOURCES = \
- src/locale/localed.c
+ src/locale/localed.c \
+ src/locale/keymap-util.c \
+ src/locale/keymap-util.h
systemd_localed_LDADD = \
libshared.la \
@@ -4784,6 +4771,18 @@ dist_pkgdata_DATA = \
src/locale/kbd-model-map \
src/locale/language-fallback-map
+test_keymap_util_SOURCES = \
+ src/locale/test-keymap-util.c \
+ src/locale/keymap-util.c \
+ src/locale/keymap-util.h
+
+test_keymap_util_LDADD = \
+ libshared.la \
+ -ldl
+
+tests += \
+ test-keymap-util
+
localectl_SOURCES = \
src/locale/localectl.c
@@ -5443,6 +5442,8 @@ libnetworkd_core_la_SOURCES = \
src/network/networkd-link.c \
src/network/networkd-netdev.h \
src/network/networkd-netdev.c \
+ src/network/networkd-netdev-vrf.h \
+ src/network/networkd-netdev-vrf.c \
src/network/networkd-netdev-tunnel.h \
src/network/networkd-netdev-tunnel.c \
src/network/networkd-netdev-veth.h \
@@ -6258,7 +6259,11 @@ hwdb-update:
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' && \
- ./ids-update.pl )
+ 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 )
.PHONY: built-sources
built-sources: $(BUILT_SOURCES)
diff --git a/TODO b/TODO
index aeed0c84d2..8de1029b9b 100644
--- a/TODO
+++ b/TODO
@@ -33,7 +33,7 @@ Janitorial Clean-ups:
Features:
-* use phyical_memory() to allow MemoryLimit= configuration based on available system memory
+* resolved: maybe add a switch to disable any local caching
* ProtectKernelLogs= (drops CAP_SYSLOG, add seccomp for syslog() syscall, and DeviceAllow to /dev/kmsg) in service files
@@ -47,6 +47,10 @@ Features:
* RestrictNamespaces= or so in services (taking away the ability to create namespaces, with setns, unshare, clone)
+* RestrictRealtime= which takes aware ability to create realtime processes
+
+* nspawn: make /proc/sys/net writable?
+
* make sure the ratelimit object can deal with USEC_INFINITY as way to turn off things
* journalctl: make sure -f ends when the container indicated by -M terminates
@@ -223,7 +227,6 @@ Features:
- resolved should optionally register additional per-interface LLMNR
names, so that for the container case we can establish the same name
(maybe "host") for referencing the server, everywhere.
- - enable DNSSEC by default
- allow clients to request DNSSEC for a single lookup even if DNSSEC is off (?)
* refcounting in sd-resolve is borked
diff --git a/autogen.sh b/autogen.sh
index 3a0695816e..4ec1b2be79 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -55,19 +55,19 @@ fi
cd $oldpwd
if [ "x$1" = "xc" ]; then
- $topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
+ $topdir/configure CFLAGS='-g -O0 -ftrapv' $args
make clean
elif [ "x$1" = "xg" ]; then
- $topdir/configure CFLAGS='-g -Og -ftrapv' --enable-kdbus $args
+ $topdir/configure CFLAGS='-g -Og -ftrapv' $args
make clean
elif [ "x$1" = "xa" ]; then
- $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-kdbus $args
+ $topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' $args
make clean
elif [ "x$1" = "xl" ]; then
- $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
+ $topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' $args
make clean
elif [ "x$1" = "xs" ]; then
- scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' --enable-kdbus $args
+ scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' $args
scan-build make
else
echo
@@ -75,6 +75,6 @@ else
echo "Initialized build system. For a common configuration please run:"
echo "----------------------------------------------------------------"
echo
- echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args"
+ echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' $args"
echo
fi
diff --git a/coccinelle/htonl.cocci b/coccinelle/htonl.cocci
new file mode 100644
index 0000000000..4e69bb7090
--- /dev/null
+++ b/coccinelle/htonl.cocci
@@ -0,0 +1,20 @@
+@@
+expression s;
+@@
+- htonl(s)
++ htobe32(s)
+@@
+expression s;
+@@
+- htons(s)
++ htobe16(s)
+@@
+expression s;
+@@
+- ntohl(s)
++ be32toh(s)
+@@
+expression s;
+@@
+- ntohs(s)
++ be16toh(s)
diff --git a/configure.ac b/configure.ac
index 329861a291..1326eebc6a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -249,6 +249,7 @@ AC_CHECK_SIZEOF(uid_t)
AC_CHECK_SIZEOF(gid_t)
AC_CHECK_SIZEOF(time_t)
AC_CHECK_SIZEOF(dev_t)
+AC_CHECK_SIZEOF(ino_t)
AC_CHECK_SIZEOF(rlim_t,,[
#include <sys/time.h>
#include <sys/resource.h>
@@ -324,6 +325,8 @@ AC_CHECK_TYPES([char16_t, char32_t, key_serial_t],
]])
AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE,
+ IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+ IFLA_VRF_TABLE,
IFLA_MACVLAN_FLAGS,
IFLA_IPVLAN_MODE,
IFLA_VTI_REMOTE,
@@ -1277,16 +1280,6 @@ AC_ARG_WITH(tpm-pcrindex,
AC_DEFINE_UNQUOTED(SD_TPM_PCR, [$SD_TPM_PCR], [TPM PCR register number to use])
# ------------------------------------------------------------------------------
-have_kdbus=no
-AC_ARG_ENABLE(kdbus, AS_HELP_STRING([--disable-kdbus], [do not connect to kdbus by default]))
-if test "x$enable_kdbus" != "xno"; then
- AC_DEFINE(ENABLE_KDBUS, 1, [Define if kdbus is to be connected to by default])
- have_kdbus=yes
- M4_DEFINES="$M4_DEFINES -DENABLE_KDBUS"
-fi
-AM_CONDITIONAL(ENABLE_KDBUS, [test "$have_kdbus" = "yes"])
-
-# ------------------------------------------------------------------------------
AC_ARG_WITH(rc-local-script-path-start,
AS_HELP_STRING([--with-rc-local-script-path-start=PATH],
[Path to /etc/rc.local]),
diff --git a/hwdb/.gitignore b/hwdb/.gitignore
index 00b977a3b5..c4796815d2 100644
--- a/hwdb/.gitignore
+++ b/hwdb/.gitignore
@@ -1,5 +1,8 @@
-/pci.ids
-/usb.ids
+/20-acpi-vendor.hwdb.base
+/acpi_id_registry.html
/ma-large.txt
/ma-medium.txt
/ma-small.txt
+/pci.ids
+/pnp_id_registry.html
+/usb.ids
diff --git a/hwdb/20-acpi-vendor.hwdb b/hwdb/20-acpi-vendor.hwdb
index 9b3b0094d5..4ae652c6d6 100644
--- a/hwdb/20-acpi-vendor.hwdb
+++ b/hwdb/20-acpi-vendor.hwdb
@@ -1,15 +1,230 @@
# This file is part of systemd.
#
# Data imported from:
-# http://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/ISA_PNPID_List.xlsx
-# Non-unique, duplicate assignements manually removed.
+# http://www.uefi.org/uefi-pnp-export
+# http://www.uefi.org/uefi-acpi-export
+#
+# With various additions from other sources
+
+acpi:3NOD*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group)
+
+acpi:AAVA*:
+ ID_VENDOR_FROM_DATABASE=Aava Mobile Oy
+
+acpi:AMDI*:
+ ID_VENDOR_FROM_DATABASE=AMD
+
+acpi:APMC*:
+ ID_VENDOR_FROM_DATABASE=Applied Micro Circuits Corporation
+
+acpi:APTA*:
+ ID_VENDOR_FROM_DATABASE=Aptina Imaging Corporation
+
+acpi:ARMH*:
+ ID_VENDOR_FROM_DATABASE=ARM Ltd.
+
+acpi:ARML*:
+ ID_VENDOR_FROM_DATABASE=ARM Ltd.
+
+acpi:ASUS*:
+ ID_VENDOR_FROM_DATABASE=ASUS
+
+acpi:ATML*:
+ ID_VENDOR_FROM_DATABASE=Atmel
+
+acpi:AUTH*:
+ ID_VENDOR_FROM_DATABASE=AuthenTec
+
+acpi:BOSC*:
+ ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH
+
+acpi:BRCM*:
+ ID_VENDOR_FROM_DATABASE=Broadcom Corporation
+
+acpi:CPLM*:
+ ID_VENDOR_FROM_DATABASE=Capella Microsystems Inc.
+
+acpi:DELL*:
+ ID_VENDOR_FROM_DATABASE=Dell, Inc.
+
+acpi:DLGS*:
+ ID_VENDOR_FROM_DATABASE=Dialog Semiconductor PLC
+
+acpi:DLLK*:
+ ID_VENDOR_FROM_DATABASE=Dell, Inc.
+
+acpi:DSUO*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen DSO Microelectronics Co.,Ltd.
+
+acpi:ELAN*:
+ ID_VENDOR_FROM_DATABASE=ELAN MICROELECTRONICS CORPORATION
+
+acpi:ESSX*:
+ ID_VENDOR_FROM_DATABASE=Everest Semiconductor Co., Ltd.
+
+acpi:FRSC*:
+ ID_VENDOR_FROM_DATABASE=Freescale, Inc
+
+acpi:FTSC*:
+ ID_VENDOR_FROM_DATABASE=FocalTech Systems Co., Ltd.
+
+acpi:GOOG*:
+ ID_VENDOR_FROM_DATABASE=Google, Inc.
+
+acpi:HIMX*:
+ ID_VENDOR_FROM_DATABASE=Himax Technologies, Inc.
+
+acpi:HISI*:
+ ID_VENDOR_FROM_DATABASE=HiSilicon Technologies Co., Ltd.
+
+acpi:HPIC*:
+ ID_VENDOR_FROM_DATABASE=HP Inc.
+
+acpi:HPQC*:
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Company
+
+acpi:HTLM*:
+ ID_VENDOR_FROM_DATABASE=HTBLuVA Mödling
+
+acpi:HWPE*:
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard Enterprise
+
+acpi:IBMX*:
+ ID_VENDOR_FROM_DATABASE=IBM
+
+acpi:IDEA*:
+ ID_VENDOR_FROM_DATABASE=Lenovo Beijing Co. Ltd.
+
+acpi:IMPJ*:
+ ID_VENDOR_FROM_DATABASE=Impinj
+
+acpi:INTC*:
+ ID_VENDOR_FROM_DATABASE=Intel Corporation
+
+acpi:INTL*:
+ ID_VENDOR_FROM_DATABASE=Intel Corporation
+
+acpi:INVN*:
+ ID_VENDOR_FROM_DATABASE=Invensense, Inc
+
+acpi:IP3T*:
+ ID_VENDOR_FROM_DATABASE=IP3 Technology Ltd.
+
+acpi:IPHI*:
+ ID_VENDOR_FROM_DATABASE=Inphi Corporation
+
+acpi:KIOX*:
+ ID_VENDOR_FROM_DATABASE=Kionix, Inc.
+
+acpi:LNRO*:
+ ID_VENDOR_FROM_DATABASE=Linaro, Ltd.
+
+acpi:LNUX*:
+ ID_VENDOR_FROM_DATABASE=The Linux Foundation
+
+acpi:MIPI*:
+ ID_VENDOR_FROM_DATABASE=MIPI Alliance
+
+acpi:MSAY*:
+ ID_VENDOR_FROM_DATABASE=Microsoft Corporation
+
+acpi:MSFT*:
+ ID_VENDOR_FROM_DATABASE=Microsoft Corporation
+
+acpi:MSHW*:
+ ID_VENDOR_FROM_DATABASE=Microsoft Corporation
+
+acpi:MXIM*:
+ ID_VENDOR_FROM_DATABASE=Maxim Integrated
+
+acpi:NVDA*:
+ ID_VENDOR_FROM_DATABASE=Nvidia
+
+acpi:NVTN*:
+ ID_VENDOR_FROM_DATABASE=Nuvoton Technology Corporation
+
+acpi:OBDA*:
+ ID_VENDOR_FROM_DATABASE=REALTEK Semiconductor Corp.
+
+acpi:OMPS*:
+ ID_VENDOR_FROM_DATABASE=OmniPreSense
+
+acpi:OVTI*:
+ ID_VENDOR_FROM_DATABASE=OmniVision Technologies, Inc.
+
+acpi:PEGA*:
+ ID_VENDOR_FROM_DATABASE=Pegatron Corporation
+
+acpi:QCOM*:
+ ID_VENDOR_FROM_DATABASE=Qualcomm Inc
+
+acpi:QEMU*:
+ ID_VENDOR_FROM_DATABASE=Red Hat, Inc.
+
+acpi:RAYD*:
+ ID_VENDOR_FROM_DATABASE=Raydium Semiconductor Corporation
+
+acpi:RKCP*:
+ ID_VENDOR_FROM_DATABASE=Fuzhou Rockchip Electronics Co., Ltd.
+
+acpi:RZSN*:
+ ID_VENDOR_FROM_DATABASE=Rozsnyó, s.r.o.
+
+acpi:SHRP*:
+ ID_VENDOR_FROM_DATABASE=Sharp Corporation
+
+acpi:SONY*:
+ ID_VENDOR_FROM_DATABASE=Sony Corporation
+
+acpi:ST86*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen South-Top Computer Co., Ltd.
+
+acpi:SWEM*:
+ ID_VENDOR_FROM_DATABASE=Sierra Wireless
+
+acpi:SYNA*:
+ ID_VENDOR_FROM_DATABASE=Synaptics Inc
+
+acpi:TCAG*:
+ ID_VENDOR_FROM_DATABASE=Teracue AG
+
+acpi:TOSB*:
+ ID_VENDOR_FROM_DATABASE=Toshiba Corporation
+
+acpi:TXNW*:
+ ID_VENDOR_FROM_DATABASE=Texas Instruments
+
+acpi:UBLX*:
+ ID_VENDOR_FROM_DATABASE=u-blox AG
+
+acpi:VAIO*:
+ ID_VENDOR_FROM_DATABASE=VAIO Corporation
+
+acpi:VFSI*:
+ ID_VENDOR_FROM_DATABASE=Validity Sensors, Inc
+
+acpi:WCOM*:
+ ID_VENDOR_FROM_DATABASE=Wacom
+
+acpi:WSDR*:
+ ID_VENDOR_FROM_DATABASE=Winsider Seminars & Solutions Inc.
+
+acpi:XMCC*:
+ ID_VENDOR_FROM_DATABASE=Xiaomi Inc.
acpi:AAA*:
ID_VENDOR_FROM_DATABASE=Avolites Ltd
+acpi:AAC*:
+ ID_VENDOR_FROM_DATABASE=AcerView
+
acpi:AAE*:
ID_VENDOR_FROM_DATABASE=Anatek Electronics Inc.
+acpi:AAM*:
+ ID_VENDOR_FROM_DATABASE=Aava Mobile Oy
+
acpi:AAT*:
ID_VENDOR_FROM_DATABASE=Ann Arbor Technologies
@@ -17,7 +232,7 @@ acpi:ABA*:
ID_VENDOR_FROM_DATABASE=ABBAHOME INC.
acpi:ABC*:
- ID_VENDOR_FROM_DATABASE=AboCom System Inc
+ ID_VENDOR_FROM_DATABASE=AboCom System Inc.
acpi:ABD*:
ID_VENDOR_FROM_DATABASE=Allen Bradley Company
@@ -28,6 +243,12 @@ acpi:ABE*:
acpi:ABO*:
ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
+acpi:ABP*:
+ ID_VENDOR_FROM_DATABASE=Advansys
+
+acpi:ABS*:
+ ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
+
acpi:ABT*:
ID_VENDOR_FROM_DATABASE=Anchor Bay Technologies, Inc.
@@ -50,7 +271,7 @@ acpi:ACE*:
ID_VENDOR_FROM_DATABASE=Actek Engineering Pty Ltd
acpi:ACG*:
- ID_VENDOR_FROM_DATABASE=A&R Cambridge Ltd
+ ID_VENDOR_FROM_DATABASE=A&R Cambridge Ltd.
acpi:ACH*:
ID_VENDOR_FROM_DATABASE=Archtek Telecom Corporation
@@ -131,7 +352,7 @@ acpi:ADS*:
ID_VENDOR_FROM_DATABASE=Analog Devices Inc
acpi:ADT*:
- ID_VENDOR_FROM_DATABASE=Aved Display Technologies
+ ID_VENDOR_FROM_DATABASE=Adtek
acpi:ADV*:
ID_VENDOR_FROM_DATABASE=Advanced Micro Devices Inc
@@ -139,6 +360,9 @@ acpi:ADV*:
acpi:ADX*:
ID_VENDOR_FROM_DATABASE=Adax Inc
+acpi:ADZ*:
+ ID_VENDOR_FROM_DATABASE=ADDER TECHNOLOGY LTD
+
acpi:AEC*:
ID_VENDOR_FROM_DATABASE=Antex Electronics Corporation
@@ -178,12 +402,18 @@ acpi:AGL*:
acpi:AGM*:
ID_VENDOR_FROM_DATABASE=Advan Int'l Corporation
+acpi:AGO*:
+ ID_VENDOR_FROM_DATABASE=AlgolTek, Inc.
+
acpi:AGT*:
ID_VENDOR_FROM_DATABASE=Agilent Technologies
acpi:AHC*:
ID_VENDOR_FROM_DATABASE=Advantech Co., Ltd.
+acpi:AHS*:
+ ID_VENDOR_FROM_DATABASE=Beijing AnHeng SecoTech Information Technology Co., Ltd.
+
acpi:AIC*:
ID_VENDOR_FROM_DATABASE=Arnos Insturments & Computer Systems
@@ -193,6 +423,9 @@ acpi:AIE*:
acpi:AII*:
ID_VENDOR_FROM_DATABASE=Amptron International Inc.
+acpi:AIK*:
+ ID_VENDOR_FROM_DATABASE=Dongguan Alllike Electronics Co., Ltd.
+
acpi:AIL*:
ID_VENDOR_FROM_DATABASE=Altos India Ltd
@@ -244,6 +477,9 @@ acpi:ALC*:
acpi:ALD*:
ID_VENDOR_FROM_DATABASE=In4S Inc
+acpi:ALE*:
+ ID_VENDOR_FROM_DATABASE=Alenco BV
+
acpi:ALG*:
ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Corp.
@@ -316,12 +552,18 @@ acpi:AMO*:
acpi:AMP*:
ID_VENDOR_FROM_DATABASE=AMP Inc
-acpi:AMS *:
+acpi:AMR*:
+ ID_VENDOR_FROM_DATABASE=AmTRAN Technology Co., Ltd.
+
+acpi:AMS*:
ID_VENDOR_FROM_DATABASE=ARMSTEL, Inc.
acpi:AMT*:
ID_VENDOR_FROM_DATABASE=AMT International Industry
+acpi:AMW*:
+ ID_VENDOR_FROM_DATABASE=AMW
+
acpi:AMX*:
ID_VENDOR_FROM_DATABASE=AMX LLC
@@ -358,12 +600,21 @@ acpi:ANS*:
acpi:ANT*:
ID_VENDOR_FROM_DATABASE=Ace CAD Enterprise Company Ltd
+acpi:ANV*:
+ ID_VENDOR_FROM_DATABASE=Beijing ANTVR Technology Co., Ltd.
+
+acpi:ANW*:
+ ID_VENDOR_FROM_DATABASE=Analog Way SAS
+
acpi:ANX*:
ID_VENDOR_FROM_DATABASE=Acer Netxus Inc
acpi:AOA*:
ID_VENDOR_FROM_DATABASE=AOpen Inc.
+acpi:AOC*:
+ ID_VENDOR_FROM_DATABASE=AOC
+
acpi:AOE*:
ID_VENDOR_FROM_DATABASE=Advanced Optics Electronics, Inc.
@@ -373,12 +624,18 @@ acpi:AOL*:
acpi:AOT*:
ID_VENDOR_FROM_DATABASE=Alcatel
+acpi:APA*:
+ ID_VENDOR_FROM_DATABASE=Adaptec
+
acpi:APC*:
ID_VENDOR_FROM_DATABASE=American Power Conversion
acpi:APD*:
ID_VENDOR_FROM_DATABASE=AppliAdata
+acpi:APE*:
+ ID_VENDOR_FROM_DATABASE=Alpine Electronics, Inc.
+
acpi:APG*:
ID_VENDOR_FROM_DATABASE=Horner Electric Inc
@@ -415,6 +672,9 @@ acpi:APX*:
acpi:ARC*:
ID_VENDOR_FROM_DATABASE=Alta Research Corporation
+acpi:ARD*:
+ ID_VENDOR_FROM_DATABASE=AREC Inc.
+
acpi:ARE*:
ID_VENDOR_FROM_DATABASE=ICET S.p.A.
@@ -436,6 +696,9 @@ acpi:ARM*:
acpi:ARO*:
ID_VENDOR_FROM_DATABASE=Poso International B.V.
+acpi:ARR*:
+ ID_VENDOR_FROM_DATABASE=ARRIS Group, Inc.
+
acpi:ARS*:
ID_VENDOR_FROM_DATABASE=Arescom Inc
@@ -451,6 +714,9 @@ acpi:ASD*:
acpi:ASE*:
ID_VENDOR_FROM_DATABASE=AseV Display Labs
+acpi:ASH*:
+ ID_VENDOR_FROM_DATABASE=Ashton Bentley Concepts
+
acpi:ASI*:
ID_VENDOR_FROM_DATABASE=Ahead Systems
@@ -499,6 +765,9 @@ acpi:ATH*:
acpi:ATI*:
ID_VENDOR_FROM_DATABASE=Allied Telesis KK
+acpi:ATJ*:
+ ID_VENDOR_FROM_DATABASE=ArchiTek Corporation
+
acpi:ATK*:
ID_VENDOR_FROM_DATABASE=Allied Telesyn Int'l
@@ -526,15 +795,27 @@ acpi:ATV*:
acpi:ATX*:
ID_VENDOR_FROM_DATABASE=Athenix Corporation
+acpi:AUG*:
+ ID_VENDOR_FROM_DATABASE=August Home, Inc.
+
acpi:AUI*:
ID_VENDOR_FROM_DATABASE=Alps Electric Inc
+acpi:AUO*:
+ ID_VENDOR_FROM_DATABASE=AU Optronics
+
acpi:AUR*:
ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
+acpi:AUS*:
+ ID_VENDOR_FROM_DATABASE=ASUSTek COMPUTER INC
+
acpi:AUT*:
ID_VENDOR_FROM_DATABASE=Autotime Corporation
+acpi:AUV*:
+ ID_VENDOR_FROM_DATABASE=Auvidea GmbH
+
acpi:AVA*:
ID_VENDOR_FROM_DATABASE=Avaya Communication
@@ -547,16 +828,22 @@ acpi:AVD*:
acpi:AVE*:
ID_VENDOR_FROM_DATABASE=Add Value Enterpises (Asia) Pte Ltd
+acpi:AVG*:
+ ID_VENDOR_FROM_DATABASE=Avegant Corporation
+
acpi:AVI*:
ID_VENDOR_FROM_DATABASE=Nippon Avionics Co.,Ltd
+acpi:AVJ*:
+ ID_VENDOR_FROM_DATABASE=Atelier Vision Corporation
+
acpi:AVL*:
ID_VENDOR_FROM_DATABASE=Avalue Technology Inc.
acpi:AVM*:
ID_VENDOR_FROM_DATABASE=AVM GmbH
-acpi:AVN *:
+acpi:AVN*:
ID_VENDOR_FROM_DATABASE=Advance Computer Corporation
acpi:AVO*:
@@ -571,6 +858,9 @@ acpi:AVT*:
acpi:AVV*:
ID_VENDOR_FROM_DATABASE=SBS Technologies (Canada), Inc. (was Avvida Systems, Inc.)
+acpi:AVX*:
+ ID_VENDOR_FROM_DATABASE=A/Vaux Electronics
+
acpi:AWC*:
ID_VENDOR_FROM_DATABASE=Access Works Comm Inc
@@ -587,7 +877,7 @@ acpi:AXC*:
ID_VENDOR_FROM_DATABASE=AXIOMTEK CO., LTD.
acpi:AXE*:
- ID_VENDOR_FROM_DATABASE=D-Link Systems Inc (used as 2nd pnpid)
+ ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
acpi:AXI*:
ID_VENDOR_FROM_DATABASE=American Magnetics
@@ -616,6 +906,9 @@ acpi:AYD*:
acpi:AYR*:
ID_VENDOR_FROM_DATABASE=Airlib, Inc
+acpi:AZH*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group)
+
acpi:AZM*:
ID_VENDOR_FROM_DATABASE=AZ Middelheim - Radiotherapy
@@ -643,6 +936,9 @@ acpi:BCC*:
acpi:BCD*:
ID_VENDOR_FROM_DATABASE=Barco GmbH
+acpi:BCI*:
+ ID_VENDOR_FROM_DATABASE=Broadata Communications Inc.
+
acpi:BCM*:
ID_VENDOR_FROM_DATABASE=Broadcom
@@ -662,7 +958,7 @@ acpi:BDS*:
ID_VENDOR_FROM_DATABASE=Barco Display Systems
acpi:BEC*:
- ID_VENDOR_FROM_DATABASE=Elektro Beckhoff GmbH
+ ID_VENDOR_FROM_DATABASE=Beckhoff Automation
acpi:BEI*:
ID_VENDOR_FROM_DATABASE=Beckworth Enterprises Inc
@@ -688,6 +984,9 @@ acpi:BGT*:
acpi:BHZ*:
ID_VENDOR_FROM_DATABASE=BitHeadz, Inc.
+acpi:BIA*:
+ ID_VENDOR_FROM_DATABASE=Biamp Systems Corporation
+
acpi:BIC*:
ID_VENDOR_FROM_DATABASE=Big Island Communications
@@ -712,12 +1011,18 @@ acpi:BLN*:
acpi:BLP*:
ID_VENDOR_FROM_DATABASE=Bloomberg L.P.
+acpi:BMD*:
+ ID_VENDOR_FROM_DATABASE=Blackmagic Design
+
acpi:BMI*:
ID_VENDOR_FROM_DATABASE=Benson Medical Instruments Company
acpi:BML*:
ID_VENDOR_FROM_DATABASE=BIOMED Lab
+acpi:BMM*:
+ ID_VENDOR_FROM_DATABASE=BMM
+
acpi:BMS*:
ID_VENDOR_FROM_DATABASE=BIOMEDISYS
@@ -730,6 +1035,9 @@ acpi:BNK*:
acpi:BNO*:
ID_VENDOR_FROM_DATABASE=Bang & Olufsen
+acpi:BNQ*:
+ ID_VENDOR_FROM_DATABASE=BenQ Corporation
+
acpi:BNS*:
ID_VENDOR_FROM_DATABASE=Boulder Nonlinear Systems
@@ -748,6 +1056,9 @@ acpi:BOS*:
acpi:BPD*:
ID_VENDOR_FROM_DATABASE=Micro Solutions, Inc.
+acpi:BPS*:
+ ID_VENDOR_FROM_DATABASE=Barco, N.V.
+
acpi:BPU*:
ID_VENDOR_FROM_DATABASE=Best Power
@@ -772,6 +1083,9 @@ acpi:BRO*:
acpi:BSE*:
ID_VENDOR_FROM_DATABASE=Bose Corporation
+acpi:BSG*:
+ ID_VENDOR_FROM_DATABASE=Robert Bosch GmbH
+
acpi:BSL*:
ID_VENDOR_FROM_DATABASE=Biomedical Systems Laboratory
@@ -1114,6 +1428,9 @@ acpi:COB*:
acpi:COD*:
ID_VENDOR_FROM_DATABASE=CODAN Pty. Ltd.
+acpi:COG*:
+ ID_VENDOR_FROM_DATABASE=Cogent
+
acpi:COI*:
ID_VENDOR_FROM_DATABASE=Codec Inc.
@@ -1159,6 +1476,9 @@ acpi:CPL*:
acpi:CPM*:
ID_VENDOR_FROM_DATABASE=Capella Microsystems Inc.
+acpi:CPP*:
+ ID_VENDOR_FROM_DATABASE=Compound Photonics
+
acpi:CPQ*:
ID_VENDOR_FROM_DATABASE=Compaq Computer Company
@@ -1168,6 +1488,9 @@ acpi:CPT*:
acpi:CPX*:
ID_VENDOR_FROM_DATABASE=Powermatic Data Systems
+acpi:CRA*:
+ ID_VENDOR_FROM_DATABASE=CRALTECH ELECTRONICA, S.L.
+
acpi:CRC*:
ID_VENDOR_FROM_DATABASE=CONRAC GmbH
@@ -1177,11 +1500,14 @@ acpi:CRD*:
acpi:CRE*:
ID_VENDOR_FROM_DATABASE=Creative Labs Inc
+acpi:CRH*:
+ ID_VENDOR_FROM_DATABASE=Contemporary Research Corp.
+
acpi:CRI*:
ID_VENDOR_FROM_DATABASE=Crio Inc.
acpi:CRL*:
- ID_VENDOR_FROM_DATABASE=Creative Logic  
+ ID_VENDOR_FROM_DATABASE=Creative Logic
acpi:CRN*:
ID_VENDOR_FROM_DATABASE=Cornerstone Imaging
@@ -1216,6 +1542,9 @@ acpi:CSE*:
acpi:CSI*:
ID_VENDOR_FROM_DATABASE=Cabletron System Inc
+acpi:CSL*:
+ ID_VENDOR_FROM_DATABASE=Cloudium Systems Ltd.
+
acpi:CSM*:
ID_VENDOR_FROM_DATABASE=Cosmic Engineering Inc.
@@ -1249,6 +1578,9 @@ acpi:CTN*:
acpi:CTP*:
ID_VENDOR_FROM_DATABASE=Computer Technology Corporation
+acpi:CTR*:
+ ID_VENDOR_FROM_DATABASE=Control4 Corporation
+
acpi:CTS*:
ID_VENDOR_FROM_DATABASE=Comtec Systems Co., Ltd.
@@ -1264,9 +1596,18 @@ acpi:CUK*:
acpi:CVA*:
ID_VENDOR_FROM_DATABASE=Covia Inc.
+acpi:CVI*:
+ ID_VENDOR_FROM_DATABASE=Colorado Video, Inc.
+
+acpi:CVP*:
+ ID_VENDOR_FROM_DATABASE=Chromatec Video Products Ltd
+
acpi:CVS*:
ID_VENDOR_FROM_DATABASE=Clarity Visual Systems
+acpi:CWC*:
+ ID_VENDOR_FROM_DATABASE=Curtiss-Wright Controls, Inc.
+
acpi:CWR*:
ID_VENDOR_FROM_DATABASE=Connectware Inc
@@ -1285,6 +1626,9 @@ acpi:CYD*:
acpi:CYL*:
ID_VENDOR_FROM_DATABASE=Cyberlabs
+acpi:CYP*:
+ ID_VENDOR_FROM_DATABASE=CYPRESS SEMICONDUCTOR CORPORATION
+
acpi:CYT*:
ID_VENDOR_FROM_DATABASE=Cytechinfo Inc
@@ -1297,6 +1641,9 @@ acpi:CYW*:
acpi:CYX*:
ID_VENDOR_FROM_DATABASE=Cyrix Corporation
+acpi:CZC*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen ChuangZhiCheng Technology Co., Ltd.
+
acpi:CZE*:
ID_VENDOR_FROM_DATABASE=Carl Zeiss AG
@@ -1400,7 +1747,7 @@ acpi:DDI*:
ID_VENDOR_FROM_DATABASE=Data Display AG
acpi:DDS*:
- ID_VENDOR_FROM_DATABASE=Barco, n.v.
+ ID_VENDOR_FROM_DATABASE=Barco, N.V.
acpi:DDT*:
ID_VENDOR_FROM_DATABASE=Datadesk Technologies Inc
@@ -1451,7 +1798,10 @@ acpi:DGS*:
ID_VENDOR_FROM_DATABASE=Diagsoft Inc
acpi:DGT*:
- ID_VENDOR_FROM_DATABASE=The Dearborn Group
+ ID_VENDOR_FROM_DATABASE=Dearborn Group Technology
+
+acpi:DHD*:
+ ID_VENDOR_FROM_DATABASE=Dension Audio Systems
acpi:DHP*:
ID_VENDOR_FROM_DATABASE=DH Print
@@ -1519,6 +1869,9 @@ acpi:DMC*:
acpi:DMM*:
ID_VENDOR_FROM_DATABASE=Dimond Multimedia Systems Inc
+acpi:DMO*:
+ ID_VENDOR_FROM_DATABASE=Data Modul AG
+
acpi:DMP*:
ID_VENDOR_FROM_DATABASE=D&M Holdings Inc, Professional Business Company
@@ -1564,6 +1917,9 @@ acpi:DPA*:
acpi:DPC*:
ID_VENDOR_FROM_DATABASE=Delta Electronics Inc
+acpi:DPH*:
+ ID_VENDOR_FROM_DATABASE=Delphi Automotive LLP
+
acpi:DPI*:
ID_VENDOR_FROM_DATABASE=DocuPoint
@@ -1600,6 +1956,9 @@ acpi:DRI*:
acpi:DRS*:
ID_VENDOR_FROM_DATABASE=DRS Defense Solutions, LLC
+acpi:DSA*:
+ ID_VENDOR_FROM_DATABASE=Display Solution AG
+
acpi:DSD*:
ID_VENDOR_FROM_DATABASE=DS Multimedia Pte Ltd
@@ -1631,7 +1990,7 @@ acpi:DTL*:
ID_VENDOR_FROM_DATABASE=e-Net Inc
acpi:DTN*:
- ID_VENDOR_FROM_DATABASE=Datang Telephone Co
+ ID_VENDOR_FROM_DATABASE=Datang Telephone Co
acpi:DTO*:
ID_VENDOR_FROM_DATABASE=Deutsche Thomson OHG
@@ -1690,12 +2049,18 @@ acpi:DYN*:
acpi:DYX*:
ID_VENDOR_FROM_DATABASE=Dynax Electronics (HK) Ltd
+acpi:EAG*:
+ ID_VENDOR_FROM_DATABASE=ELTEC Elektronik AG
+
acpi:EAS*:
ID_VENDOR_FROM_DATABASE=Evans and Sutherland Computer
acpi:EBH*:
ID_VENDOR_FROM_DATABASE=Data Price Informatica
+acpi:EBS*:
+ ID_VENDOR_FROM_DATABASE=EBS Euchner Büro- und Schulsysteme GmbH
+
acpi:EBT*:
ID_VENDOR_FROM_DATABASE=HUALONG TECHNOLOGY CO., LTD
@@ -1705,6 +2070,9 @@ acpi:ECA*:
acpi:ECC*:
ID_VENDOR_FROM_DATABASE=ESSential Comm. Corporation
+acpi:ECH*:
+ ID_VENDOR_FROM_DATABASE=EchoStar Corporation
+
acpi:ECI*:
ID_VENDOR_FROM_DATABASE=Enciris Technologies
@@ -1780,6 +2148,9 @@ acpi:EHN*:
acpi:EIC*:
ID_VENDOR_FROM_DATABASE=Eicon Technology Corporation
+acpi:EIZ*:
+ ID_VENDOR_FROM_DATABASE=Eizo
+
acpi:EKA*:
ID_VENDOR_FROM_DATABASE=MagTek Inc.
@@ -1819,6 +2190,9 @@ acpi:ELS*:
acpi:ELT*:
ID_VENDOR_FROM_DATABASE=Element Labs, Inc.
+acpi:ELU*:
+ ID_VENDOR_FROM_DATABASE=Express Industrial, Ltd.
+
acpi:ELX*:
ID_VENDOR_FROM_DATABASE=Elonex PLC
@@ -1828,6 +2202,9 @@ acpi:EMB*:
acpi:EMC*:
ID_VENDOR_FROM_DATABASE=eMicro Corporation
+acpi:EMD*:
+ ID_VENDOR_FROM_DATABASE=Embrionix Design Inc.
+
acpi:EME*:
ID_VENDOR_FROM_DATABASE=EMiNE TECHNOLOGY COMPANY, LTD.
@@ -1864,11 +2241,14 @@ acpi:ENS*:
acpi:ENT*:
ID_VENDOR_FROM_DATABASE=Enterprise Comm. & Computing Inc
+acpi:EON*:
+ ID_VENDOR_FROM_DATABASE=Eon Instrumentation, Inc.
+
acpi:EPC*:
ID_VENDOR_FROM_DATABASE=Empac
-acpi:EPH *:
- ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc. 
+acpi:EPH*:
+ ID_VENDOR_FROM_DATABASE=Epiphan Systems Inc.
acpi:EPI*:
ID_VENDOR_FROM_DATABASE=Envision Peripherals, Inc
@@ -1897,12 +2277,18 @@ acpi:ERN*:
acpi:ERP*:
ID_VENDOR_FROM_DATABASE=Euraplan GmbH
+acpi:ERS*:
+ ID_VENDOR_FROM_DATABASE=Eizo Rugged Solutions
+
acpi:ERT*:
ID_VENDOR_FROM_DATABASE=Escort Insturments Corporation
acpi:ESA*:
ID_VENDOR_FROM_DATABASE=Elbit Systems of America
+acpi:ESB*:
+ ID_VENDOR_FROM_DATABASE=Esterline Belgium BVBA
+
acpi:ESC*:
ID_VENDOR_FROM_DATABASE=Eden Sistemas de Computacao S/A
@@ -1984,6 +2370,9 @@ acpi:EXN*:
acpi:EXP*:
ID_VENDOR_FROM_DATABASE=Data Export Corporation
+acpi:EXR*:
+ ID_VENDOR_FROM_DATABASE=Explorer Inc.
+
acpi:EXT*:
ID_VENDOR_FROM_DATABASE=Exatech Computadores & Servicos Ltda
@@ -1996,12 +2385,18 @@ acpi:EXY*:
acpi:EYE*:
ID_VENDOR_FROM_DATABASE=eyevis GmbH
+acpi:EYF*:
+ ID_VENDOR_FROM_DATABASE=eyefactive Gmbh
+
acpi:EZE*:
ID_VENDOR_FROM_DATABASE=EzE Technologies
acpi:EZP*:
ID_VENDOR_FROM_DATABASE=Storm Technology
+acpi:FAN*:
+ ID_VENDOR_FROM_DATABASE=Fantalooks Co., Ltd.
+
acpi:FAR*:
ID_VENDOR_FROM_DATABASE=Farallon Computing
@@ -2014,12 +2409,21 @@ acpi:FCB*:
acpi:FCG*:
ID_VENDOR_FROM_DATABASE=First International Computer Ltd
+acpi:FCM*:
+ ID_VENDOR_FROM_DATABASE=Funai
+
acpi:FCS*:
ID_VENDOR_FROM_DATABASE=Focus Enhancements, Inc.
acpi:FDC*:
ID_VENDOR_FROM_DATABASE=Future Domain
+acpi:FDD*:
+ ID_VENDOR_FROM_DATABASE=Forth Dimension Displays Ltd
+
+acpi:FDI*:
+ ID_VENDOR_FROM_DATABASE=Future Designs, Inc.
+
acpi:FDT*:
ID_VENDOR_FROM_DATABASE=Fujitsu Display Technologies Corp.
@@ -2093,7 +2497,7 @@ acpi:FMC*:
ID_VENDOR_FROM_DATABASE=Ford Microelectronics Inc
acpi:FMI*:
- ID_VENDOR_FROM_DATABASE=Fujitsu Microelect Inc
+ ID_VENDOR_FROM_DATABASE=Fellowes, Inc.
acpi:FML*:
ID_VENDOR_FROM_DATABASE=Fujitsu Microelect Ltd
@@ -2110,12 +2514,18 @@ acpi:FNI*:
acpi:FOA*:
ID_VENDOR_FROM_DATABASE=FOR-A Company Limited
+acpi:FOK*:
+ ID_VENDOR_FROM_DATABASE=Fokus Technologies GmbH
+
acpi:FOS*:
ID_VENDOR_FROM_DATABASE=Foss Tecator
acpi:FOX*:
ID_VENDOR_FROM_DATABASE=HON HAI PRECISON IND.CO.,LTD.
+acpi:FPC*:
+ ID_VENDOR_FROM_DATABASE=Fingerprint Cards AB
+
acpi:FPE*:
ID_VENDOR_FROM_DATABASE=Fujitsu Peripherals Ltd
@@ -2137,6 +2547,9 @@ acpi:FRE*:
acpi:FRI*:
ID_VENDOR_FROM_DATABASE=Fibernet Research Inc
+acpi:FRO*:
+ ID_VENDOR_FROM_DATABASE=FARO Technologies
+
acpi:FRS*:
ID_VENDOR_FROM_DATABASE=South Mountain Technologies, LTD
@@ -2170,6 +2583,9 @@ acpi:FTN*:
acpi:FTR*:
ID_VENDOR_FROM_DATABASE=Mediasonic
+acpi:FTS*:
+ ID_VENDOR_FROM_DATABASE=FocalTech Systems Co., Ltd.
+
acpi:FTW*:
ID_VENDOR_FROM_DATABASE=MindTribe Product Engineering, Inc.
@@ -2203,6 +2619,9 @@ acpi:FZC*:
acpi:FZI*:
ID_VENDOR_FROM_DATABASE=FZI Forschungszentrum Informatik
+acpi:GAC*:
+ ID_VENDOR_FROM_DATABASE=GreenArrays, Inc.
+
acpi:GAG*:
ID_VENDOR_FROM_DATABASE=Gage Applied Sciences Inc
@@ -2233,11 +2652,17 @@ acpi:GDS*:
acpi:GDT*:
ID_VENDOR_FROM_DATABASE=Vortex Computersysteme GmbH
+acpi:GEC*:
+ ID_VENDOR_FROM_DATABASE=Gechic Corporation
+
+acpi:GED*:
+ ID_VENDOR_FROM_DATABASE=General Dynamics C4 Systems
+
acpi:GEF*:
ID_VENDOR_FROM_DATABASE=GE Fanuc Embedded Systems
acpi:GEH*:
- ID_VENDOR_FROM_DATABASE=GE Intelligent Platforms - Huntsville
+ ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
acpi:GEM*:
ID_VENDOR_FROM_DATABASE=Gem Plus
@@ -2317,6 +2742,12 @@ acpi:GNN*:
acpi:GNZ*:
ID_VENDOR_FROM_DATABASE=Gunze Ltd
+acpi:GOE*:
+ ID_VENDOR_FROM_DATABASE=GOEPEL electronic GmbH
+
+acpi:GPR*:
+ ID_VENDOR_FROM_DATABASE=GoPro, Inc.
+
acpi:GRA*:
ID_VENDOR_FROM_DATABASE=Graphica Computer
@@ -2344,6 +2775,9 @@ acpi:GSC*:
acpi:GSM*:
ID_VENDOR_FROM_DATABASE=Goldstar Company Ltd
+acpi:GSN*:
+ ID_VENDOR_FROM_DATABASE=Grandstream Networks, Inc.
+
acpi:GST*:
ID_VENDOR_FROM_DATABASE=Graphic SystemTechnology
@@ -2383,6 +2817,9 @@ acpi:GVL*:
acpi:GWI*:
ID_VENDOR_FROM_DATABASE=GW Instruments
+acpi:GWK*:
+ ID_VENDOR_FROM_DATABASE=Gateworks Corporation
+
acpi:GWY*:
ID_VENDOR_FROM_DATABASE=Gateway 2000
@@ -2437,6 +2874,9 @@ acpi:HDV*:
acpi:HEC*:
ID_VENDOR_FROM_DATABASE=Hisense Electric Co., Ltd.
+acpi:HEI*:
+ ID_VENDOR_FROM_DATABASE=Hyundai
+
acpi:HEL*:
ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems Europe Ltd
@@ -2458,6 +2898,9 @@ acpi:HIB*:
acpi:HIC*:
ID_VENDOR_FROM_DATABASE=Hitachi Information Technology Co., Ltd.
+acpi:HII*:
+ ID_VENDOR_FROM_DATABASE=Harman International Industries, Inc
+
acpi:HIK*:
ID_VENDOR_FROM_DATABASE=Hikom Co., Ltd.
@@ -2467,6 +2910,9 @@ acpi:HIL*:
acpi:HIQ*:
ID_VENDOR_FROM_DATABASE=Kaohsiung Opto Electronics Americas, Inc.
+acpi:HIS*:
+ ID_VENDOR_FROM_DATABASE=Hope Industrial Systems, Inc.
+
acpi:HIT*:
ID_VENDOR_FROM_DATABASE=Hitachi America Ltd
@@ -2476,9 +2922,15 @@ acpi:HJI*:
acpi:HKA*:
ID_VENDOR_FROM_DATABASE=HONKO MFG. CO., LTD.
+acpi:HKC*:
+ ID_VENDOR_FROM_DATABASE=HKC OVERSEAS LIMITED
+
acpi:HKG*:
ID_VENDOR_FROM_DATABASE=Josef Heim KG
+acpi:HLG*:
+ ID_VENDOR_FROM_DATABASE=China Hualu Group Co., Ltd.
+
acpi:HMC*:
ID_VENDOR_FROM_DATABASE=Hualon Microelectric Corporation
@@ -2507,19 +2959,25 @@ acpi:HPA*:
ID_VENDOR_FROM_DATABASE=Zytor Communications
acpi:HPC*:
- ID_VENDOR_FROM_DATABASE=Hewlett Packard Co.
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Co.
acpi:HPD*:
ID_VENDOR_FROM_DATABASE=Hewlett Packard
+acpi:HPE*:
+ ID_VENDOR_FROM_DATABASE=Hewlett Packard Enterprise
+
acpi:HPI*:
ID_VENDOR_FROM_DATABASE=Headplay, Inc.
acpi:HPK*:
ID_VENDOR_FROM_DATABASE=HAMAMATSU PHOTONICS K.K.
+acpi:HPN*:
+ ID_VENDOR_FROM_DATABASE=HP Inc.
+
acpi:HPQ*:
- ID_VENDOR_FROM_DATABASE=HP
+ ID_VENDOR_FROM_DATABASE=Hewlett-Packard Co.
acpi:HPR*:
ID_VENDOR_FROM_DATABASE=H.P.R. Electronics GmbH
@@ -2548,12 +3006,18 @@ acpi:HSC*:
acpi:HSD*:
ID_VENDOR_FROM_DATABASE=HannStar Display Corp
+acpi:HSL*:
+ ID_VENDOR_FROM_DATABASE=Hansol
+
acpi:HSM*:
ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
acpi:HSP*:
ID_VENDOR_FROM_DATABASE=HannStar Display Corp
+acpi:HST*:
+ ID_VENDOR_FROM_DATABASE=Horsent Technology Co., Ltd.
+
acpi:HTC*:
ID_VENDOR_FROM_DATABASE=Hitachi Ltd
@@ -2563,6 +3027,12 @@ acpi:HTI*:
acpi:HTK*:
ID_VENDOR_FROM_DATABASE=Holtek Microelectronics Inc
+acpi:HTL*:
+ ID_VENDOR_FROM_DATABASE=HTBLuVA Mödling
+
+acpi:HTR*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen ZhuoYi HengTong Computer Technology Limited
+
acpi:HTX*:
ID_VENDOR_FROM_DATABASE=Hitex Systementwicklung GmbH
@@ -2572,6 +3042,9 @@ acpi:HUB*:
acpi:HUM*:
ID_VENDOR_FROM_DATABASE=IMP Electronics Ltd.
+acpi:HVR*:
+ ID_VENDOR_FROM_DATABASE=HTC Corportation
+
acpi:HWA*:
ID_VENDOR_FROM_DATABASE=Harris Canada Inc
@@ -2608,6 +3081,9 @@ acpi:HYT*:
acpi:HYV*:
ID_VENDOR_FROM_DATABASE=Hynix Semiconductor
+acpi:IAD*:
+ ID_VENDOR_FROM_DATABASE=IAdea Corporation
+
acpi:IAF*:
ID_VENDOR_FROM_DATABASE=Institut f r angewandte Funksystemtechnik GmbH
@@ -2624,7 +3100,7 @@ acpi:IBI*:
ID_VENDOR_FROM_DATABASE=INBINE.CO.LTD
acpi:IBM*:
- ID_VENDOR_FROM_DATABASE=IBM
+ ID_VENDOR_FROM_DATABASE=IBM Brasil
acpi:IBP*:
ID_VENDOR_FROM_DATABASE=IBP Instruments GmbH
@@ -2647,6 +3123,9 @@ acpi:ICE*:
acpi:ICI*:
ID_VENDOR_FROM_DATABASE=Infotek Communication Inc
+acpi:ICL*:
+ ID_VENDOR_FROM_DATABASE=Fujitsu ICL
+
acpi:ICM*:
ID_VENDOR_FROM_DATABASE=Intracom SA
@@ -2656,6 +3135,9 @@ acpi:ICN*:
acpi:ICO*:
ID_VENDOR_FROM_DATABASE=Intel Corp
+acpi:ICP*:
+ ID_VENDOR_FROM_DATABASE=ICP Electronics, Inc./iEi Technology Corp.
+
acpi:ICS*:
ID_VENDOR_FROM_DATABASE=Integrated Circuit Systems
@@ -2731,6 +3213,15 @@ acpi:III*:
acpi:IIN*:
ID_VENDOR_FROM_DATABASE=IINFRA Co., Ltd
+acpi:IIT*:
+ ID_VENDOR_FROM_DATABASE=Informatik Information Technologies
+
+acpi:IKE*:
+ ID_VENDOR_FROM_DATABASE=Ikegami Tsushinki Co. Ltd.
+
+acpi:IKN*:
+ ID_VENDOR_FROM_DATABASE=IKON
+
acpi:IKS*:
ID_VENDOR_FROM_DATABASE=Ikos Systems Inc
@@ -2768,11 +3259,17 @@ acpi:IMN*:
ID_VENDOR_FROM_DATABASE=Impossible Production
acpi:IMP*:
- ID_VENDOR_FROM_DATABASE=Impression Products Incorporated
+ ID_VENDOR_FROM_DATABASE=Impinj
acpi:IMT*:
ID_VENDOR_FROM_DATABASE=Inmax Technology Corporation
+acpi:IMS*:
+ ID_VENDOR_FROM_DATABASE=Integrated Micro Solution Inc.
+
+acpi:INA*:
+ ID_VENDOR_FROM_DATABASE=Inventec Corporation
+
acpi:INC*:
ID_VENDOR_FROM_DATABASE=Home Row Inc
@@ -2815,12 +3312,12 @@ acpi:INS*:
acpi:INT*:
ID_VENDOR_FROM_DATABASE=Interphase Corporation
-acpi:inu*:
- ID_VENDOR_FROM_DATABASE=Inovatec S.p.A.
-
acpi:INV*:
ID_VENDOR_FROM_DATABASE=Inviso, Inc.
+acpi:INX*:
+ ID_VENDOR_FROM_DATABASE=Communications Supply Corporation (A division of WESCO)
+
acpi:INZ*:
ID_VENDOR_FROM_DATABASE=Best Buy
@@ -2860,6 +3357,9 @@ acpi:IPN*:
acpi:IPP*:
ID_VENDOR_FROM_DATABASE=IP Power Technologies GmbH
+acpi:IPQ*:
+ ID_VENDOR_FROM_DATABASE=IP3 Technology Ltd.
+
acpi:IPR*:
ID_VENDOR_FROM_DATABASE=Ithaca Peripherals
@@ -2879,7 +3379,7 @@ acpi:IQT*:
ID_VENDOR_FROM_DATABASE=IMAGEQUEST Co., Ltd
acpi:IRD*:
- ID_VENDOR_FROM_DATABASE=IRdata
+ ID_VENDOR_FROM_DATABASE=Irdata
acpi:ISA*:
ID_VENDOR_FROM_DATABASE=Symbol Technologies
@@ -2926,6 +3426,9 @@ acpi:ITD*:
acpi:ITE*:
ID_VENDOR_FROM_DATABASE=Integrated Tech Express Inc
+acpi:ITI*:
+ ID_VENDOR_FROM_DATABASE=VanErum Group
+
acpi:ITK*:
ID_VENDOR_FROM_DATABASE=ITK Telekommunikation AG
@@ -2974,6 +3477,9 @@ acpi:IWX*:
acpi:IXD*:
ID_VENDOR_FROM_DATABASE=Intertex Data AB
+acpi:IXN*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen Inet Mobile Internet Technology Co., LTD
+
acpi:JAC*:
ID_VENDOR_FROM_DATABASE=Astec Inc
@@ -2992,6 +3498,9 @@ acpi:JAZ*:
acpi:JCE*:
ID_VENDOR_FROM_DATABASE=Jace Tech Inc
+acpi:JDI*:
+ ID_VENDOR_FROM_DATABASE=Japan Display Inc.
+
acpi:JDL*:
ID_VENDOR_FROM_DATABASE=Japan Digital Laboratory Co.,Ltd.
@@ -3100,6 +3609,9 @@ acpi:KEM*:
acpi:KES*:
ID_VENDOR_FROM_DATABASE=Kesa Corporation
+acpi:KEU*:
+ ID_VENDOR_FROM_DATABASE=Kontron Europe GmbH
+
acpi:KEY*:
ID_VENDOR_FROM_DATABASE=Key Tech Inc
@@ -3112,9 +3624,15 @@ acpi:KFE*:
acpi:KFX*:
ID_VENDOR_FROM_DATABASE=Kofax Image Products
+acpi:KGI*:
+ ID_VENDOR_FROM_DATABASE=Klipsch Group, Inc
+
acpi:KGL*:
ID_VENDOR_FROM_DATABASE=KEISOKU GIKEN Co.,Ltd.
+acpi:KIO*:
+ ID_VENDOR_FROM_DATABASE=Kionix, Inc.
+
acpi:KIS*:
ID_VENDOR_FROM_DATABASE=KiSS Technology A/S
@@ -3127,6 +3645,9 @@ acpi:KME*:
acpi:KML*:
ID_VENDOR_FROM_DATABASE=Kensington Microware Ltd
+acpi:KMR*:
+ ID_VENDOR_FROM_DATABASE=Kramer Electronics Ltd. International
+
acpi:KNC*:
ID_VENDOR_FROM_DATABASE=Konica corporation
@@ -3166,6 +3687,9 @@ acpi:KRY*:
acpi:KSC*:
ID_VENDOR_FROM_DATABASE=Kinetic Systems Corporation
+acpi:KSG*:
+ ID_VENDOR_FROM_DATABASE=KUPA China Shenzhen Micro Technology Co., Ltd. Gold Institute
+
acpi:KSL*:
ID_VENDOR_FROM_DATABASE=Karn Solutions Ltd.
@@ -3214,6 +3738,9 @@ acpi:KYE*:
acpi:KYK*:
ID_VENDOR_FROM_DATABASE=Samsung Electronics America Inc
+acpi:KYN*:
+ ID_VENDOR_FROM_DATABASE=KEYENCE CORPORATION
+
acpi:KZI*:
ID_VENDOR_FROM_DATABASE=K-Zone International co. Ltd.
@@ -3235,6 +3762,9 @@ acpi:LAG*:
acpi:LAN*:
ID_VENDOR_FROM_DATABASE=Sodeman Lancom Inc
+acpi:LAP*:
+ ID_VENDOR_FROM_DATABASE=BenQ
+
acpi:LAS*:
ID_VENDOR_FROM_DATABASE=LASAT Comm. A/S
@@ -3268,6 +3798,9 @@ acpi:LCS*:
acpi:LCT*:
ID_VENDOR_FROM_DATABASE=Labcal Technologies
+acpi:LDN*:
+ ID_VENDOR_FROM_DATABASE=Laserdyne Technologies
+
acpi:LDT*:
ID_VENDOR_FROM_DATABASE=LogiDataTech Electronic GmbH
@@ -3277,6 +3810,9 @@ acpi:LEC*:
acpi:LED*:
ID_VENDOR_FROM_DATABASE=Long Engineering Design Inc
+acpi:LED*:
+ ID_VENDOR_FROM_DATABASE=LeafNet
+
acpi:LEG*:
ID_VENDOR_FROM_DATABASE=Legerity, Inc
@@ -3292,6 +3828,9 @@ acpi:LEX*:
acpi:LGC*:
ID_VENDOR_FROM_DATABASE=Logic Ltd
+acpi:LGD*:
+ ID_VENDOR_FROM_DATABASE=LG Display
+
acpi:LGI*:
ID_VENDOR_FROM_DATABASE=Logitech Inc
@@ -3343,6 +3882,9 @@ acpi:LMT*:
acpi:LND*:
ID_VENDOR_FROM_DATABASE=Land Computer Company Ltd
+acpi:LNE*:
+ ID_VENDOR_FROM_DATABASE=Linksys
+
acpi:LNK*:
ID_VENDOR_FROM_DATABASE=Link Tech Inc
@@ -3355,6 +3897,9 @@ acpi:LNT*:
acpi:LNV*:
ID_VENDOR_FROM_DATABASE=Lenovo
+acpi:LNX*:
+ ID_VENDOR_FROM_DATABASE=The Linux Foundation
+
acpi:LOC*:
ID_VENDOR_FROM_DATABASE=Locamation B.V.
@@ -3373,6 +3918,9 @@ acpi:LPE*:
acpi:LPI*:
ID_VENDOR_FROM_DATABASE=Design Technology
+acpi:LPL*:
+ ID_VENDOR_FROM_DATABASE=LG Philips
+
acpi:LSC*:
ID_VENDOR_FROM_DATABASE=LifeSize Communications
@@ -3538,6 +4086,12 @@ acpi:MCS*:
acpi:MCT*:
ID_VENDOR_FROM_DATABASE=Microtec
+acpi:MCX*:
+ ID_VENDOR_FROM_DATABASE=Millson Custom Solutions Inc.
+
+acpi:MCY*:
+ ID_VENDOR_FROM_DATABASE=Microdyne
+
acpi:MDA*:
ID_VENDOR_FROM_DATABASE=Media4 Inc
@@ -3587,7 +4141,7 @@ acpi:MEE*:
ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Engineering Co., Ltd.
acpi:MEG*:
- ID_VENDOR_FROM_DATABASE=Abeam Tech Ltd
+ ID_VENDOR_FROM_DATABASE=Abeam Tech Ltd.
acpi:MEI*:
ID_VENDOR_FROM_DATABASE=Panasonic Industry Company
@@ -3595,18 +4149,27 @@ acpi:MEI*:
acpi:MEJ*:
ID_VENDOR_FROM_DATABASE=Mac-Eight Co., LTD.
+acpi:MEK*:
+ ID_VENDOR_FROM_DATABASE=Mediaedge Corporation
+
acpi:MEL*:
ID_VENDOR_FROM_DATABASE=Mitsubishi Electric Corporation
acpi:MEN*:
ID_VENDOR_FROM_DATABASE=MEN Mikroelectronik Nueruberg GmbH
+acpi:MEP*:
+ ID_VENDOR_FROM_DATABASE=Meld Technology
+
acpi:MEQ*:
ID_VENDOR_FROM_DATABASE=Matelect Ltd.
acpi:MET*:
ID_VENDOR_FROM_DATABASE=Metheus Corporation
+acpi:MEU*:
+ ID_VENDOR_FROM_DATABASE=MPL AG, Elektronik-Unternehmen
+
acpi:MEX*:
ID_VENDOR_FROM_DATABASE=MSC Vertriebs GmbH
@@ -3664,6 +4227,9 @@ acpi:MIS*:
acpi:MIT*:
ID_VENDOR_FROM_DATABASE=MCM Industrial Technology GmbH
+acpi:MIV*:
+ ID_VENDOR_FROM_DATABASE=MicroImage Video Systems
+
acpi:MJI*:
ID_VENDOR_FROM_DATABASE=MARANTZ JAPAN, INC.
@@ -3673,6 +4239,9 @@ acpi:MJS*:
acpi:MKC*:
ID_VENDOR_FROM_DATABASE=Media Tek Inc.
+acpi:MKS*:
+ ID_VENDOR_FROM_DATABASE=MK Seiko Co., Ltd.
+
acpi:MKT*:
ID_VENDOR_FROM_DATABASE=MICROTEK Inc.
@@ -3688,15 +4257,24 @@ acpi:MLG*:
acpi:MLI*:
ID_VENDOR_FROM_DATABASE=McIntosh Laboratory Inc.
+acpi:MLL*:
+ ID_VENDOR_FROM_DATABASE=Millogic Ltd.
+
acpi:MLM*:
ID_VENDOR_FROM_DATABASE=Millennium Engineering Inc
acpi:MLN*:
ID_VENDOR_FROM_DATABASE=Mark Levinson
+acpi:MLP*:
+ ID_VENDOR_FROM_DATABASE=Magic Leap
+
acpi:MLS*:
ID_VENDOR_FROM_DATABASE=Milestone EPE
+acpi:MLT*:
+ ID_VENDOR_FROM_DATABASE=Wanlida Group Co., Ltd.
+
acpi:MLX*:
ID_VENDOR_FROM_DATABASE=Mylex Corporation
@@ -3724,6 +4302,9 @@ acpi:MMS*:
acpi:MNC*:
ID_VENDOR_FROM_DATABASE=Mini Micro Methods Ltd
+acpi:MNI*:
+ ID_VENDOR_FROM_DATABASE=Marseille, Inc.
+
acpi:MNL*:
ID_VENDOR_FROM_DATABASE=Monorail Inc
@@ -3736,6 +4317,9 @@ acpi:MOD*:
acpi:MOM*:
ID_VENDOR_FROM_DATABASE=Momentum Data Systems
+acpi:MON*:
+ ID_VENDOR_FROM_DATABASE=Daewoo
+
acpi:MOS*:
ID_VENDOR_FROM_DATABASE=Moses Corporation
@@ -3820,6 +4404,9 @@ acpi:MSM*:
acpi:MSP*:
ID_VENDOR_FROM_DATABASE=Mistral Solutions [P] Ltd.
+acpi:MSR*:
+ ID_VENDOR_FROM_DATABASE=MASPRO DENKOH Corp.
+
acpi:MST*:
ID_VENDOR_FROM_DATABASE=MS Telematica
@@ -3835,6 +4422,9 @@ acpi:MSX*:
acpi:MSY*:
ID_VENDOR_FROM_DATABASE=MicroTouch Systems Inc
+acpi:MTA*:
+ ID_VENDOR_FROM_DATABASE=Meta Watch Ltd
+
acpi:MTB*:
ID_VENDOR_FROM_DATABASE=Media Technologies Ltd.
@@ -3853,6 +4443,9 @@ acpi:MTH*:
acpi:MTI*:
ID_VENDOR_FROM_DATABASE=MaxCom Technical Inc
+acpi:MTJ*:
+ ID_VENDOR_FROM_DATABASE=MicroTechnica Co.,Ltd.
+
acpi:MTK*:
ID_VENDOR_FROM_DATABASE=Microtek International Inc.
@@ -3881,7 +4474,7 @@ acpi:MUD*:
ID_VENDOR_FROM_DATABASE=Multi-Dimension Institute
acpi:MUK*:
- ID_VENDOR_FROM_DATABASE=mainpine limited
+ ID_VENDOR_FROM_DATABASE=Mainpine Limited
acpi:MVD*:
ID_VENDOR_FROM_DATABASE=Microvitec PLC
@@ -3892,6 +4485,9 @@ acpi:MVI*:
acpi:MVM*:
ID_VENDOR_FROM_DATABASE=SOBO VISION
+acpi:MVN*:
+ ID_VENDOR_FROM_DATABASE=Meta Company
+
acpi:MVS*:
ID_VENDOR_FROM_DATABASE=Microvision
@@ -3946,6 +4542,9 @@ acpi:NAK*:
acpi:NAL*:
ID_VENDOR_FROM_DATABASE=Network Alchemy
+acpi:NAN*:
+ ID_VENDOR_FROM_DATABASE=Nanao
+
acpi:NAT*:
ID_VENDOR_FROM_DATABASE=NaturalPoint Inc.
@@ -3979,6 +4578,9 @@ acpi:NCI*:
acpi:NCL*:
ID_VENDOR_FROM_DATABASE=NetComm Ltd
+acpi:NCP*:
+ ID_VENDOR_FROM_DATABASE=Najing CEC Panda FPD Technology CO. ltd
+
acpi:NCR*:
ID_VENDOR_FROM_DATABASE=NCR Electronics
@@ -3991,6 +4593,9 @@ acpi:NCT*:
acpi:NDC*:
ID_VENDOR_FROM_DATABASE=National DataComm Corporaiton
+acpi:NDF*:
+ ID_VENDOR_FROM_DATABASE=NDF Special Light Products B.V.
+
acpi:NDI*:
ID_VENDOR_FROM_DATABASE=National Display Systems
@@ -4048,6 +4653,9 @@ acpi:NIX*:
acpi:NLC*:
ID_VENDOR_FROM_DATABASE=Next Level Communications
+acpi:NME*:
+ ID_VENDOR_FROM_DATABASE=Navico, Inc.
+
acpi:NMP*:
ID_VENDOR_FROM_DATABASE=Nokia Mobile Phones
@@ -4063,6 +4671,9 @@ acpi:NMX*:
acpi:NNC*:
ID_VENDOR_FROM_DATABASE=NNC
+acpi:NOD*:
+ ID_VENDOR_FROM_DATABASE=3NOD Digital Technology Co. Ltd.
+
acpi:NOE*:
ID_VENDOR_FROM_DATABASE=NordicEye AB
@@ -4078,6 +4689,9 @@ acpi:NOR*:
acpi:NOT*:
ID_VENDOR_FROM_DATABASE=Not Limited Inc
+acpi:NPA*:
+ ID_VENDOR_FROM_DATABASE=Arvanics
+
acpi:NPI*:
ID_VENDOR_FROM_DATABASE=Network Peripherals Inc
@@ -4090,6 +4704,9 @@ acpi:NRT*:
acpi:NRV*:
ID_VENDOR_FROM_DATABASE=Taugagreining hf
+acpi:NSA*:
+ ID_VENDOR_FROM_DATABASE=NeuroSky, Inc.
+
acpi:NSC*:
ID_VENDOR_FROM_DATABASE=National Semiconductor Corporation
@@ -4178,7 +4795,7 @@ acpi:NXS*:
ID_VENDOR_FROM_DATABASE=Technology Nexus Secure Open Systems AB
acpi:NYC*:
- ID_VENDOR_FROM_DATABASE=nakayo telecommunications,inc.
+ ID_VENDOR_FROM_DATABASE=Nakayo Relecommunications, Inc.
acpi:OAK*:
ID_VENDOR_FROM_DATABASE=Oak Tech Inc
@@ -4210,6 +4827,9 @@ acpi:OEC*:
acpi:OEI*:
ID_VENDOR_FROM_DATABASE=Optum Engineering Inc.
+acpi:OHW*:
+ ID_VENDOR_FROM_DATABASE=M-Labs Limited
+
acpi:OIC*:
ID_VENDOR_FROM_DATABASE=Option Industrial Computers
@@ -4300,6 +4920,12 @@ acpi:ORN*:
acpi:OSA*:
ID_VENDOR_FROM_DATABASE=OSAKA Micro Computer, Inc.
+acpi:OSD*:
+ ID_VENDOR_FROM_DATABASE=Optical Systems Design Pty Ltd
+
+acpi:OSI*:
+ ID_VENDOR_FROM_DATABASE=Open Stack, Inc.
+
acpi:OSP*:
ID_VENDOR_FROM_DATABASE=OPTI-UPS Corporation
@@ -4312,8 +4938,11 @@ acpi:OTB*:
acpi:OTI*:
ID_VENDOR_FROM_DATABASE=Orchid Technology
+acpi:OTK*:
+ ID_VENDOR_FROM_DATABASE=OmniTek
+
acpi:OTM*:
- ID_VENDOR_FROM_DATABASE=Optoma Corporation          
+ ID_VENDOR_FROM_DATABASE=Optoma Corporation
acpi:OTT*:
ID_VENDOR_FROM_DATABASE=OPTO22, Inc.
@@ -4321,6 +4950,9 @@ acpi:OTT*:
acpi:OUK*:
ID_VENDOR_FROM_DATABASE=OUK Company Ltd
+acpi:OVR*:
+ ID_VENDOR_FROM_DATABASE=Oculus VR, Inc.
+
acpi:OWL*:
ID_VENDOR_FROM_DATABASE=Mediacom Technologies Pte Ltd
@@ -4408,6 +5040,9 @@ acpi:PCW*:
acpi:PCX*:
ID_VENDOR_FROM_DATABASE=PC Xperten
+acpi:PDC*:
+ ID_VENDOR_FROM_DATABASE=Polaroid
+
acpi:PDM*:
ID_VENDOR_FROM_DATABASE=Psion Dacom Plc.
@@ -4429,6 +5064,9 @@ acpi:PDV*:
acpi:PEC*:
ID_VENDOR_FROM_DATABASE=POTRANS Electrical Corp.
+acpi:PEG*:
+ ID_VENDOR_FROM_DATABASE=Pegatron Corporation
+
acpi:PEI*:
ID_VENDOR_FROM_DATABASE=PEI Electronics Inc
@@ -4480,6 +5118,9 @@ acpi:PHS*:
acpi:PHY*:
ID_VENDOR_FROM_DATABASE=Phylon Communications
+acpi:PIC*:
+ ID_VENDOR_FROM_DATABASE=Picturall Ltd.
+
acpi:PIE*:
ID_VENDOR_FROM_DATABASE=Pacific Image Electronics Company Ltd
@@ -4502,7 +5143,7 @@ acpi:PJT*:
ID_VENDOR_FROM_DATABASE=Pan Jit International Inc.
acpi:PKA*:
- ID_VENDOR_FROM_DATABASE=Acco UK ltd.
+ ID_VENDOR_FROM_DATABASE=Acco UK Ltd.
acpi:PLC*:
ID_VENDOR_FROM_DATABASE=Pro-Log Corporation
@@ -4564,6 +5205,9 @@ acpi:PON*:
acpi:POR*:
ID_VENDOR_FROM_DATABASE=Portalis LC
+acpi:POT*:
+ ID_VENDOR_FROM_DATABASE=Parrot
+
acpi:PPC*:
ID_VENDOR_FROM_DATABASE=Phoenixtec Power Company Ltd
@@ -4612,6 +5256,9 @@ acpi:PRM*:
acpi:PRO*:
ID_VENDOR_FROM_DATABASE=Proteon
+acpi:PRP*:
+ ID_VENDOR_FROM_DATABASE=UEFI Forum
+
acpi:PRS*:
ID_VENDOR_FROM_DATABASE=Leutron Vision
@@ -4645,6 +5292,9 @@ acpi:PSM*:
acpi:PST*:
ID_VENDOR_FROM_DATABASE=Global Data SA
+acpi:PSY*:
+ ID_VENDOR_FROM_DATABASE=Prodea Systems Inc.
+
acpi:PTA*:
ID_VENDOR_FROM_DATABASE=PAR Tech Inc.
@@ -4666,6 +5316,9 @@ acpi:PTL*:
acpi:PTS*:
ID_VENDOR_FROM_DATABASE=Plain Tree Systems Inc
+acpi:PUL*:
+ ID_VENDOR_FROM_DATABASE=Pulse-Eight Ltd
+
acpi:PVG*:
ID_VENDOR_FROM_DATABASE=Proview Global Co., Ltd
@@ -4840,9 +5493,21 @@ acpi:RES*:
acpi:RET*:
ID_VENDOR_FROM_DATABASE=Resonance Technology, Inc.
+acpi:REV*:
+ ID_VENDOR_FROM_DATABASE=Revolution Display, Inc.
+
acpi:REX*:
ID_VENDOR_FROM_DATABASE=RATOC Systems, Inc.
+acpi:RFI*:
+ ID_VENDOR_FROM_DATABASE=RAFI GmbH & Co. KG
+
+acpi:RFX*:
+ ID_VENDOR_FROM_DATABASE=Redfox Technologies Inc.
+
+acpi:RGB*:
+ ID_VENDOR_FROM_DATABASE=RGB Spectrum
+
acpi:RGL*:
ID_VENDOR_FROM_DATABASE=Robertson Geologging Ltd
@@ -4891,6 +5556,9 @@ acpi:RMC*:
acpi:RMP*:
ID_VENDOR_FROM_DATABASE=Research Machines
+acpi:RMS*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen Ramos Digital Technology Co., Ltd
+
acpi:RMT*:
ID_VENDOR_FROM_DATABASE=Roper Mobile
@@ -4936,6 +5604,9 @@ acpi:RSN*:
acpi:RSQ*:
ID_VENDOR_FROM_DATABASE=R Squared
+acpi:RSR*:
+ ID_VENDOR_FROM_DATABASE=Zhong Shan City Richsound Electronic Industrial Ltd.
+
acpi:RSS*:
ID_VENDOR_FROM_DATABASE=Rockwell Semiconductor Systems
@@ -4978,6 +5649,9 @@ acpi:RWC*:
acpi:RXT*:
ID_VENDOR_FROM_DATABASE=Tectona SoftSolutions (P) Ltd.,
+acpi:RZS*:
+ ID_VENDOR_FROM_DATABASE=Rozsnyó, s.r.o.
+
acpi:SAA*:
ID_VENDOR_FROM_DATABASE=Sanritz Automation Co.,Ltd.
@@ -5020,6 +5694,9 @@ acpi:SBS*:
acpi:SBT*:
ID_VENDOR_FROM_DATABASE=Senseboard Technologies AB
+acpi:SCB*:
+ ID_VENDOR_FROM_DATABASE=SeeCubic B.V.
+
acpi:SCC*:
ID_VENDOR_FROM_DATABASE=SORD Computer Corporation
@@ -5059,6 +5736,9 @@ acpi:SCS*:
acpi:SCT*:
ID_VENDOR_FROM_DATABASE=Smart Card Technology
+acpi:SCX*:
+ ID_VENDOR_FROM_DATABASE=Socionext Inc.
+
acpi:SDA*:
ID_VENDOR_FROM_DATABASE=SAT (Societe Anonyme)
@@ -5239,6 +5919,9 @@ acpi:SJE*:
acpi:SKD*:
ID_VENDOR_FROM_DATABASE=Schneider & Koch
+acpi:SKM*:
+ ID_VENDOR_FROM_DATABASE=Guangzhou Teclast Information Technology Limited
+
acpi:SKT*:
ID_VENDOR_FROM_DATABASE=Samsung Electro-Mechanics Company Ltd
@@ -5329,6 +6012,9 @@ acpi:SNI*:
acpi:SNK*:
ID_VENDOR_FROM_DATABASE=S&K Electronics
+acpi:SNN*:
+ ID_VENDOR_FROM_DATABASE=SUNNY ELEKTRONIK
+
acpi:SNO*:
ID_VENDOR_FROM_DATABASE=SINOSUN TECHNOLOGY CO., LTD
@@ -5350,6 +6036,9 @@ acpi:SNX*:
acpi:SNY*:
ID_VENDOR_FROM_DATABASE=Sony
+acpi:SOC*:
+ ID_VENDOR_FROM_DATABASE=Santec Corporation
+
acpi:SOI*:
ID_VENDOR_FROM_DATABASE=Silicon Optix Corporation
@@ -5419,6 +6108,9 @@ acpi:SRF*:
acpi:SRG*:
ID_VENDOR_FROM_DATABASE=Intuitive Surgical, Inc.
+acpi:SRS*:
+ ID_VENDOR_FROM_DATABASE=SR-Systems e.K.
+
acpi:SRT*:
ID_VENDOR_FROM_DATABASE=SeeReal Technologies GmbH
@@ -5437,6 +6129,9 @@ acpi:SSI*:
acpi:SSJ*:
ID_VENDOR_FROM_DATABASE=Sankyo Seiki Mfg.co., Ltd
+acpi:SSL*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen South-Top Computer Co., Ltd.
+
acpi:SSP*:
ID_VENDOR_FROM_DATABASE=Spectrum Signal Proecessing Inc
@@ -5491,6 +6186,9 @@ acpi:STO*:
acpi:STP*:
ID_VENDOR_FROM_DATABASE=StreamPlay Ltd
+acpi:STQ*:
+ ID_VENDOR_FROM_DATABASE=Synthetel Corporation
+
acpi:STR*:
ID_VENDOR_FROM_DATABASE=Starlight Networks Inc
@@ -5536,9 +6234,15 @@ acpi:SVC*:
acpi:SVD*:
ID_VENDOR_FROM_DATABASE=SVD Computer
+acpi:SVE*:
+ ID_VENDOR_FROM_DATABASE=SVEC
+
acpi:SVI*:
ID_VENDOR_FROM_DATABASE=Sun Microsystems
+acpi:SVR*:
+ ID_VENDOR_FROM_DATABASE=Sensics, Inc.
+
acpi:SVS*:
ID_VENDOR_FROM_DATABASE=SVSI
@@ -5554,6 +6258,9 @@ acpi:SWI*:
acpi:SWL*:
ID_VENDOR_FROM_DATABASE=Sharedware Ltd
+acpi:SWO*:
+ ID_VENDOR_FROM_DATABASE=Guangzhou Shirui Electronics Co., Ltd.
+
acpi:SWS*:
ID_VENDOR_FROM_DATABASE=Static
@@ -5566,6 +6273,9 @@ acpi:SXB*:
acpi:SXD*:
ID_VENDOR_FROM_DATABASE=Silex technology, Inc.
+acpi:SXG*:
+ ID_VENDOR_FROM_DATABASE=SELEX GALILEO
+
acpi:SXL*:
ID_VENDOR_FROM_DATABASE=SolutionInside
@@ -5605,6 +6315,12 @@ acpi:SYV*:
acpi:SYX*:
ID_VENDOR_FROM_DATABASE=Prime Systems, Inc.
+acpi:SZM*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen MTC Co., Ltd
+
+acpi:SZV*:
+ ID_VENDOR_FROM_DATABASE=OvisLink
+
acpi:TAA*:
ID_VENDOR_FROM_DATABASE=Tandberg
@@ -5626,6 +6342,9 @@ acpi:TAS*:
acpi:TAT*:
ID_VENDOR_FROM_DATABASE=Teleliaison Inc
+acpi:TAV*:
+ ID_VENDOR_FROM_DATABASE=Thales Avionics
+
acpi:TAX*:
ID_VENDOR_FROM_DATABASE=Taxan (Europe) Ltd
@@ -5722,6 +6441,15 @@ acpi:TEL*:
acpi:TER*:
ID_VENDOR_FROM_DATABASE=TerraTec Electronic GmbH
+acpi:TET*:
+ ID_VENDOR_FROM_DATABASE=TETRADYNE CO., LTD.
+
+acpi:TEX*:
+ ID_VENDOR_FROM_DATABASE=Texas Instruments
+
+acpi:TEZ*:
+ ID_VENDOR_FROM_DATABASE=Tech Source Inc.
+
acpi:TGC*:
ID_VENDOR_FROM_DATABASE=Toshiba Global Commerce Solutions, Inc.
@@ -5743,6 +6471,9 @@ acpi:THN*:
acpi:TIC*:
ID_VENDOR_FROM_DATABASE=Trigem KinfoComm
+acpi:TIL*:
+ ID_VENDOR_FROM_DATABASE=Technical Illusions Inc.
+
acpi:TIP*:
ID_VENDOR_FROM_DATABASE=TIPTEL AG
@@ -5755,6 +6486,9 @@ acpi:TIX*:
acpi:TKC*:
ID_VENDOR_FROM_DATABASE=Taiko Electric Works.LTD
+acpi:TKG*:
+ ID_VENDOR_FROM_DATABASE=Tek Gear
+
acpi:TKN*:
ID_VENDOR_FROM_DATABASE=Teknor Microsystem Inc
@@ -5770,12 +6504,21 @@ acpi:TLA*:
acpi:TLD*:
ID_VENDOR_FROM_DATABASE=Telindus
+acpi:TLE*:
+ ID_VENDOR_FROM_DATABASE=Zhejiang Tianle Digital Electric Co., Ltd.
+
+acpi:TLF*:
+ ID_VENDOR_FROM_DATABASE=Teleforce.,co,ltd
+
acpi:TLI*:
ID_VENDOR_FROM_DATABASE=TOSHIBA TELI CORPORATION
acpi:TLK*:
ID_VENDOR_FROM_DATABASE=Telelink AG
+acpi:TLL*:
+ ID_VENDOR_FROM_DATABASE=Thinklogical
+
acpi:TLS*:
ID_VENDOR_FROM_DATABASE=Teleste Educational OY
@@ -5827,6 +6570,12 @@ acpi:TOE*:
acpi:TOG*:
ID_VENDOR_FROM_DATABASE=The OPEN Group
+acpi:TOL*:
+ ID_VENDOR_FROM_DATABASE=TCL Corporation
+
+acpi:TOM*:
+ ID_VENDOR_FROM_DATABASE=Ceton Corporation
+
acpi:TON*:
ID_VENDOR_FROM_DATABASE=TONNA
@@ -5842,6 +6591,9 @@ acpi:TOU*:
acpi:TPC*:
ID_VENDOR_FROM_DATABASE=Touch Panel Systems Corporation
+acpi:TPD*:
+ ID_VENDOR_FROM_DATABASE=Times (Shanghai) Computer Co., Ltd.
+
acpi:TPE*:
ID_VENDOR_FROM_DATABASE=Technology Power Enterprises Inc
@@ -5869,6 +6621,9 @@ acpi:TPZ*:
acpi:TRA*:
ID_VENDOR_FROM_DATABASE=TriTech Microelectronics International
+acpi:TRB*:
+ ID_VENDOR_FROM_DATABASE=Triumph Board a.s.
+
acpi:TRC*:
ID_VENDOR_FROM_DATABASE=Trioc AB
@@ -5923,6 +6678,9 @@ acpi:TSF*:
acpi:TSG*:
ID_VENDOR_FROM_DATABASE=The Software Group Ltd
+acpi:TSH*:
+ ID_VENDOR_FROM_DATABASE=ELAN MICROELECTRONICS CORPORATION
+
acpi:TSI*:
ID_VENDOR_FROM_DATABASE=TeleVideo Systems
@@ -5960,11 +6718,17 @@ acpi:TTK*:
ID_VENDOR_FROM_DATABASE=Totoku Electric Company Ltd
acpi:TTL*:
- ID_VENDOR_FROM_DATABASE=2-Tel B.V.
+ ID_VENDOR_FROM_DATABASE=2-Tel B.V
+
+acpi:TTP*:
+ ID_VENDOR_FROM_DATABASE=Toshiba Corporation
acpi:TTS*:
ID_VENDOR_FROM_DATABASE=TechnoTrend Systemtechnik GmbH
+acpi:TTX*:
+ ID_VENDOR_FROM_DATABASE=Taitex Corporation
+
acpi:TTY*:
ID_VENDOR_FROM_DATABASE=TRIDELITY Display Solutions GmbH
@@ -6034,6 +6798,9 @@ acpi:UBI*:
acpi:UBL*:
ID_VENDOR_FROM_DATABASE=Ubinetics Ltd.
+acpi:UBU*:
+ ID_VENDOR_FROM_DATABASE=Canonical Ltd.
+
acpi:UDN*:
ID_VENDOR_FROM_DATABASE=Uniden Corporation
@@ -6085,9 +6852,18 @@ acpi:UNB*:
acpi:UNC*:
ID_VENDOR_FROM_DATABASE=Unisys Corporation
-acpi:UNI*:
+acpi:UND*
ID_VENDOR_FROM_DATABASE=Unisys Corporation
+acpi:UNE*
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNF*
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+acpi:UNI*:
+ ID_VENDOR_FROM_DATABASE=Uniform Industry Corp.
+
acpi:UNM*:
ID_VENDOR_FROM_DATABASE=Unisys Corporation
@@ -6118,9 +6894,15 @@ acpi:URD*:
acpi:USA*:
ID_VENDOR_FROM_DATABASE=Utimaco Safeware AG
+acpi:USC*:
+ ID_VENDOR_FROM_DATABASE=UltraStor
+
acpi:USD*:
ID_VENDOR_FROM_DATABASE=U.S. Digital Corporation
+acpi:USE*:
+ ID_VENDOR_FROM_DATABASE=U. S. Electronics Inc.
+
acpi:USI*:
ID_VENDOR_FROM_DATABASE=Universal Scientific Industrial Co., Ltd.
@@ -6133,6 +6915,12 @@ acpi:UTD*:
acpi:UWC*:
ID_VENDOR_FROM_DATABASE=Uniwill Computer Corp.
+acpi:VAD*:
+ ID_VENDOR_FROM_DATABASE=Vaddio, LLC
+
+acpi:VAI*:
+ ID_VENDOR_FROM_DATABASE=VAIO Corporation
+
acpi:VAL*:
ID_VENDOR_FROM_DATABASE=Valence Computing Corporation
@@ -6208,6 +6996,9 @@ acpi:VID*:
acpi:VIK*:
ID_VENDOR_FROM_DATABASE=Viking Connectors
+acpi:VIM*:
+ ID_VENDOR_FROM_DATABASE=Via Mons Ltd.
+
acpi:VIN*:
ID_VENDOR_FROM_DATABASE=Vine Micros Ltd
@@ -6226,9 +7017,18 @@ acpi:VIZ*:
acpi:VLB*:
ID_VENDOR_FROM_DATABASE=ValleyBoard Ltda.
+acpi:VLC*:
+ ID_VENDOR_FROM_DATABASE=VersaLogic Corporation
+
+acpi:VLK*:
+ ID_VENDOR_FROM_DATABASE=Vislink International Ltd
+
acpi:VLT*:
ID_VENDOR_FROM_DATABASE=VideoLan Technologies
+acpi:VLV*:
+ ID_VENDOR_FROM_DATABASE=Valve Corporation
+
acpi:VMI*:
ID_VENDOR_FROM_DATABASE=Vermont Microsystems
@@ -6250,12 +7050,18 @@ acpi:VPI*:
acpi:VPR*:
ID_VENDOR_FROM_DATABASE=Best Buy
+acpi:VPX*:
+ ID_VENDOR_FROM_DATABASE=VPixx Technologies Inc.
+
acpi:VQ@*:
ID_VENDOR_FROM_DATABASE=Vision Quest
acpi:VRC*:
ID_VENDOR_FROM_DATABASE=Virtual Resources Corporation
+acpi:VRM*:
+ ID_VENDOR_FROM_DATABASE=VRmagic Holding AG
+
acpi:VSC*:
ID_VENDOR_FROM_DATABASE=ViewSonic Corporation
@@ -6274,6 +7080,9 @@ acpi:VSP*:
acpi:VSR*:
ID_VENDOR_FROM_DATABASE=V-Star Electronics Inc.
+acpi:VTB*:
+ ID_VENDOR_FROM_DATABASE=Videotechnik Breithaupt
+
acpi:VTC*:
ID_VENDOR_FROM_DATABASE=VTel Corporation
@@ -6343,7 +7152,7 @@ acpi:WEB*:
acpi:WEC*:
ID_VENDOR_FROM_DATABASE=Winbond Electronics Corporation
-acpi:WEL *:
+acpi:WEL*:
ID_VENDOR_FROM_DATABASE=W-DEV
acpi:WEY*:
@@ -6421,6 +7230,12 @@ acpi:WTS*:
acpi:WVM*:
ID_VENDOR_FROM_DATABASE=Wave Systems Corporation
+acpi:WVV*:
+ ID_VENDOR_FROM_DATABASE=WolfVision GmbH
+
+acpi:WWP*:
+ ID_VENDOR_FROM_DATABASE=Wipotec Wiege- und Positioniersysteme GmbH
+
acpi:WWV*:
ID_VENDOR_FROM_DATABASE=World Wide Video, Inc.
@@ -6428,7 +7243,7 @@ acpi:WXT*:
ID_VENDOR_FROM_DATABASE=Woxter Technology Co. Ltd
acpi:WYS*:
- ID_VENDOR_FROM_DATABASE=Myse Technology
+ ID_VENDOR_FROM_DATABASE=Wyse Technology
acpi:WYT*:
ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd.
@@ -6502,6 +7317,9 @@ acpi:XTN*:
acpi:XYC*:
ID_VENDOR_FROM_DATABASE=Xycotec Computer GmbH
+acpi:XYE*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen Zhuona Technology Co., Ltd.
+
acpi:YED*:
ID_VENDOR_FROM_DATABASE=Y-E Data Inc
@@ -6529,18 +7347,30 @@ acpi:ZAZ*:
acpi:ZBR*:
ID_VENDOR_FROM_DATABASE=Zebra Technologies International, LLC
+acpi:ZBX*:
+ ID_VENDOR_FROM_DATABASE=Zebax Technologies
+
+acpi:ZCM*:
+ ID_VENDOR_FROM_DATABASE=Zenith
+
acpi:ZCT*:
ID_VENDOR_FROM_DATABASE=ZeitControl cardsystems GmbH
acpi:ZDS*:
ID_VENDOR_FROM_DATABASE=Zenith Data Systems
+acpi:ZEN*:
+ ID_VENDOR_FROM_DATABASE=ZENIC Inc.
+
acpi:ZGT*:
ID_VENDOR_FROM_DATABASE=Zenith Data Systems
acpi:ZIC*:
ID_VENDOR_FROM_DATABASE=Nationz Technologies Inc.
+acpi:ZMC*:
+ ID_VENDOR_FROM_DATABASE=HangZhou ZMCHIVIN
+
acpi:ZMT*:
ID_VENDOR_FROM_DATABASE=Zalman Tech Co., Ltd.
@@ -6577,6 +7407,9 @@ acpi:ZTM*:
acpi:ZTT*:
ID_VENDOR_FROM_DATABASE=Z3 Technology
+acpi:ZWE*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen Zowee Technology Co., LTD
+
acpi:ZYD*:
ID_VENDOR_FROM_DATABASE=Zydacron Inc
@@ -6591,3 +7424,6 @@ acpi:ZYX*:
acpi:ZZZ*:
ID_VENDOR_FROM_DATABASE=Boca Research Inc
+
+acpi:inu*:
+ ID_VENDOR_FROM_DATABASE=Inovatec S.p.A.
diff --git a/hwdb/20-acpi-vendor.hwdb.patch b/hwdb/20-acpi-vendor.hwdb.patch
new file mode 100644
index 0000000000..734dc59422
--- /dev/null
+++ b/hwdb/20-acpi-vendor.hwdb.patch
@@ -0,0 +1,492 @@
+--- 20-acpi-vendor.hwdb.base 2016-06-10 12:40:38.143970821 +0200
++++ 20-acpi-vendor.hwdb 2016-06-10 12:43:40.557054147 +0200
+@@ -3,6 +3,8 @@
+ # Data imported from:
+ # http://www.uefi.org/uefi-pnp-export
+ # http://www.uefi.org/uefi-acpi-export
++#
++# With various additions from other sources
+
+ acpi:3NOD*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen three Connaught Information Technology Co., Ltd. (3nod Group)
+@@ -10,9 +12,6 @@
+ acpi:AAVA*:
+ ID_VENDOR_FROM_DATABASE=Aava Mobile Oy
+
+-acpi:ACPI*:
+- ID_VENDOR_FROM_DATABASE=Intel Corporation
+-
+ acpi:AMDI*:
+ ID_VENDOR_FROM_DATABASE=AMD
+
+@@ -217,6 +216,9 @@
+ acpi:AAA*:
+ ID_VENDOR_FROM_DATABASE=Avolites Ltd
+
++acpi:AAC*:
++ ID_VENDOR_FROM_DATABASE=AcerView
++
+ acpi:AAE*:
+ ID_VENDOR_FROM_DATABASE=Anatek Electronics Inc.
+
+@@ -241,6 +243,9 @@
+ acpi:ABO*:
+ ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
+
++acpi:ABP*:
++ ID_VENDOR_FROM_DATABASE=Advansys
++
+ acpi:ABS*:
+ ID_VENDOR_FROM_DATABASE=Abaco Systems, Inc.
+
+@@ -286,7 +291,7 @@
+ acpi:ACO*:
+ ID_VENDOR_FROM_DATABASE=Allion Computer Inc.
+
+-acpi:ACP*:
++acpi:ACP[0-9A-F]*:
+ ID_VENDOR_FROM_DATABASE=Aspen Tech Inc
+
+ acpi:ACR*:
+@@ -556,6 +561,9 @@
+ acpi:AMT*:
+ ID_VENDOR_FROM_DATABASE=AMT International Industry
+
++acpi:AMW*:
++ ID_VENDOR_FROM_DATABASE=AMW
++
+ acpi:AMX*:
+ ID_VENDOR_FROM_DATABASE=AMX LLC
+
+@@ -604,6 +612,9 @@
+ acpi:AOA*:
+ ID_VENDOR_FROM_DATABASE=AOpen Inc.
+
++acpi:AOC*:
++ ID_VENDOR_FROM_DATABASE=AOC
++
+ acpi:AOE*:
+ ID_VENDOR_FROM_DATABASE=Advanced Optics Electronics, Inc.
+
+@@ -613,6 +624,9 @@
+ acpi:AOT*:
+ ID_VENDOR_FROM_DATABASE=Alcatel
+
++acpi:APA*:
++ ID_VENDOR_FROM_DATABASE=Adaptec
++
+ acpi:APC*:
+ ID_VENDOR_FROM_DATABASE=American Power Conversion
+
+@@ -788,7 +802,7 @@
+ ID_VENDOR_FROM_DATABASE=Alps Electric Inc
+
+ acpi:AUO*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - AUO
++ ID_VENDOR_FROM_DATABASE=AU Optronics
+
+ acpi:AUR*:
+ ID_VENDOR_FROM_DATABASE=Aureal Semiconductor
+@@ -862,6 +876,9 @@
+ acpi:AXC*:
+ ID_VENDOR_FROM_DATABASE=AXIOMTEK CO., LTD.
+
++acpi:AXE*:
++ ID_VENDOR_FROM_DATABASE=D-Link Systems Inc
++
+ acpi:AXI*:
+ ID_VENDOR_FROM_DATABASE=American Magnetics
+
+@@ -1003,6 +1020,9 @@
+ acpi:BML*:
+ ID_VENDOR_FROM_DATABASE=BIOMED Lab
+
++acpi:BMM*:
++ ID_VENDOR_FROM_DATABASE=BMM
++
+ acpi:BMS*:
+ ID_VENDOR_FROM_DATABASE=BIOMEDISYS
+
+@@ -1015,6 +1035,9 @@
+ acpi:BNO*:
+ ID_VENDOR_FROM_DATABASE=Bang & Olufsen
+
++acpi:BNQ*:
++ ID_VENDOR_FROM_DATABASE=BenQ Corporation
++
+ acpi:BNS*:
+ ID_VENDOR_FROM_DATABASE=Boulder Nonlinear Systems
+
+@@ -1255,6 +1278,9 @@
+ acpi:CHA*:
+ ID_VENDOR_FROM_DATABASE=Chase Research PLC
+
++acpi:CHC*:
++ ID_VENDOR_FROM_DATABASE=Chic Technology Corp.
++
+ acpi:CHD*:
+ ID_VENDOR_FROM_DATABASE=ChangHong Electric Co.,Ltd
+
+@@ -1402,6 +1428,9 @@
+ acpi:COD*:
+ ID_VENDOR_FROM_DATABASE=CODAN Pty. Ltd.
+
++acpi:COG*:
++ ID_VENDOR_FROM_DATABASE=Cogent
++
+ acpi:COI*:
+ ID_VENDOR_FROM_DATABASE=Codec Inc.
+
+@@ -1805,7 +1834,7 @@
+ ID_VENDOR_FROM_DATABASE=Dragon Information Technology
+
+ acpi:DJE*:
+- ID_VENDOR_FROM_DATABASE=Capstone Visua lProduct Development
++ ID_VENDOR_FROM_DATABASE=Capstone Visual Product Development
+
+ acpi:DJP*:
+ ID_VENDOR_FROM_DATABASE=Maygay Machines, Ltd
+@@ -2119,6 +2148,9 @@
+ acpi:EIC*:
+ ID_VENDOR_FROM_DATABASE=Eicon Technology Corporation
+
++acpi:EIZ*:
++ ID_VENDOR_FROM_DATABASE=Eizo
++
+ acpi:EKA*:
+ ID_VENDOR_FROM_DATABASE=MagTek Inc.
+
+@@ -2377,6 +2409,9 @@
+ acpi:FCG*:
+ ID_VENDOR_FROM_DATABASE=First International Computer Ltd
+
++acpi:FCM*:
++ ID_VENDOR_FROM_DATABASE=Funai
++
+ acpi:FCS*:
+ ID_VENDOR_FROM_DATABASE=Focus Enhancements, Inc.
+
+@@ -2839,6 +2874,9 @@
+ acpi:HEC*:
+ ID_VENDOR_FROM_DATABASE=Hisense Electric Co., Ltd.
+
++acpi:HEI*:
++ ID_VENDOR_FROM_DATABASE=Hyundai
++
+ acpi:HEL*:
+ ID_VENDOR_FROM_DATABASE=Hitachi Micro Systems Europe Ltd
+
+@@ -2968,6 +3006,9 @@
+ acpi:HSD*:
+ ID_VENDOR_FROM_DATABASE=HannStar Display Corp
+
++acpi:HSL*:
++ ID_VENDOR_FROM_DATABASE=Hansol
++
+ acpi:HSM*:
+ ID_VENDOR_FROM_DATABASE=AT&T Microelectronics
+
+@@ -3082,6 +3123,9 @@
+ acpi:ICI*:
+ ID_VENDOR_FROM_DATABASE=Infotek Communication Inc
+
++acpi:ICL*:
++ ID_VENDOR_FROM_DATABASE=Fujitsu ICL
++
+ acpi:ICM*:
+ ID_VENDOR_FROM_DATABASE=Intracom SA
+
+@@ -3175,6 +3219,9 @@
+ acpi:IKE*:
+ ID_VENDOR_FROM_DATABASE=Ikegami Tsushinki Co. Ltd.
+
++acpi:IKN*:
++ ID_VENDOR_FROM_DATABASE=IKON
++
+ acpi:IKS*:
+ ID_VENDOR_FROM_DATABASE=Ikos Systems Inc
+
+@@ -3217,6 +3264,9 @@
+ acpi:IMT*:
+ ID_VENDOR_FROM_DATABASE=Inmax Technology Corporation
+
++acpi:IMS*:
++ ID_VENDOR_FROM_DATABASE=Integrated Micro Solution Inc.
++
+ acpi:INA*:
+ ID_VENDOR_FROM_DATABASE=Inventec Corporation
+
+@@ -3712,6 +3762,9 @@
+ acpi:LAN*:
+ ID_VENDOR_FROM_DATABASE=Sodeman Lancom Inc
+
++acpi:LAP*:
++ ID_VENDOR_FROM_DATABASE=BenQ
++
+ acpi:LAS*:
+ ID_VENDOR_FROM_DATABASE=LASAT Comm. A/S
+
+@@ -3757,6 +3810,9 @@
+ acpi:LED*:
+ ID_VENDOR_FROM_DATABASE=Long Engineering Design Inc
+
++acpi:LED*:
++ ID_VENDOR_FROM_DATABASE=LeafNet
++
+ acpi:LEG*:
+ ID_VENDOR_FROM_DATABASE=Legerity, Inc
+
+@@ -3772,6 +3828,9 @@
+ acpi:LGC*:
+ ID_VENDOR_FROM_DATABASE=Logic Ltd
+
++acpi:LGD*:
++ ID_VENDOR_FROM_DATABASE=LG Display
++
+ acpi:LGI*:
+ ID_VENDOR_FROM_DATABASE=Logitech Inc
+
+@@ -3823,6 +3882,9 @@
+ acpi:LND*:
+ ID_VENDOR_FROM_DATABASE=Land Computer Company Ltd
+
++acpi:LNE*:
++ ID_VENDOR_FROM_DATABASE=Linksys
++
+ acpi:LNK*:
+ ID_VENDOR_FROM_DATABASE=Link Tech Inc
+
+@@ -3857,7 +3919,7 @@
+ ID_VENDOR_FROM_DATABASE=Design Technology
+
+ acpi:LPL*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - LPL
++ ID_VENDOR_FROM_DATABASE=LG Philips
+
+ acpi:LSC*:
+ ID_VENDOR_FROM_DATABASE=LifeSize Communications
+@@ -4027,6 +4089,9 @@
+ acpi:MCX*:
+ ID_VENDOR_FROM_DATABASE=Millson Custom Solutions Inc.
+
++acpi:MCY*:
++ ID_VENDOR_FROM_DATABASE=Microdyne
++
+ acpi:MDA*:
+ ID_VENDOR_FROM_DATABASE=Media4 Inc
+
+@@ -4252,6 +4317,9 @@
+ acpi:MOM*:
+ ID_VENDOR_FROM_DATABASE=Momentum Data Systems
+
++acpi:MON*:
++ ID_VENDOR_FROM_DATABASE=Daewoo
++
+ acpi:MOS*:
+ ID_VENDOR_FROM_DATABASE=Moses Corporation
+
+@@ -4474,6 +4542,9 @@
+ acpi:NAL*:
+ ID_VENDOR_FROM_DATABASE=Network Alchemy
+
++acpi:NAN*:
++ ID_VENDOR_FROM_DATABASE=Nanao
++
+ acpi:NAT*:
+ ID_VENDOR_FROM_DATABASE=NaturalPoint Inc.
+
+@@ -4969,6 +5040,9 @@
+ acpi:PCX*:
+ ID_VENDOR_FROM_DATABASE=PC Xperten
+
++acpi:PDC*:
++ ID_VENDOR_FROM_DATABASE=Polaroid
++
+ acpi:PDM*:
+ ID_VENDOR_FROM_DATABASE=Psion Dacom Plc.
+
+@@ -5032,9 +5106,6 @@
+ acpi:PHE*:
+ ID_VENDOR_FROM_DATABASE=Philips Medical Systems Boeblingen GmbH
+
+-acpi:PHI*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - PHI
+-
+ acpi:PHL*:
+ ID_VENDOR_FROM_DATABASE=Philips Consumer Electronics Company
+
+@@ -5116,9 +5187,6 @@
+ acpi:PNL*:
+ ID_VENDOR_FROM_DATABASE=Panelview, Inc.
+
+-acpi:PNP*:
+- ID_VENDOR_FROM_DATABASE=Microsoft
+-
+ acpi:PNR*:
+ ID_VENDOR_FROM_DATABASE=Planar Systems, Inc.
+
+@@ -5248,15 +5316,9 @@
+ acpi:PTS*:
+ ID_VENDOR_FROM_DATABASE=Plain Tree Systems Inc
+
+-acpi:PTW*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - PTW
+-
+ acpi:PUL*:
+ ID_VENDOR_FROM_DATABASE=Pulse-Eight Ltd
+
+-acpi:PVC*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - PVC
+-
+ acpi:PVG*:
+ ID_VENDOR_FROM_DATABASE=Proview Global Co., Ltd
+
+@@ -5560,9 +5622,6 @@
+ acpi:RTI*:
+ ID_VENDOR_FROM_DATABASE=Rancho Tech Inc
+
+-acpi:RTK*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - RTK
+-
+ acpi:RTL*:
+ ID_VENDOR_FROM_DATABASE=Realtek Semiconductor Company Ltd
+
+@@ -5725,9 +5784,6 @@
+ acpi:SEE*:
+ ID_VENDOR_FROM_DATABASE=SeeColor Corporation
+
+-acpi:SEG*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - SEG
+-
+ acpi:SEI*:
+ ID_VENDOR_FROM_DATABASE=Seitz & Associates Inc
+
+@@ -6178,6 +6234,9 @@
+ acpi:SVD*:
+ ID_VENDOR_FROM_DATABASE=SVD Computer
+
++acpi:SVE*:
++ ID_VENDOR_FROM_DATABASE=SVEC
++
+ acpi:SVI*:
+ ID_VENDOR_FROM_DATABASE=Sun Microsystems
+
+@@ -6259,6 +6318,9 @@
+ acpi:SZM*:
+ ID_VENDOR_FROM_DATABASE=Shenzhen MTC Co., Ltd
+
++acpi:SZV*:
++ ID_VENDOR_FROM_DATABASE=OvisLink
++
+ acpi:TAA*:
+ ID_VENDOR_FROM_DATABASE=Tandberg
+
+@@ -6343,6 +6405,9 @@
+ acpi:TDD*:
+ ID_VENDOR_FROM_DATABASE=Tandberg Data Display AS
+
++acpi:TDK*:
++ ID_VENDOR_FROM_DATABASE=TDK USA Corporation
++
+ acpi:TDM*:
+ ID_VENDOR_FROM_DATABASE=Tandem Computer Europe Inc
+
+@@ -6379,6 +6444,9 @@
+ acpi:TET*:
+ ID_VENDOR_FROM_DATABASE=TETRADYNE CO., LTD.
+
++acpi:TEX*:
++ ID_VENDOR_FROM_DATABASE=Texas Instruments
++
+ acpi:TEZ*:
+ ID_VENDOR_FROM_DATABASE=Tech Source Inc.
+
+@@ -6490,9 +6558,6 @@
+ acpi:TNC*:
+ ID_VENDOR_FROM_DATABASE=TNC Industrial Company Ltd
+
+-acpi:TNJ*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - TNJ
+-
+ acpi:TNM*:
+ ID_VENDOR_FROM_DATABASE=TECNIMAGEN SA
+
+@@ -6787,14 +6852,14 @@
+ acpi:UNC*:
+ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+-acpi:UND*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - UND
++acpi:UND*
++ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+-acpi:UNE*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - UNE
++acpi:UNE*
++ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+-acpi:UNF*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - UNF
++acpi:UNF*
++ ID_VENDOR_FROM_DATABASE=Unisys Corporation
+
+ acpi:UNI*:
+ ID_VENDOR_FROM_DATABASE=Uniform Industry Corp.
+@@ -6829,6 +6894,9 @@
+ acpi:USA*:
+ ID_VENDOR_FROM_DATABASE=Utimaco Safeware AG
+
++acpi:USC*:
++ ID_VENDOR_FROM_DATABASE=UltraStor
++
+ acpi:USD*:
+ ID_VENDOR_FROM_DATABASE=U.S. Digital Corporation
+
+@@ -7057,9 +7125,6 @@
+ acpi:WAL*:
+ ID_VENDOR_FROM_DATABASE=Wave Access
+
+-acpi:WAN*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - WAN
+-
+ acpi:WAV*:
+ ID_VENDOR_FROM_DATABASE=Wavephore
+
+@@ -7178,7 +7243,7 @@
+ ID_VENDOR_FROM_DATABASE=Woxter Technology Co. Ltd
+
+ acpi:WYS*:
+- ID_VENDOR_FROM_DATABASE=Myse Technology
++ ID_VENDOR_FROM_DATABASE=Wyse Technology
+
+ acpi:WYT*:
+ ID_VENDOR_FROM_DATABASE=Wooyoung Image & Information Co.,Ltd.
+@@ -7192,9 +7257,6 @@
+ acpi:XDM*:
+ ID_VENDOR_FROM_DATABASE=XDM Ltd.
+
+-acpi:XER*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - XER
+-
+ acpi:XFG*:
+ ID_VENDOR_FROM_DATABASE=Jan Strapko - FOTO
+
+@@ -7222,9 +7284,6 @@
+ acpi:XNT*:
+ ID_VENDOR_FROM_DATABASE=XN Technologies, Inc.
+
+-acpi:XOC*:
+- ID_VENDOR_FROM_DATABASE=DO NOT USE - XOC
+-
+ acpi:XQU*:
+ ID_VENDOR_FROM_DATABASE=SHANGHAI SVA-DAV ELECTRONICS CO., LTD
+
+@@ -7291,6 +7350,9 @@
+ acpi:ZBX*:
+ ID_VENDOR_FROM_DATABASE=Zebax Technologies
+
++acpi:ZCM*:
++ ID_VENDOR_FROM_DATABASE=Zenith
++
+ acpi:ZCT*:
+ ID_VENDOR_FROM_DATABASE=ZeitControl cardsystems GmbH
diff --git a/hwdb/60-evdev.hwdb b/hwdb/60-evdev.hwdb
index 9f2bbbfd18..4152ef503e 100644
--- a/hwdb/60-evdev.hwdb
+++ b/hwdb/60-evdev.hwdb
@@ -127,6 +127,13 @@ evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLati
EVDEV_ABS_35=76:1815:22
EVDEV_ABS_36=131:1330:30
+# Dell Precision M4700
+evdev:name:AlpsPS/2 ALPS DualPoint TouchPad:dmi:*svnDellInc.:pnPrecisionM4700*
+ EVDEV_ABS_00=0:1960:24
+ EVDEV_ABS_01=113:1436:30
+ EVDEV_ABS_35=0:1960:24
+ EVDEV_ABS_36=113:1436:30
+
# Dell XPS15 9550
evdev:name:SynPS/2 Synaptics TouchPad:dmi:bvn*:bvr*:bd*:svnDellInc.:pnXPS159550*
EVDEV_ABS_00=::41
diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb
index 29aac807d1..a5b39dc41e 100644
--- a/hwdb/70-mouse.hwdb
+++ b/hwdb/70-mouse.hwdb
@@ -316,6 +316,8 @@ mouse:usb:v046dpc046:name:Logitech USB Optical Mouse:
mouse:usb:v046dpc05a:name:Logitech USB Optical Mouse:
# Logitech USB Laser Mouse M-U0011-O rebranded as "terra Laser"
mouse:usb:v046dpc065:name:Logitech USB Laser Mouse:
+# Logitech USB Laser Mouse M-U0007 [M500]
+mouse:usb:v046dpc069:name:Logitech USB Laser Mouse:
# Logitech V500 Cordless Notebook Mouse
mouse:usb:v046dpc510:name:Logitech USB Receiver:
# Logitech M560 Wireless Mouse
@@ -341,10 +343,6 @@ mouse:usb:v046dpc06b:name:Logitech G700 Laser Mouse:
mouse:usb:v046dpc531:name:Logitech USB Receiver:
MOUSE_DPI=*1000@500 3800@500 500@1000 1500@1000 2000@1000
-# Logitech USB Laser Mouse M-U0007 [M500]
-mouse:usb:v046dpc069:name:Logitech USB Laser Mouse:
- MOUSE_DPI=1100@125
-
# Logitech Wireless Mouse M310
mouse:usb:v046dp1024:name:Logitech M310:
MOUSE_DPI=1100@168
diff --git a/hwdb/acpi-update.py b/hwdb/acpi-update.py
new file mode 100755
index 0000000000..2dc8c7c064
--- /dev/null
+++ b/hwdb/acpi-update.py
@@ -0,0 +1,79 @@
+#!/usr/bin/python3
+
+from html.parser import HTMLParser
+from enum import Enum
+
+class State(Enum):
+ NOWHERE = 0
+ COMPANY = 1
+ AFTER_COMPANY = 2
+ PNPID = 3
+ AFTER_PNPID = 4
+ DATE = 5
+
+class PNPTableParser(HTMLParser):
+
+ def __init__(self):
+ HTMLParser.__init__(self)
+ self.state = State.NOWHERE
+ self.data = ""
+ self.pnpid = None
+ self.company = None
+ self.table = []
+
+ def handle_starttag(self, tag, attrs):
+
+ if tag == "td":
+ if self.state == State.NOWHERE:
+ self.state = State.COMPANY
+ elif self.state == State.AFTER_COMPANY:
+ self.state = State.PNPID
+ elif self.state == State.AFTER_PNPID:
+ self.state = State.DATE
+ else:
+ raise Error("Unexpected field")
+
+ self.data = ""
+
+ def handle_endtag(self, tag):
+
+ if tag == "td":
+ if self.state == State.COMPANY:
+ self.company = ' '.join(self.data.strip().split())
+ self.state = State.AFTER_COMPANY
+ elif self.state == State.PNPID:
+ self.pnpid = self.data.strip()
+ self.state = State.AFTER_PNPID
+ self.table.append((self.pnpid, self.company))
+ elif self.state == State.DATE:
+ self.state = State.NOWHERE
+ else:
+ raise Error("Unexpected field")
+
+ def handle_data(self, data):
+ self.data += data
+
+def read_table(a):
+
+ parser = PNPTableParser()
+
+ for line in a:
+ parser.feed(line)
+
+ parser.close()
+ parser.table.sort()
+
+ for pnpid, company in parser.table:
+ print("\nacpi:{0}*:\n ID_VENDOR_FROM_DATABASE={1}".format(pnpid, company))
+
+a = open("acpi_id_registry.html")
+b = open("pnp_id_registry.html")
+
+print('# This file is part of systemd.\n'
+ '#\n'
+ '# Data imported from:\n'
+ '# http://www.uefi.org/uefi-pnp-export\n'
+ '# http://www.uefi.org/uefi-acpi-export')
+
+read_table(a)
+read_table(b)
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index 9c04849f66..3ecc969c10 100644
--- a/man/kernel-command-line.xml
+++ b/man/kernel-command-line.xml
@@ -146,7 +146,9 @@
<varlistentry>
<term><varname>-b</varname></term>
+ <term><varname>rd.emergency</varname></term>
<term><varname>emergency</varname></term>
+ <term><varname>rd.rescue</varname></term>
<term><varname>rescue</varname></term>
<term><varname>single</varname></term>
<term><varname>s</varname></term>
@@ -158,7 +160,7 @@
<term><varname>5</varname></term>
<listitem>
<para>Parameters understood by the system and service
- manager, as compatibility options. For details, see
+ manager, as compatibility and convenience options. For details, see
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
</listitem>
</varlistentry>
diff --git a/man/sd_bus_add_match.xml b/man/sd_bus_add_match.xml
new file mode 100644
index 0000000000..8bcf7164a0
--- /dev/null
+++ b/man/sd_bus_add_match.xml
@@ -0,0 +1,119 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Julian Orth
+
+ 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/>.
+-->
+
+<refentry id="sd_bus_add_match">
+
+ <refentryinfo>
+ <title>sd_bus_add_match</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <firstname>Julian</firstname>
+ <surname>Orth</surname>
+ <email>ju.orth@gmail.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_bus_add_match</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_bus_add_match</refname>
+
+ <refpurpose>Add a match rule for message dispatching</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_add_match</function></funcdef>
+ <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+ <paramdef>sd_bus_slot **<parameter>slot</parameter></paramdef>
+ <paramdef>const char *<parameter>match</parameter></paramdef>
+ <paramdef>sd_bus_message_handler_t <parameter>callback</parameter></paramdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ </funcprototype>
+
+ <funcprototype>
+ <funcdef>typedef int (*<function>sd_bus_message_handler_t</function>)</funcdef>
+ <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+ <paramdef>void *<parameter>userdata</parameter></paramdef>
+ <paramdef>sd_bus_error *<parameter>ret_error</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <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>.
+ </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.
+ </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>
+
+ <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.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_get_fd.xml b/man/sd_bus_get_fd.xml
new file mode 100644
index 0000000000..49162a6e65
--- /dev/null
+++ b/man/sd_bus_get_fd.xml
@@ -0,0 +1,101 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Julian Orth
+
+ 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/>.
+-->
+
+<refentry id="sd_bus_get_fd">
+
+ <refentryinfo>
+ <title>sd_bus_get_fd</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <firstname>Julian</firstname>
+ <surname>Orth</surname>
+ <email>ju.orth@gmail.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_bus_get_fd</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_bus_get_fd</refname>
+
+ <refpurpose>Get the file descriptor connected to the message bus</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_get_fd</function></funcdef>
+ <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>sd_bus_get_fd()</function> returns the file descriptor used to
+ communicate with the message bus. This descriptor can be used with
+ <citerefentry
+ project='die-net'><refentrytitle>select</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry
+ project='die-net'><refentrytitle>poll</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ or similar functions to wait for incmming messages.
+ </para>
+
+ <para>
+ If the bus was created with the
+ <citerefentry><refentrytitle>sd_bus_set_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ function, then the <parameter>input_fd</parameter> used in that call is
+ returned.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns the file descriptor used for incoming messages from the message
+ bus.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd_bus_set_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_message_read_basic.xml b/man/sd_bus_message_read_basic.xml
new file mode 100644
index 0000000000..6a46403159
--- /dev/null
+++ b/man/sd_bus_message_read_basic.xml
@@ -0,0 +1,113 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Julian Orth
+
+ 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/>.
+-->
+
+<refentry id="sd_bus_message_read_basic">
+
+ <refentryinfo>
+ <title>sd_bus_message_read_basic</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <firstname>Julian</firstname>
+ <surname>Orth</surname>
+ <email>ju.orth@gmail.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_bus_message_read_basic</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_bus_message_read_basic</refname>
+
+ <refpurpose>Read a basic type from a message</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_message_read_basic</function></funcdef>
+ <paramdef>sd_bus_message *<parameter>m</parameter></paramdef>
+ <paramdef>char <parameter>type</parameter></paramdef>
+ <paramdef>void *<parameter>p</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>sd_bus_message_read_basic()</function> reads a basic type from a
+ message and advances the read position in the message. The set of basic
+ types and their ascii codes passed in <parameter>type</parameter> are
+ described in the <ulink
+ url="https://dbus.freedesktop.org/doc/dbus-specification.html">D-Bus
+ Specification</ulink>.
+ </para>
+
+ <para>
+ If <parameter>p</parameter> is not NULL, it should contain a pointer to an
+ appropriate object. For example, if <parameter>type</parameter> is
+ <constant>'y'</constant>, the object passed in <parameter>p</parameter>
+ should have type <code>uint8_t *</code>. If <parameter>type</parameter>
+ is <constant>'s'</constant>, the object passed in <parameter>p</parameter>
+ should have type <code>const char **</code>. Note that, if the basic type
+ is a pointer (e.g., <code>const char *</code> in the case of a string),
+ the pointer is only borrowed and the contents must be copied if they are
+ to be used after the end of the messages lifetime. Similarly, during the
+ lifetime of such a pointer, the message must not be modified.
+ </para>
+
+ <para>
+ If there is no object of the specified type at the current position in the
+ message, an error is returned.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ On success, <function>sd_bus_message_read_basic()</function> returns 0 or
+ a positive integer. On failure, it returns a negative errno-style error
+ code.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/sd_bus_process.xml b/man/sd_bus_process.xml
new file mode 100644
index 0000000000..4b9f52e52f
--- /dev/null
+++ b/man/sd_bus_process.xml
@@ -0,0 +1,111 @@
+<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Julian Orth
+
+ 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/>.
+-->
+
+<refentry id="sd_bus_process">
+
+ <refentryinfo>
+ <title>sd_bus_process</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <firstname>Julian</firstname>
+ <surname>Orth</surname>
+ <email>ju.orth@gmail.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>sd_bus_process</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sd_bus_process</refname>
+
+ <refpurpose>Drive the connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
+
+ <funcprototype>
+ <funcdef>int <function>sd_bus_process</function></funcdef>
+ <paramdef>sd_bus *<parameter>bus</parameter></paramdef>
+ <paramdef>sd_bus_message **<parameter>r</parameter></paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>sd_bus_process()</function> drives the connection between the
+ message bus and the client. That is, it handles connecting,
+ authentication, and message processing. It should be called in a loop
+ until no further progress can be made or an error occurs.
+ </para>
+
+ <para>
+ Once no further progress can be made,
+ <citerefentry><refentrytitle>sd_bus_wait</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ should be called. Alternatively the user can wait for incoming data on
+ the file descriptor returned by
+ <citerefentry><refentrytitle>sd_bus_get_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+
+ <para>
+ <function>sd_bus_process</function> processes at most one incoming
+ message per call. If the parameter <parameter>r</parameter> is not NULL
+ and the call processed a message, <code>*r</code> is set to this message.
+ The caller owns a reference to this message and should call
+ <citerefentry><refentrytitle>sd_bus_message_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ when the message is no longer needed. If <parameter>r</parameter> is not
+ NULL, progress was made, but no message was processed, <code>*r</code> is
+ set to NULL.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If progress was made, a positive integer is returned. If no progress was
+ made, 0 is returned. If an error occurs, a negative errno-style error code
+ is returned.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 1c3256a662..dbfc7692f7 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -1218,49 +1218,55 @@
<tbody>
<row>
<entry>@clock</entry>
- <entry>System calls for changing the system clock (<function>adjtimex()</function>,
- <function>settimeofday()</function>)</entry>
+ <entry>System calls for changing the system clock (<citerefentry project='man-pages'><refentrytitle>adjtimex</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>settimeofday</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
+ </row>
+ <row>
+ <entry>@cpu-emulation</entry>
+ <entry>System calls for CPU emulation functionality (<citerefentry project='man-pages'><refentrytitle>vm86</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
+ </row>
+ <row>
+ <entry>@debug</entry>
+ <entry>Debugging, performance monitoring and tracing functionality (<citerefentry project='man-pages'><refentrytitle>ptrace</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>perf_event_open</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
<entry>@io-event</entry>
- <entry>Event loop use (<function>poll()</function>, <function>select()</function>,
- <citerefentry project='man-pages'><refentrytitle>epoll</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <function>eventfd()</function>...)</entry>
+ <entry>Event loop system calls (<citerefentry project='man-pages'><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>select</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>epoll</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>eventfd</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
<entry>@ipc</entry>
- <entry>SysV IPC, POSIX Message Queues or other IPC (<citerefentry project='man-pages'><refentrytitle>mq_overview</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry project='man-pages'><refentrytitle>svipc</refentrytitle><manvolnum>7</manvolnum></citerefentry>)</entry>
+ <entry>SysV IPC, POSIX Message Queues or other IPC (<citerefentry project='man-pages'><refentrytitle>mq_overview</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>svipc</refentrytitle><manvolnum>7</manvolnum></citerefentry>)</entry>
+ </row>
+ <row>
+ <entry>@keyring</entry>
+ <entry>Kernel keyring access (<citerefentry project='man-pages'><refentrytitle>keyctl</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
<entry>@module</entry>
- <entry>Kernel module control (<function>create_module()</function>, <function>init_module()</function>...)</entry>
+ <entry>Kernel module control (<citerefentry project='man-pages'><refentrytitle>init_module</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>delete_module</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
<entry>@mount</entry>
- <entry>File system mounting and unmounting (<function>chroot()</function>, <function>mount()</function>...)</entry>
+ <entry>File system mounting and unmounting (<citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>chroot</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
</row>
<row>
<entry>@network-io</entry>
- <entry>Socket I/O (including local AF_UNIX):
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
- <citerefentry project='man-pages'><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry></entry>
+ <entry>Socket I/O (including local AF_UNIX): <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>unix</refentrytitle><manvolnum>7</manvolnum></citerefentry></entry>
</row>
<row>
<entry>@obsolete</entry>
- <entry>Unusual, obsolete or unimplemented (<function>fattach()</function>, <function>gtty()</function>, <function>vm86()</function>...)</entry>
+ <entry>Unusual, obsolete or unimplemented (<citerefentry project='man-pages'><refentrytitle>create_module</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>gtty</refentrytitle><manvolnum>2</manvolnum></citerefentry>, …)</entry>
</row>
<row>
<entry>@privileged</entry>
- <entry>All system calls which need superuser capabilities (<citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>)</entry>
+ <entry>All system calls which need super-user capabilities (<citerefentry project='man-pages'><refentrytitle>capabilities</refentrytitle><manvolnum>7</manvolnum></citerefentry>)</entry>
</row>
<row>
<entry>@process</entry>
- <entry>Process control, execution, namespaces (<function>execve()</function>, <function>kill()</function>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>...)</entry>
+ <entry>Process control, execution, namespaces (<citerefentry project='man-pages'><refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …</entry>
</row>
<row>
<entry>@raw-io</entry>
- <entry>Raw I/O ports (<function>ioperm()</function>, <function>iopl()</function>, <function>pciconfig_read()</function>...)</entry>
+ <entry>Raw I/O port access (<citerefentry project='man-pages'><refentrytitle>ioperm</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>iopl</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <function>pciconfig_read()</function>, …</entry>
</row>
</tbody>
</tgroup>
@@ -1533,6 +1539,26 @@
<citerefentry project='man-pages'><refentrytitle>termcap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>$JOURNAL_STREAM</varname></term>
+
+ <listitem><para>If the standard output or standard error output of the executed processes are connected to the
+ journal (for example, by setting <varname>StandardError=journal</varname>) <varname>$JOURNAL_STREAM</varname>
+ contains the device and inode numbers of the connection file descriptor, formatted in decimal, separated by a
+ colon (<literal>:</literal>). This permits invoked processes to safely detect whether their standard output or
+ standard error output are connected to the journal. The device and inode numbers of the file descriptors should
+ be compared with the values set in the environment variable to determine whether the process output is still
+ connected to the journal. Note that it is generally not sufficient to only check whether
+ <varname>$JOURNAL_STREAM</varname> is set at all as services might invoke external processes replacing their
+ standard output or standard error output, without unsetting the environment variable.</para>
+
+ <para>This environment variable is primarily useful to allow services to optionally upgrade their used log
+ protocol to the native journal protocol (using
+ <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry> and other
+ functions) if their standard output or standard error output is connected to the journal anyway, thus enabling
+ delivery of structured metadata along with logged messages.</para></listitem>
+ </varlistentry>
</variablelist>
<para>Additional variables may be configured by the following
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index cde5d65949..2be1efee2f 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -161,6 +161,10 @@
<row><entry><varname>vxlan</varname></entry>
<entry>A virtual extensible LAN (vxlan), for connecting Cloud computing deployments.</entry></row>
+
+ <row><entry><varname>vrf</varname></entry>
+ <entry>A Virtual Routing and Forwarding (<ulink url="https://www.kernel.org/doc/Documentation/networking/vrf.txt">VRF</ulink>) interface to create seperate routing and forwarding domains.</entry></row>
+
</tbody>
</tgroup>
</table>
@@ -639,6 +643,33 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>Key=</varname></term>
+ <listitem>
+ <para>The <varname>Key=</varname> parameter specifies the same key to use in
+ both directions (<varname>InputKey=</varname> and <varname>OutputKey=</varname>).
+ The <varname>Key=</varname> is either a number or an IPv4 address-like dotted quad.
+ It is used as mark-configured SAD/SPD entry as part of the lookup key (both in data
+ and control path) in ip xfrm (framework used to implement IPsec protocol).
+ See <ulink url="http://man7.org/linux/man-pages/man8/ip-xfrm.8.html">
+ ip-xfrm - transform configuration</ulink> for details. It is only used for VTI/VTI6
+ tunnels.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>InputKey=</varname></term>
+ <listitem>
+ <para>The <varname>InputKey=</varname> parameter specifies the key to use for input.
+ The format is same as <varname>Key=</varname>. It is only used for VTI/VTI6 tunnels.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>OutputKey=</varname></term>
+ <listitem>
+ <para>The <varname>OutputKey=</varname> parameter specifies the key to use for output.
+ The format is same as <varname>Key=</varname>. It is only used for VTI/VTI6 tunnels.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Mode=</varname></term>
<listitem>
<para>An <literal>ip6tnl</literal> tunnel can be in one of three
@@ -1110,7 +1141,16 @@ Name=dummy-test
Kind=dummy
MACAddress=12:34:56:78:9a:bc</programlisting>
</example>
+ <example>
+ <title>/etc/systemd/network/25-vrf.netdev</title>
+ <para>Create an VRF interface with table 42.</para>
+ <programlisting>[NetDev]
+Name=vrf-test
+Kind=vrf
+[VRF]
+TableId=42</programlisting>
+ </example>
</refsect1>
<refsect1>
<title>See Also</title>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index ea98c821fa..edf227c134 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -579,6 +579,12 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>VRF=</varname></term>
+ <listitem>
+ <para>The name of the VRF to add the link to.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>VLAN=</varname></term>
<listitem>
<para>The name of a VLAN to create on the link. This
@@ -1279,6 +1285,17 @@ DHCP=yes
</programlisting>
</example>
+ <example>
+ <title>/etc/systemd/network/25-vrf.network</title>
+ <para>Add the bond1 interface to the VRF master interface vrf-test. This will redirect routes generated on this interface to be within the routing table defined during VRF creation. Traffic won't be redirected towards the VRFs routing table unless specific ip-rules are added.</para>
+ <programlisting>[Match]
+Name=bond1
+
+[Network]
+VRF=vrf-test
+</programlisting>
+ </example>
+
</refsect1>
<refsect1>
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
index d4c8fa7091..7263c0b329 100644
--- a/man/systemd.resource-control.xml
+++ b/man/systemd.resource-control.xml
@@ -92,16 +92,14 @@
<refsect1>
<title>Automatic Dependencies</title>
- <para>Units with the <varname>Slice=</varname> setting set get
- automatic <varname>Requires=</varname> and
- <varname>After=</varname> dependencies on the specified slice
- unit.</para>
+ <para>Units with the <varname>Slice=</varname> setting set automatically acquire <varname>Requires=</varname> and
+ <varname>After=</varname> dependencies on the specified slice unit.</para>
</refsect1>
<refsect1>
<title>Unified and Legacy Control Group Hierarchies</title>
- <para>Unified control group hierarchy is the new version of kernel control group interface. Depending on the
+ <para>The unified control group hierarchy is the new version of kernel control group interface. Depending on the
resource type, there are differences in resource control capabilities. Also, because of interface changes, some
resource types have a separate set of options on the unified hierarchy.</para>
@@ -117,8 +115,8 @@
<varlistentry>
<term><option>Memory</option></term>
<listitem>
- <para><varname>MemoryMax</varname> replaces <varname>MemoryLimit</varname>. <varname>MemoryLow</varname>
- and <varname>MemoryHigh</varname> are effective only on unified hierarchy.</para>
+ <para><varname>MemoryMax=</varname> replaces <varname>MemoryLimit=</varname>. <varname>MemoryLow=</varname>
+ and <varname>MemoryHigh=</varname> are effective only on unified hierarchy.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -228,9 +226,11 @@
reclaimed as long as memory can be reclaimed from unprotected units.</para>
<para>Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is
- parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. This controls the
- <literal>memory.low</literal> control group attribute. For details about this control group attribute, see
- <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
+ parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. Alternatively, a
+ percentage value may be specified, which is taken relative to the installed physical memory on the
+ system. This controls the <literal>memory.low</literal> control group attribute. For details about this
+ control group attribute, see <ulink
+ url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
<para>Implies <literal>MemoryAccounting=true</literal>.</para>
@@ -247,7 +247,9 @@
aggressively in such cases. This is the main mechanism to control memory usage of a unit.</para>
<para>Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is
- parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. If assigned the
+ parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. Alternatively, a
+ percentage value may be specified, which is taken relative to the installed physical memory on the
+ system. If assigned the
special value <literal>infinity</literal>, no memory limit is applied. This controls the
<literal>memory.high</literal> control group attribute. For details about this control group attribute, see
<ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
@@ -268,8 +270,9 @@
last line of defense.</para>
<para>Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is
- parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. If assigned the
- special value <literal>infinity</literal>, no memory limit is applied. This controls the
+ parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. Alternatively, a
+ percentage value may be specified, which is taken relative to the installed physical memory on the system. If
+ assigned the special value <literal>infinity</literal>, no memory limit is applied. This controls the
<literal>memory.max</literal> control group attribute. For details about this control group attribute, see
<ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
@@ -284,17 +287,14 @@
<term><varname>MemoryLimit=<replaceable>bytes</replaceable></varname></term>
<listitem>
- <para>Specify the limit on maximum memory usage of the
- executed processes. The limit specifies how much process and
- kernel memory can be used by tasks in this unit. Takes a
- memory size in bytes. If the value is suffixed with K, M, G
- or T, the specified memory size is parsed as Kilobytes,
- Megabytes, Gigabytes, or Terabytes (with the base 1024),
- respectively. If assigned the special value
- <literal>infinity</literal>, no memory limit is applied. This
- controls the <literal>memory.limit_in_bytes</literal>
- control group attribute. For details about this control
- group attribute, see <ulink
+ <para>Specify the limit on maximum memory usage of the executed processes. The limit specifies how much
+ process and kernel memory can be used by tasks in this unit. Takes a memory size in bytes. If the value is
+ suffixed with K, M, G or T, the specified memory size is parsed as Kilobytes, Megabytes, Gigabytes, or
+ Terabytes (with the base 1024), respectively. Alternatively, a percentage value may be specified, which is
+ taken relative to the installed physical memory on the system. If assigned the special value
+ <literal>infinity</literal>, no memory limit is applied. This controls the
+ <literal>memory.limit_in_bytes</literal> control group attribute. For details about this control group
+ attribute, see <ulink
url="https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt">memory.txt</ulink>.</para>
<para>Implies <literal>MemoryAccounting=true</literal>.</para>
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index 26974ed73f..19ca6d6837 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -497,8 +497,8 @@
<para>These are targets that are called whenever the SysV
compatibility code asks for runlevel 2, 3, 4, 5,
respectively. It is a good idea to make this an alias for
- (i.e. symlink to) <filename>multi-user.target</filename>
- (for runlevel 2) or <filename>graphical.target</filename>
+ (i.e. symlink to) <filename>graphical.target</filename>
+ (for runlevel 5) or <filename>multi-user.target</filename>
(the others).</para>
</listitem>
</varlistentry>
diff --git a/man/systemd.xml b/man/systemd.xml
index b8d91b8943..65f55199e2 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -1024,25 +1024,27 @@
<varlistentry>
<term><varname>emergency</varname></term>
+ <term><varname>rd.emergency</varname></term>
<term><varname>-b</varname></term>
<listitem><para>Boot into emergency mode. This is equivalent
- to <varname>systemd.unit=emergency.target</varname> and
- provided for compatibility reasons and to be easier to
- type.</para></listitem>
+ to <varname>systemd.unit=emergency.target</varname> or
+ <varname>rd.systemd.unit=emergency.target</varname>, respectively, and
+ provided for compatibility reasons and to be easier to type.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>rescue</varname></term>
+ <term><varname>rd.rescue</varname></term>
<term><varname>single</varname></term>
<term><varname>s</varname></term>
<term><varname>S</varname></term>
<term><varname>1</varname></term>
<listitem><para>Boot into rescue mode. This is equivalent to
- <varname>systemd.unit=rescue.target</varname> and provided for
- compatibility reasons and to be easier to
- type.</para></listitem>
+ <varname>systemd.unit=rescue.target</varname> or
+ <varname>rd.systemd.unit=rescue.target</varname>, respectively, and
+ provided for compatibility reasons and to be easier to type.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/udevadm.xml b/man/udevadm.xml
index 8c1abd2770..1c7921f5bd 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -380,7 +380,7 @@
<para>Modify the internal state of the running udev daemon.</para>
<variablelist>
<varlistentry>
- <term><option>-x</option></term>
+ <term><option>-e</option></term>
<term><option>--exit</option></term>
<listitem>
<para>Signal and wait for systemd-udevd to exit.</para>
diff --git a/src/basic/formats-util.h b/src/basic/formats-util.h
index 9b4e8e98fa..39a185f59b 100644
--- a/src/basic/formats-util.h
+++ b/src/basic/formats-util.h
@@ -61,3 +61,19 @@
#else
# error Unknown rlim_t size
#endif
+
+#if SIZEOF_DEV_T == 8
+# define DEV_FMT "%" PRIu64
+#elif SIZEOF_DEV_T == 4
+# define DEV_FMT "%" PRIu32
+#else
+# error Unknown dev_t size
+#endif
+
+#if SIZEOF_INO_T == 8
+# define INO_FMT "%" PRIu64
+#elif SIZEOF_INO_T == 4
+# define INO_FMT "%" PRIu32
+#else
+# error Unknown ino_t size
+#endif
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 8b977871e9..b1272f8799 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -577,6 +577,9 @@ struct btrfs_ioctl_quota_ctl_args {
#define IN6_ADDR_GEN_MODE_EUI64 0
#define IN6_ADDR_GEN_MODE_NONE 1
+#endif
+
+#if !HAVE_DECL_IN6_ADDR_GEN_MODE_STABLE_PRIVACY
#define IN6_ADDR_GEN_MODE_STABLE_PRIVACY 2
#endif
@@ -834,6 +837,10 @@ struct btrfs_ioctl_quota_ctl_args {
#define IFLA_BRPORT_PROXYARP 10
#endif
+#if !HAVE_DECL_IFLA_VRF_TABLE
+#define IFLA_VRF_TABLE 1
+#endif
+
#if !HAVE_DECL_NDA_IFINDEX
#define NDA_UNSPEC 0
#define NDA_DST 1
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c
index 6c11b605a9..503a895731 100644
--- a/src/basic/parse-util.c
+++ b/src/basic/parse-util.c
@@ -532,3 +532,22 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
return 0;
}
+
+int parse_percent(const char *p) {
+ const char *pc, *n;
+ unsigned v;
+ int r;
+
+ pc = endswith(p, "%");
+ if (!pc)
+ return -EINVAL;
+
+ n = strndupa(p, pc - p);
+ r = safe_atou(n, &v);
+ if (r < 0)
+ return r;
+ if (v > 100)
+ return -ERANGE;
+
+ return (int) v;
+}
diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h
index 7dc579a159..73441bb6fd 100644
--- a/src/basic/parse-util.h
+++ b/src/basic/parse-util.h
@@ -105,3 +105,5 @@ static inline int safe_atozu(const char *s, size_t *ret_u) {
int safe_atod(const char *s, double *ret_d);
int parse_fractional_part_u(const char **s, size_t digits, unsigned *res);
+
+int parse_percent(const char *p);
diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c
index 3505fa9c9a..0430beadaa 100644
--- a/src/basic/proc-cmdline.c
+++ b/src/basic/proc-cmdline.c
@@ -160,17 +160,29 @@ static const char * const rlmap[] = {
"3", SPECIAL_MULTI_USER_TARGET,
"4", SPECIAL_MULTI_USER_TARGET,
"5", SPECIAL_GRAPHICAL_TARGET,
+ NULL
+};
+
+static const char * const rlmap_initrd[] = {
+ "emergency", SPECIAL_EMERGENCY_TARGET,
+ "rescue", SPECIAL_RESCUE_TARGET,
+ NULL
};
const char* runlevel_to_target(const char *word) {
size_t i;
+ const char * const *rlmap_ptr = in_initrd() ? rlmap_initrd
+ : rlmap;
if (!word)
return NULL;
- for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
- if (streq(word, rlmap[i]))
- return rlmap[i+1];
+ if (in_initrd() && (word = startswith(word, "rd.")) == NULL)
+ return NULL;
+
+ for (i = 0; rlmap_ptr[i] != NULL; i += 2)
+ if (streq(word, rlmap_ptr[i]))
+ return rlmap_ptr[i+1];
return NULL;
}
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index f6bde20fc5..20768b715a 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -110,6 +110,15 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
assert(line);
assert(pid >= 0);
+ /* Retrieves a process' command line. Replaces unprintable characters while doing so by whitespace (coalescing
+ * multiple sequential ones into one). If max_length is != 0 will return a string of the specified size at most
+ * (the trailing NUL byte does count towards the length here!), abbreviated with a "..." ellipsis. If
+ * comm_fallback is true and the process has no command line set (the case for kernel threads), or has a
+ * command line that resolves to the empty string will return the "comm" name of the process instead.
+ *
+ * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
+ * comm_fallback is false). */
+
p = procfs_file_alloca(pid, "cmdline");
f = fopen(p, "re");
@@ -119,12 +128,22 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
return -errno;
}
- if (max_length == 0) {
+ if (max_length == 1) {
+
+ /* If there's only room for one byte, return the empty string */
+ r = new0(char, 1);
+ if (!r)
+ return -ENOMEM;
+
+ *line = r;
+ return 0;
+
+ } else if (max_length == 0) {
size_t len = 0, allocated = 0;
while ((c = getc(f)) != EOF) {
- if (!GREEDY_REALLOC(r, allocated, len+2)) {
+ if (!GREEDY_REALLOC(r, allocated, len+3)) {
free(r);
return -ENOMEM;
}
@@ -136,14 +155,17 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
}
r[len++] = c;
- } else
+ } else if (len > 0)
space = true;
}
if (len > 0)
r[len] = 0;
+ else
+ r = mfree(r);
} else {
+ bool dotdotdot = false;
size_t left;
r = new(char, max_length);
@@ -155,28 +177,46 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
while ((c = getc(f)) != EOF) {
if (isprint(c)) {
+
if (space) {
- if (left <= 4)
+ if (left <= 2) {
+ dotdotdot = true;
break;
+ }
*(k++) = ' ';
left--;
space = false;
}
- if (left <= 4)
+ if (left <= 1) {
+ dotdotdot = true;
break;
+ }
*(k++) = (char) c;
left--;
- } else
+ } else if (k > r)
space = true;
}
- if (left <= 4) {
- size_t n = MIN(left-1, 3U);
- memcpy(k, "...", n);
- k[n] = 0;
+ if (dotdotdot) {
+ if (max_length <= 4) {
+ k = r;
+ left = max_length;
+ } else {
+ k = r + max_length - 4;
+ left = 4;
+
+ /* Eat up final spaces */
+ while (k > r && isspace(k[-1])) {
+ k--;
+ left++;
+ }
+ }
+
+ strncpy(k, "...", left-1);
+ k[left-1] = 0;
} else
*k = 0;
}
@@ -195,7 +235,37 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char *
if (h < 0)
return h;
- r = strjoin("[", t, "]", NULL);
+ if (max_length == 0)
+ r = strjoin("[", t, "]", NULL);
+ else {
+ size_t l;
+
+ l = strlen(t);
+
+ if (l + 3 <= max_length)
+ r = strjoin("[", t, "]", NULL);
+ else if (max_length <= 6) {
+
+ r = new(char, max_length);
+ if (!r)
+ return -ENOMEM;
+
+ memcpy(r, "[...]", max_length-1);
+ r[max_length-1] = 0;
+ } else {
+ char *e;
+
+ t[max_length - 6] = 0;
+
+ /* Chop off final spaces */
+ e = strchr(t, 0);
+ while (e > t && isspace(e[-1]))
+ e--;
+ *e = 0;
+
+ r = strjoin("[", t, "...]", NULL);
+ }
+ }
if (!r)
return -ENOMEM;
}
@@ -325,9 +395,6 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
assert(field);
assert(uid);
- if (pid == 0)
- return getuid();
-
p = procfs_file_alloca(pid, "status");
f = fopen(p, "re");
if (!f) {
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index c8769a54f4..385c3e4df3 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -85,7 +85,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
return -EINVAL;
a->sockaddr.in6.sin6_family = AF_INET6;
- a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+ a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
a->size = sizeof(struct sockaddr_in6);
} else if (*s == '/') {
@@ -133,7 +133,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
if (r > 0) {
/* Gotcha, it's a traditional IPv4 address */
a->sockaddr.in.sin_family = AF_INET;
- a->sockaddr.in.sin_port = htons((uint16_t) u);
+ a->sockaddr.in.sin_port = htobe16((uint16_t)u);
a->size = sizeof(struct sockaddr_in);
} else {
unsigned idx;
@@ -147,7 +147,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
return -EINVAL;
a->sockaddr.in6.sin6_family = AF_INET6;
- a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+ a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
a->sockaddr.in6.sin6_scope_id = idx;
a->sockaddr.in6.sin6_addr = in6addr_any;
a->size = sizeof(struct sockaddr_in6);
@@ -164,12 +164,12 @@ int socket_address_parse(SocketAddress *a, const char *s) {
if (socket_ipv6_is_supported()) {
a->sockaddr.in6.sin6_family = AF_INET6;
- a->sockaddr.in6.sin6_port = htons((uint16_t) u);
+ a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
a->sockaddr.in6.sin6_addr = in6addr_any;
a->size = sizeof(struct sockaddr_in6);
} else {
a->sockaddr.in.sin_family = AF_INET;
- a->sockaddr.in.sin_port = htons((uint16_t) u);
+ a->sockaddr.in.sin_port = htobe16((uint16_t)u);
a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
a->size = sizeof(struct sockaddr_in);
}
@@ -488,9 +488,7 @@ int sockaddr_port(const struct sockaddr *_sa) {
if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
- return ntohs(sa->sa.sa_family == AF_INET6 ?
- sa->in6.sin6_port :
- sa->in.sin_port);
+ return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port);
}
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
@@ -506,13 +504,13 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
case AF_INET: {
uint32_t a;
- a = ntohl(sa->in.sin_addr.s_addr);
+ a = be32toh(sa->in.sin_addr.s_addr);
if (include_port)
r = asprintf(&p,
"%u.%u.%u.%u:%u",
a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
- ntohs(sa->in.sin_port));
+ be16toh(sa->in.sin_port));
else
r = asprintf(&p,
"%u.%u.%u.%u",
@@ -534,7 +532,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
r = asprintf(&p,
"%u.%u.%u.%u:%u",
a[0], a[1], a[2], a[3],
- ntohs(sa->in6.sin6_port));
+ be16toh(sa->in6.sin6_port));
else
r = asprintf(&p,
"%u.%u.%u.%u",
@@ -550,7 +548,7 @@ int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_
r = asprintf(&p,
"[%s]:%u",
a,
- ntohs(sa->in6.sin6_port));
+ be16toh(sa->in6.sin6_port));
if (r < 0)
return -ENOMEM;
} else {
@@ -988,7 +986,7 @@ ssize_t next_datagram_size_fd(int fd) {
l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC);
if (l < 0) {
- if (errno == EOPNOTSUPP)
+ if (errno == EOPNOTSUPP || errno == EFAULT)
goto fallback;
return -errno;
diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h
index f209a84634..44eadf0347 100644
--- a/src/basic/unit-name.h
+++ b/src/basic/unit-name.h
@@ -195,7 +195,6 @@ typedef enum SwapState {
_SWAP_STATE_INVALID = -1
} SwapState;
-
typedef enum TargetState {
TARGET_DEAD,
TARGET_ACTIVE,
diff --git a/src/basic/util.c b/src/basic/util.c
index 756c663be4..09d16697b7 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -36,6 +36,7 @@
#include "alloc-util.h"
#include "build.h"
+#include "cgroup-util.h"
#include "def.h"
#include "dirent-util.h"
#include "fd-util.h"
@@ -64,6 +65,7 @@ assert_cc(EAGAIN == EWOULDBLOCK);
int saved_argc = 0;
char **saved_argv = NULL;
+static int saved_in_initrd = -1;
size_t page_size(void) {
static thread_local size_t pgsz = 0;
@@ -454,11 +456,10 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa
}
bool in_initrd(void) {
- static int saved = -1;
struct statfs s;
- if (saved >= 0)
- return saved;
+ if (saved_in_initrd >= 0)
+ return saved_in_initrd;
/* We make two checks here:
*
@@ -470,11 +471,15 @@ bool in_initrd(void) {
* emptying when transititioning to the main systemd.
*/
- saved = access("/etc/initrd-release", F_OK) >= 0 &&
- statfs("/", &s) >= 0 &&
- is_temporary_fs(&s);
+ saved_in_initrd = access("/etc/initrd-release", F_OK) >= 0 &&
+ statfs("/", &s) >= 0 &&
+ is_temporary_fs(&s);
- return saved;
+ return saved_in_initrd;
+}
+
+void in_initrd_force(bool value) {
+ saved_in_initrd = value;
}
/* hey glibc, APIs with callbacks without a user pointer are so useless */
@@ -767,15 +772,64 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
}
uint64_t physical_memory(void) {
- long mem;
+ _cleanup_free_ char *root = NULL, *value = NULL;
+ uint64_t mem, lim;
+ size_t ps;
+ long sc;
+
+ /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of
+ * memory.
+ *
+ * In order to support containers nicely that have a configured memory limit we'll take the minimum of the
+ * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */
+
+ sc = sysconf(_SC_PHYS_PAGES);
+ assert(sc > 0);
+
+ ps = page_size();
+ mem = (uint64_t) sc * (uint64_t) ps;
+
+ if (cg_get_root_path(&root) < 0)
+ return mem;
+
+ if (cg_get_attribute("memory", root, "memory.limit_in_bytes", &value))
+ return mem;
+
+ if (safe_atou64(value, &lim) < 0)
+ return mem;
+
+ /* Make sure the limit is a multiple of our own page size */
+ lim /= ps;
+ lim *= ps;
+
+ return MIN(mem, lim);
+}
+
+uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
+ uint64_t p, m, ps, r;
+
+ assert(max > 0);
+
+ /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
+ * the result is a multiple of the page size (rounds down). */
+
+ ps = page_size();
+ assert(ps > 0);
+
+ p = physical_memory() / ps;
+ assert(p > 0);
+
+ m = p * v;
+ if (m / p != v)
+ return UINT64_MAX;
- /* We return this as uint64_t in case we are running as 32bit
- * process on a 64bit kernel with huge amounts of memory */
+ m /= max;
- mem = sysconf(_SC_PHYS_PAGES);
- assert(mem > 0);
+ r = m * ps;
+ if (r / ps != m)
+ return UINT64_MAX;
- return (uint64_t) mem * (uint64_t) page_size();
+ return r;
}
int update_reboot_parameter_and_warn(const char *param) {
diff --git a/src/basic/util.h b/src/basic/util.h
index 1c032c15c9..db105197e8 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -86,6 +86,7 @@ int prot_from_flags(int flags) _const_;
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
bool in_initrd(void);
+void in_initrd_force(bool value);
void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
int (*compar) (const void *, const void *, void *),
@@ -183,6 +184,7 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
uint64_t physical_memory(void);
+uint64_t physical_memory_scale(uint64_t v, uint64_t max);
int update_reboot_parameter_and_warn(const char *param);
diff --git a/src/core/busname.c b/src/core/busname.c
index f03a95c24e..730be2ee14 100644
--- a/src/core/busname.c
+++ b/src/core/busname.c
@@ -998,12 +998,7 @@ static int busname_get_timeout(Unit *u, usec_t *timeout) {
}
static bool busname_supported(void) {
- static int supported = -1;
-
- if (supported < 0)
- supported = is_kdbus_available();
-
- return supported;
+ return false;
}
static int busname_control_pid(Unit *u) {
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index f3e0c54b76..799296ad28 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -1723,7 +1723,7 @@ int manager_setup_cgroup(Manager *m) {
return log_error_errno(r, "Failed to determine supported controllers: %m");
for (c = 0; c < _CGROUP_CONTROLLER_MAX; c++)
- log_debug("Controller '%s' supported: %s", cgroup_controller_to_string(c), yes_no(m->cgroup_supported & c));
+ log_debug("Controller '%s' supported: %s", cgroup_controller_to_string(c), yes_no(m->cgroup_supported & CGROUP_CONTROLLER_TO_MASK(c)));
return 0;
}
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index 8525fa1bf1..27bbe2d26d 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -641,7 +641,7 @@ int bus_cgroup_set_property(
return 1;
- } else if (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth")) {
+ } else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
const char *path;
bool read = true;
unsigned n = 0;
@@ -835,6 +835,8 @@ int bus_cgroup_set_property(
r = sd_bus_message_read(message, "t", &v);
if (r < 0)
return r;
+ if (v <= 0)
+ return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name);
if (mode != UNIT_CHECK) {
if (streq(name, "MemoryLow"))
@@ -847,19 +849,53 @@ int bus_cgroup_set_property(
unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
if (v == CGROUP_LIMIT_MAX)
- unit_write_drop_in_private_format(u, mode, name, "%s=max", name);
+ unit_write_drop_in_private_format(u, mode, name, "%s=infinity", name);
else
unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, v);
}
return 1;
+ } else if (STR_IN_SET(name, "MemoryLowByPhysicalMemory", "MemoryHighByPhysicalMemory", "MemoryMaxByPhysicalMemory")) {
+ uint32_t raw;
+ uint64_t v;
+
+ r = sd_bus_message_read(message, "u", &raw);
+ if (r < 0)
+ return r;
+
+ v = physical_memory_scale(raw, UINT32_MAX);
+ if (v <= 0 || v == UINT64_MAX)
+ return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name);
+
+ if (mode != UNIT_CHECK) {
+ const char *e;
+
+ /* Chop off suffix */
+ assert_se(e = endswith(name, "ByPhysicalMemory"));
+ name = strndupa(name, e - name);
+
+ if (streq(name, "MemoryLow"))
+ c->memory_low = v;
+ else if (streq(name, "MemoryHigh"))
+ c->memory_high = v;
+ else
+ c->memory_max = v;
+
+ unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
+ unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu32 "%%", name, (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100, (uint64_t) UINT32_MAX)));
+ }
+
+ return 1;
+
} else if (streq(name, "MemoryLimit")) {
uint64_t limit;
r = sd_bus_message_read(message, "t", &limit);
if (r < 0)
return r;
+ if (limit <= 0)
+ return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name);
if (mode != UNIT_CHECK) {
c->memory_limit = limit;
@@ -873,6 +909,26 @@ int bus_cgroup_set_property(
return 1;
+ } else if (streq(name, "MemoryLimitByPhysicalMemory")) {
+ uint64_t limit;
+ uint32_t raw;
+
+ r = sd_bus_message_read(message, "u", &raw);
+ if (r < 0)
+ return r;
+
+ limit = physical_memory_scale(raw, UINT32_MAX);
+ if (limit <= 0 || limit == UINT64_MAX)
+ return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name);
+
+ if (mode != UNIT_CHECK) {
+ c->memory_limit = limit;
+ unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
+ unit_write_drop_in_private_format(u, mode, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%", (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100, (uint64_t) UINT32_MAX)));
+ }
+
+ return 1;
+
} else if (streq(name, "DevicePolicy")) {
const char *policy;
CGroupDevicePolicy p;
diff --git a/src/core/execute.c b/src/core/execute.c
index c20650626c..3c3369373f 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -289,7 +289,15 @@ static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
return r;
}
-static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd, uid_t uid, gid_t gid) {
+static int connect_logger_as(
+ const ExecContext *context,
+ ExecOutput output,
+ const char *ident,
+ const char *unit_id,
+ int nfd,
+ uid_t uid,
+ gid_t gid) {
+
int fd, r;
assert(context);
@@ -310,7 +318,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons
return -errno;
}
- fd_inc_sndbuf(fd, SNDBUF_SIZE);
+ (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
dprintf(fd,
"%s\n"
@@ -328,11 +336,11 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons
output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
is_terminal_output(output));
- if (fd != nfd) {
- r = dup2(fd, nfd) < 0 ? -errno : nfd;
- safe_close(fd);
- } else
- r = nfd;
+ if (fd == nfd)
+ return nfd;
+
+ r = dup2(fd, nfd) < 0 ? -errno : nfd;
+ safe_close(fd);
return r;
}
@@ -446,7 +454,10 @@ static int setup_output(
int fileno,
int socket_fd,
const char *ident,
- uid_t uid, gid_t gid) {
+ uid_t uid,
+ gid_t gid,
+ dev_t *journal_stream_dev,
+ ino_t *journal_stream_ino) {
ExecOutput o;
ExecInput i;
@@ -456,6 +467,8 @@ static int setup_output(
assert(context);
assert(params);
assert(ident);
+ assert(journal_stream_dev);
+ assert(journal_stream_ino);
if (fileno == STDOUT_FILENO && params->stdout_fd >= 0) {
@@ -535,6 +548,17 @@ static int setup_output(
if (r < 0) {
log_unit_error_errno(unit, r, "Failed to connect %s to the journal socket, ignoring: %m", fileno == STDOUT_FILENO ? "stdout" : "stderr");
r = open_null_as(O_WRONLY, fileno);
+ } else {
+ struct stat st;
+
+ /* If we connected this fd to the journal via a stream, patch the device/inode into the passed
+ * parameters, but only then. This is useful so that we can set $JOURNAL_STREAM that permits
+ * services to detect whether they are connected to the journal or not. */
+
+ if (fstat(fileno, &st) >= 0) {
+ *journal_stream_dev = st.st_dev;
+ *journal_stream_ino = st.st_ino;
+ }
}
return r;
@@ -1278,6 +1302,8 @@ static int build_environment(
const char *home,
const char *username,
const char *shell,
+ dev_t journal_stream_dev,
+ ino_t journal_stream_ino,
char ***ret) {
_cleanup_strv_free_ char **our_env = NULL;
@@ -1287,7 +1313,7 @@ static int build_environment(
assert(c);
assert(ret);
- our_env = new0(char*, 11);
+ our_env = new0(char*, 12);
if (!our_env)
return -ENOMEM;
@@ -1359,8 +1385,15 @@ static int build_environment(
our_env[n_env++] = x;
}
+ if (journal_stream_dev != 0 && journal_stream_ino != 0) {
+ if (asprintf(&x, "JOURNAL_STREAM=" DEV_FMT ":" INO_FMT, journal_stream_dev, journal_stream_ino) < 0)
+ return -ENOMEM;
+
+ our_env[n_env++] = x;
+ }
+
our_env[n_env++] = NULL;
- assert(n_env <= 11);
+ assert(n_env <= 12);
*ret = our_env;
our_env = NULL;
@@ -1473,10 +1506,12 @@ static int exec_child(
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL;
_cleanup_free_ char *mac_selinux_context_net = NULL;
const char *username = NULL, *home = NULL, *shell = NULL, *wd;
+ dev_t journal_stream_dev = 0;
+ ino_t journal_stream_ino = 0;
+ bool needs_mount_namespace;
uid_t uid = UID_INVALID;
gid_t gid = GID_INVALID;
int i, r;
- bool needs_mount_namespace;
assert(unit);
assert(command);
@@ -1576,13 +1611,13 @@ static int exec_child(
return r;
}
- r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid);
+ r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino);
if (r < 0) {
*exit_status = EXIT_STDOUT;
return r;
}
- r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid);
+ r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino);
if (r < 0) {
*exit_status = EXIT_STDERR;
return r;
@@ -1721,7 +1756,16 @@ static int exec_child(
}
}
- r = build_environment(context, params, n_fds, home, username, shell, &our_env);
+ r = build_environment(
+ context,
+ params,
+ n_fds,
+ home,
+ username,
+ shell,
+ journal_stream_dev,
+ journal_stream_ino,
+ &our_env);
if (r < 0) {
*exit_status = EXIT_MEMORY;
return r;
diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c
index 3503db52ed..fd1021f706 100644
--- a/src/core/kmod-setup.c
+++ b/src/core/kmod-setup.c
@@ -64,9 +64,6 @@ int kmod_setup(void) {
/* this should never be a module */
{ "unix", "/proc/net/unix", true, true, NULL },
- /* IPC is needed before we bring up any other services */
- { "kdbus", "/sys/fs/kdbus", false, false, is_kdbus_wanted },
-
#ifdef HAVE_LIBIPTC
/* netfilter is needed by networkd, nspawn among others, and cannot be autoloaded */
{ "ip_tables", "/proc/net/ip_tables_names", false, false, NULL },
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 17c72aed88..8295cf45a6 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2774,7 +2774,7 @@ int config_parse_cpu_quota(
void *userdata) {
CGroupContext *c = data;
- double percent;
+ int r;
assert(filename);
assert(lvalue);
@@ -2785,18 +2785,13 @@ int config_parse_cpu_quota(
return 0;
}
- if (!endswith(rvalue, "%")) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "CPU quota '%s' not ending in '%%'. Ignoring.", rvalue);
- return 0;
- }
-
- if (sscanf(rvalue, "%lf%%", &percent) != 1 || percent <= 0) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "CPU quota '%s' invalid. Ignoring.", rvalue);
+ r = parse_percent(rvalue);
+ if (r <= 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "CPU quota '%s' invalid. Ignoring.", rvalue);
return 0;
}
- c->cpu_quota_per_sec_usec = (usec_t) (percent * USEC_PER_SEC / 100);
-
+ c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 100U;
return 0;
}
@@ -2817,9 +2812,19 @@ int config_parse_memory_limit(
int r;
if (!isempty(rvalue) && !streq(rvalue, "infinity")) {
- r = parse_size(rvalue, 1024, &bytes);
- if (r < 0 || bytes < 1) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Memory limit '%s' invalid. Ignoring.", rvalue);
+
+ r = parse_percent(rvalue);
+ if (r < 0) {
+ r = parse_size(rvalue, 1024, &bytes);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Memory limit '%s' invalid. Ignoring.", rvalue);
+ return 0;
+ }
+ } else
+ bytes = physical_memory_scale(r, 100U);
+
+ if (bytes < 1) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' too small. Ignoring.", rvalue);
return 0;
}
}
@@ -3830,7 +3835,15 @@ static int load_from_path(Unit *u, const char *path) {
if (r >= 0)
break;
filename = mfree(filename);
- if (r != -ENOENT)
+
+ /* ENOENT means that the file is missing or is a dangling symlink.
+ * ENOTDIR means that one of paths we expect to be is a directory
+ * is not a directory, we should just ignore that.
+ * EACCES means that the directory or file permissions are wrong.
+ */
+ if (r == -EACCES)
+ log_debug_errno(r, "Cannot access \"%s\": %m", filename);
+ else if (!IN_SET(r, -ENOENT, -ENOTDIR))
return r;
/* Empty the symlink names for the next run */
diff --git a/src/core/main.c b/src/core/main.c
index 6124a984c3..237c9c9ebe 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -409,7 +409,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
if (detect_container() > 0)
log_set_target(LOG_TARGET_CONSOLE);
- } else if (!in_initrd() && !value) {
+ } else if (!value) {
const char *target;
/* SysV compatibility */
diff --git a/src/core/manager.c b/src/core/manager.c
index ec8acdff5b..012aa6cd53 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -814,28 +814,6 @@ static int manager_setup_cgroups_agent(Manager *m) {
return 0;
}
-static int manager_setup_kdbus(Manager *m) {
- _cleanup_free_ char *p = NULL;
-
- assert(m);
-
- if (m->test_run || m->kdbus_fd >= 0)
- return 0;
- if (!is_kdbus_available())
- return -ESOCKTNOSUPPORT;
-
- m->kdbus_fd = bus_kernel_create_bus(
- MANAGER_IS_SYSTEM(m) ? "system" : "user",
- MANAGER_IS_SYSTEM(m), &p);
-
- if (m->kdbus_fd < 0)
- return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m");
-
- log_debug("Successfully set up kdbus on %s", p);
-
- return 0;
-}
-
static int manager_connect_bus(Manager *m, bool reexecuting) {
bool try_bus_connect;
@@ -877,6 +855,19 @@ enum {
_GC_OFFSET_MAX
};
+static void unit_gc_mark_good(Unit *u, unsigned gc_marker)
+{
+ Iterator i;
+ Unit *other;
+
+ u->gc_marker = gc_marker + GC_OFFSET_GOOD;
+
+ /* Recursively mark referenced units as GOOD as well */
+ SET_FOREACH(other, u->dependencies[UNIT_REFERENCES], i)
+ if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
+ unit_gc_mark_good(other, gc_marker);
+}
+
static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
Iterator i;
Unit *other;
@@ -886,6 +877,7 @@ static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
u->gc_marker == gc_marker + GC_OFFSET_BAD ||
+ u->gc_marker == gc_marker + GC_OFFSET_UNSURE ||
u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
return;
@@ -926,7 +918,7 @@ bad:
return;
good:
- u->gc_marker = gc_marker + GC_OFFSET_GOOD;
+ unit_gc_mark_good(u, gc_marker);
}
static unsigned manager_dispatch_gc_queue(Manager *m) {
@@ -1230,7 +1222,6 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
/* We might have deserialized the kdbus control fd, but if we
* didn't, then let's create the bus now. */
- manager_setup_kdbus(m);
manager_connect_bus(m, !!serialization);
bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);
diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index 40fc548b42..f9c9b4a91f 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -108,8 +108,6 @@ static const MountPoint mount_table[] = {
{ "efivarfs", "/sys/firmware/efi/efivars", "efivarfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
is_efi_boot, MNT_NONE },
#endif
- { "kdbusfs", "/sys/fs/kdbus", "kdbusfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
- is_kdbus_wanted, MNT_IN_CONTAINER },
};
/* These are API file systems that might be mounted by other software,
diff --git a/src/core/scope.c b/src/core/scope.c
index 238f63a729..decd1a1f3f 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -428,8 +428,9 @@ static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
unit_tidy_watch_pids(u, 0, 0);
unit_watch_all_pids(u);
- /* If the PID set is empty now, then let's finish this off */
- if (set_isempty(u->pids))
+ /* If the PID set is empty now, then let's finish this off
+ (On unified we use proper notifications) */
+ if (cg_unified() <= 0 && set_isempty(u->pids))
scope_notify_cgroup_empty_event(u);
}
diff --git a/src/core/service.c b/src/core/service.c
index 7ebabca5d6..78c33b1530 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -574,20 +574,9 @@ static int service_setup_bus_name(Service *s) {
if (!s->bus_name)
return 0;
- if (is_kdbus_available()) {
- const char *n;
-
- n = strjoina(s->bus_name, ".busname");
- r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
- if (r < 0)
- return log_unit_error_errno(UNIT(s), r, "Failed to add dependency to .busname unit: %m");
-
- } else {
- /* If kdbus is not available, we know the dbus socket is required, hence pull it in, and require it */
- r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
- if (r < 0)
- return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
- }
+ r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
+ if (r < 0)
+ return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
/* Regardless if kdbus is used or not, we always want to be ordered against dbus.socket if both are in the transaction. */
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true);
@@ -2800,8 +2789,9 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
unit_tidy_watch_pids(u, s->main_pid, s->control_pid);
unit_watch_all_pids(u);
- /* If the PID set is empty now, then let's finish this off */
- if (set_isempty(u->pids))
+ /* If the PID set is empty now, then let's finish this off
+ (On unified we use proper notifications) */
+ if (cg_unified() <= 0 && set_isempty(u->pids))
service_notify_cgroup_empty_event(u);
}
diff --git a/src/core/socket.c b/src/core/socket.c
index f6204d04bf..e098055885 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -730,16 +730,16 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
case AF_INET: {
uint32_t
- a = ntohl(local.in.sin_addr.s_addr),
- b = ntohl(remote.in.sin_addr.s_addr);
+ a = be32toh(local.in.sin_addr.s_addr),
+ b = be32toh(remote.in.sin_addr.s_addr);
if (asprintf(&r,
"%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
nr,
a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
- ntohs(local.in.sin_port),
+ be16toh(local.in.sin_port),
b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
- ntohs(remote.in.sin_port)) < 0)
+ be16toh(remote.in.sin_port)) < 0)
return -ENOMEM;
break;
@@ -760,9 +760,9 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
"%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
nr,
a[0], a[1], a[2], a[3],
- ntohs(local.in6.sin6_port),
+ be16toh(local.in6.sin6_port),
b[0], b[1], b[2], b[3],
- ntohs(remote.in6.sin6_port)) < 0)
+ be16toh(remote.in6.sin6_port)) < 0)
return -ENOMEM;
} else {
char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
@@ -771,9 +771,9 @@ static int instance_from_socket(int fd, unsigned nr, char **instance) {
"%u-%s:%u-%s:%u",
nr,
inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
- ntohs(local.in6.sin6_port),
+ be16toh(local.in6.sin6_port),
inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
- ntohs(remote.in6.sin6_port)) < 0)
+ be16toh(remote.in6.sin6_port)) < 0)
return -ENOMEM;
}
diff --git a/src/core/unit.c b/src/core/unit.c
index e98086a3f6..581962eba6 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3375,7 +3375,7 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co
return -EINVAL;
wrapped = strjoina("# This is a drop-in unit file extension, created via \"systemctl set-property\"\n"
- "or an equivalent operation. Do not edit.\n",
+ "# or an equivalent operation. Do not edit.\n",
data,
"\n");
diff --git a/src/dbus1-generator/dbus1-generator.c b/src/dbus1-generator/dbus1-generator.c
deleted file mode 100644
index 717cb9558e..0000000000
--- a/src/dbus1-generator/dbus1-generator.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/***
- 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 "alloc-util.h"
-#include "bus-internal.h"
-#include "bus-util.h"
-#include "cgroup-util.h"
-#include "conf-parser.h"
-#include "dirent-util.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "mkdir.h"
-#include "special.h"
-#include "unit-name.h"
-#include "util.h"
-
-static const char *arg_dest_late = "/tmp", *arg_dest = "/tmp";
-
-static int create_dbus_files(
- const char *path,
- const char *name,
- const char *service,
- const char *exec,
- const char *user,
- const char *type) {
-
- _cleanup_free_ char *b = NULL, *s = NULL, *lnk = NULL;
- _cleanup_fclose_ FILE *f = NULL;
- int r;
-
- assert(path);
- assert(name);
- assert(service || exec);
-
- if (!service) {
- _cleanup_free_ char *a = NULL;
-
- s = strjoin("dbus-", name, ".service", NULL);
- if (!s)
- return log_oom();
-
- a = strjoin(arg_dest_late, "/", s, NULL);
- if (!a)
- return log_oom();
-
- f = fopen(a, "wxe");
- if (!f)
- return log_error_errno(errno, "Failed to create %s: %m", a);
-
- fprintf(f,
- "# Automatically generated by systemd-dbus1-generator\n\n"
- "[Unit]\n"
- "SourcePath=%s\n"
- "Description=DBUS1: %s\n"
- "Documentation=man:systemd-dbus1-generator(8)\n\n"
- "[Service]\n"
- "ExecStart=%s\n"
- "Type=dbus\n"
- "BusName=%s\n",
- path,
- name,
- exec,
- name);
-
- if (user)
- fprintf(f, "User=%s\n", user);
-
-
- if (type) {
- fprintf(f, "Environment=DBUS_STARTER_BUS_TYPE=%s\n", type);
-
- if (streq(type, "system"))
- fprintf(f, "Environment=DBUS_STARTER_ADDRESS=" DEFAULT_SYSTEM_BUS_ADDRESS "\n");
- else if (streq(type, "session")) {
- char *run;
-
- run = getenv("XDG_RUNTIME_DIR");
- if (!run) {
- log_error("XDG_RUNTIME_DIR not set.");
- return -EINVAL;
- }
-
- fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT "\n",
- getuid(), run);
- }
- }
-
- r = fflush_and_check(f);
- if (r < 0)
- return log_error_errno(r, "Failed to write %s: %m", a);
-
- f = safe_fclose(f);
-
- service = s;
- }
-
- b = strjoin(arg_dest_late, "/", name, ".busname", NULL);
- if (!b)
- return log_oom();
-
- f = fopen(b, "wxe");
- if (!f)
- return log_error_errno(errno, "Failed to create %s: %m", b);
-
- fprintf(f,
- "# Automatically generated by systemd-dbus1-generator\n\n"
- "[Unit]\n"
- "SourcePath=%s\n"
- "Description=DBUS1: %s\n"
- "Documentation=man:systemd-dbus1-generator(8)\n\n"
- "[BusName]\n"
- "Name=%s\n"
- "Service=%s\n"
- "AllowWorld=talk\n",
- path,
- name,
- name,
- service);
-
- r = fflush_and_check(f);
- if (r < 0)
- return log_error_errno(r, "Failed to write %s: %m", b);
-
- lnk = strjoin(arg_dest_late, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL);
- if (!lnk)
- return log_oom();
-
- mkdir_parents_label(lnk, 0755);
- if (symlink(b, lnk))
- return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
-
- return 0;
-}
-
-static int add_dbus(const char *path, const char *fname, const char *type) {
- _cleanup_free_ char *name = NULL, *exec = NULL, *user = NULL, *service = NULL;
-
- const ConfigTableItem table[] = {
- { "D-BUS Service", "Name", config_parse_string, 0, &name },
- { "D-BUS Service", "Exec", config_parse_string, 0, &exec },
- { "D-BUS Service", "User", config_parse_string, 0, &user },
- { "D-BUS Service", "SystemdService", config_parse_string, 0, &service },
- { },
- };
-
- char *p;
- int r;
-
- assert(path);
- assert(fname);
-
- p = strjoina(path, "/", fname);
- r = config_parse(NULL, p, NULL,
- "D-BUS Service\0",
- config_item_table_lookup, table,
- true, false, true, NULL);
- if (r < 0)
- return r;
-
- if (!name) {
- log_warning("Activation file %s lacks name setting, ignoring.", p);
- return 0;
- }
-
- if (!service_name_is_valid(name)) {
- log_warning("Bus service name %s is not valid, ignoring.", name);
- return 0;
- }
-
- if (streq(name, "org.freedesktop.systemd1")) {
- log_debug("Skipping %s, identified as systemd.", p);
- return 0;
- }
-
- if (service) {
- if (!unit_name_is_valid(service, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
- log_warning("Unit name %s is not valid, ignoring.", service);
- return 0;
- }
- if (!endswith(service, ".service")) {
- log_warning("Bus names can only activate services, ignoring %s.", p);
- return 0;
- }
- } else {
- if (streq(exec, "/bin/false") || !exec) {
- log_warning("Neither service name nor binary path specified, ignoring %s.", p);
- return 0;
- }
-
- if (exec[0] != '/') {
- log_warning("Exec= in %s does not start with an absolute path, ignoring.", p);
- return 0;
- }
- }
-
- return create_dbus_files(p, name, service, exec, user, type);
-}
-
-static int parse_dbus_fragments(const char *path, const char *type) {
- _cleanup_closedir_ DIR *d = NULL;
- struct dirent *de;
- int r;
-
- assert(path);
- assert(type);
-
- d = opendir(path);
- if (!d) {
- if (errno == -ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to enumerate D-Bus activated services: %m");
- }
-
- r = 0;
- FOREACH_DIRENT(de, d, goto fail) {
- int q;
-
- if (!endswith(de->d_name, ".service"))
- continue;
-
- q = add_dbus(path, de->d_name, type);
- if (q < 0)
- r = q;
- }
-
- return r;
-
-fail:
- return log_error_errno(errno, "Failed to read D-Bus services directory: %m");
-}
-
-static int link_busnames_target(const char *units) {
- const char *f, *t;
-
- f = strjoina(units, "/" SPECIAL_BUSNAMES_TARGET);
- t = strjoina(arg_dest, "/" SPECIAL_BASIC_TARGET ".wants/" SPECIAL_BUSNAMES_TARGET);
-
- mkdir_parents_label(t, 0755);
- if (symlink(f, t) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", t);
-
- return 0;
-}
-
-static int link_compatibility(const char *units) {
- const char *f, *t;
-
- f = strjoina(units, "/systemd-bus-proxyd.socket");
- t = strjoina(arg_dest, "/" SPECIAL_DBUS_SOCKET);
- mkdir_parents_label(t, 0755);
- if (symlink(f, t) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", t);
-
- f = strjoina(units, "/systemd-bus-proxyd.socket");
- t = strjoina(arg_dest, "/" SPECIAL_SOCKETS_TARGET ".wants/systemd-bus-proxyd.socket");
- mkdir_parents_label(t, 0755);
- if (symlink(f, t) < 0)
- return log_error_errno(errno, "Failed to create symlink %s: %m", t);
-
- t = strjoina(arg_dest, "/" SPECIAL_DBUS_SERVICE);
- if (symlink("/dev/null", t) < 0)
- return log_error_errno(errno, "Failed to mask %s: %m", t);
-
- return 0;
-}
-
-int main(int argc, char *argv[]) {
- const char *path, *type, *units;
- int r, q;
-
- if (argc > 1 && argc != 4) {
- log_error("This program takes three or no arguments.");
- return EXIT_FAILURE;
- }
-
- if (argc > 1) {
- arg_dest = argv[1];
- arg_dest_late = argv[3];
- }
-
- log_set_target(LOG_TARGET_SAFE);
- log_parse_environment();
- log_open();
-
- umask(0022);
-
- if (!is_kdbus_available())
- return 0;
-
- r = cg_pid_get_owner_uid(0, NULL);
- if (r >= 0) {
- path = "/usr/share/dbus-1/services";
- type = "session";
- units = USER_DATA_UNIT_PATH;
- } else if (r == -ENXIO) {
- path = "/usr/share/dbus-1/system-services";
- type = "system";
- units = SYSTEM_DATA_UNIT_PATH;
- } else
- return log_error_errno(r, "Failed to determine whether we are running as user or system instance: %m");
-
- r = parse_dbus_fragments(path, type);
-
- /* FIXME: One day this should just be pulled in statically from basic.target */
- q = link_busnames_target(units);
- if (q < 0)
- r = q;
-
- q = link_compatibility(units);
- if (q < 0)
- r = q;
-
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-}
diff --git a/src/libsystemd-network/arp-util.c b/src/libsystemd-network/arp-util.c
index 4660c7ea09..02028bf28a 100644
--- a/src/libsystemd-network/arp-util.c
+++ b/src/libsystemd-network/arp-util.c
@@ -79,7 +79,7 @@ int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_
};
union sockaddr_union link = {
.ll.sll_family = AF_PACKET,
- .ll.sll_protocol = htons(ETH_P_ARP),
+ .ll.sll_protocol = htobe16(ETH_P_ARP),
.ll.sll_ifindex = ifindex,
.ll.sll_halen = ETH_ALEN,
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
@@ -112,17 +112,17 @@ static int arp_send_packet(int fd, int ifindex,
bool announce) {
union sockaddr_union link = {
.ll.sll_family = AF_PACKET,
- .ll.sll_protocol = htons(ETH_P_ARP),
+ .ll.sll_protocol = htobe16(ETH_P_ARP),
.ll.sll_ifindex = ifindex,
.ll.sll_halen = ETH_ALEN,
.ll.sll_addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
};
struct ether_arp arp = {
- .ea_hdr.ar_hrd = htons(ARPHRD_ETHER), /* HTYPE */
- .ea_hdr.ar_pro = htons(ETHERTYPE_IP), /* PTYPE */
+ .ea_hdr.ar_hrd = htobe16(ARPHRD_ETHER), /* HTYPE */
+ .ea_hdr.ar_pro = htobe16(ETHERTYPE_IP), /* PTYPE */
.ea_hdr.ar_hln = ETH_ALEN, /* HLEN */
.ea_hdr.ar_pln = sizeof(be32_t), /* PLEN */
- .ea_hdr.ar_op = htons(ARPOP_REQUEST), /* REQUEST */
+ .ea_hdr.ar_op = htobe16(ARPOP_REQUEST), /* REQUEST */
};
int r;
diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c
index fac25e0fa2..a9f5a0a5de 100644
--- a/src/libsystemd-network/dhcp-network.c
+++ b/src/libsystemd-network/dhcp-network.c
@@ -107,9 +107,9 @@ static int _bind_raw_socket(int ifindex, union sockaddr_union *link,
return -errno;
link->ll.sll_family = AF_PACKET;
- link->ll.sll_protocol = htons(ETH_P_IP);
+ link->ll.sll_protocol = htobe16(ETH_P_IP);
link->ll.sll_ifindex = ifindex;
- link->ll.sll_hatype = htons(arp_type);
+ link->ll.sll_hatype = htobe16(arp_type);
link->ll.sll_halen = mac_addr_len;
memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len);
diff --git a/src/libsystemd-network/lldp-network.c b/src/libsystemd-network/lldp-network.c
index f031760351..59c25598e9 100644
--- a/src/libsystemd-network/lldp-network.c
+++ b/src/libsystemd-network/lldp-network.c
@@ -57,7 +57,8 @@ int lldp_network_bind_raw_socket(int ifindex) {
assert(ifindex > 0);
- fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, htons(ETHERTYPE_LLDP));
+ fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK,
+ htobe16(ETHERTYPE_LLDP));
if (fd < 0)
return -errno;
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index ea4f03df1d..11ee2e252e 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -260,7 +260,7 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
DHCPPacket *packet, size_t len) {
union sockaddr_union link = {
.ll.sll_family = AF_PACKET,
- .ll.sll_protocol = htons(ETH_P_IP),
+ .ll.sll_protocol = htobe16(ETH_P_IP),
.ll.sll_ifindex = server->ifindex,
.ll.sll_halen = ETH_ALEN,
};
diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c
index ea3fe369ce..07b0d7f704 100644
--- a/src/libsystemd-network/sd-ndisc.c
+++ b/src/libsystemd-network/sd-ndisc.c
@@ -307,7 +307,7 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
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(CMSG_DATA(cmsg)));
+ triple_timestamp_from_realtime(&rt->timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
}
if (!triple_timestamp_is_set(&rt->timestamp))
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index bfe967bfb0..eb042e9c81 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -1987,7 +1987,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ sd_bus *bus = NULL;
int r;
log_parse_environment();
@@ -2078,6 +2078,7 @@ int main(int argc, char *argv[]) {
r = busctl_main(bus, argc, argv);
finish:
+ sd_bus_flush_close_unref(bus);
pager_close();
strv_free(arg_matches);
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 4da9dbfd63..b20a7ebb4c 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -310,12 +310,12 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
if (l < sizeof(struct sockaddr_in))
return -EINVAL;
- return htons(port) == sockaddr.in.sin_port;
+ return htobe16(port) == sockaddr.in.sin_port;
} else {
if (l < sizeof(struct sockaddr_in6))
return -EINVAL;
- return htons(port) == sockaddr.in6.sin6_port;
+ return htobe16(port) == sockaddr.in6.sin6_port;
}
}
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 3a4bac2ced..566a050432 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -278,6 +278,10 @@ static const NLType rtnl_link_info_data_ip6tnl_types[] = {
[IFLA_IPTUN_FLOWINFO] = { .type = NETLINK_TYPE_U32 },
};
+static const NLType rtnl_link_info_data_vrf_types[] = {
+ [IFLA_VRF_TABLE] = { .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",
@@ -298,6 +302,7 @@ static const char* const nl_union_link_info_data_table[] = {
[NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = "vti",
[NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = "vti6",
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = "ip6tnl",
+ [NL_UNION_LINK_INFO_DATA_VRF] = "vrf",
};
DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData);
@@ -338,6 +343,9 @@ static const NLTypeSystem rtnl_link_info_data_type_systems[] = {
[NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types),
.types = rtnl_link_info_data_ip6tnl_types },
+ [NL_UNION_LINK_INFO_DATA_VRF] = { .count = ELEMENTSOF(rtnl_link_info_data_vrf_types),
+ .types = rtnl_link_info_data_vrf_types },
+
};
static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h
index ecb20bfcdc..7c0e598b26 100644
--- a/src/libsystemd/sd-netlink/netlink-types.h
+++ b/src/libsystemd/sd-netlink/netlink-types.h
@@ -86,6 +86,7 @@ typedef enum NLUnionLinkInfoData {
NL_UNION_LINK_INFO_DATA_VTI_TUNNEL,
NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL,
NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL,
+ NL_UNION_LINK_INFO_DATA_VRF,
_NL_UNION_LINK_INFO_DATA_MAX,
_NL_UNION_LINK_INFO_DATA_INVALID = -1
} NLUnionLinkInfoData;
diff --git a/src/libudev/libudev-monitor.c b/src/libudev/libudev-monitor.c
index f870eba9eb..1f9d16c450 100644
--- a/src/libudev/libudev-monitor.c
+++ b/src/libudev/libudev-monitor.c
@@ -650,9 +650,9 @@ retry:
if (memcmp(buf.raw, "libudev", 8) == 0) {
/* udev message needs proper version magic */
- if (buf.nlh.magic != htonl(UDEV_MONITOR_MAGIC)) {
+ if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC)) {
log_debug("unrecognized message signature (%x != %x)",
- buf.nlh.magic, htonl(UDEV_MONITOR_MAGIC));
+ buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC));
return NULL;
}
if (buf.nlh.properties_off+32 > (size_t)buflen) {
@@ -715,7 +715,7 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor,
ssize_t blen, count;
struct udev_monitor_netlink_header nlh = {
.prefix = "libudev",
- .magic = htonl(UDEV_MONITOR_MAGIC),
+ .magic = htobe32(UDEV_MONITOR_MAGIC),
.header_size = sizeof nlh,
};
struct iovec iov[2] = {
@@ -736,19 +736,19 @@ int udev_monitor_send_device(struct udev_monitor *udev_monitor,
/* fill in versioned header */
val = udev_device_get_subsystem(udev_device);
- nlh.filter_subsystem_hash = htonl(util_string_hash32(val));
+ nlh.filter_subsystem_hash = htobe32(util_string_hash32(val));
val = udev_device_get_devtype(udev_device);
if (val != NULL)
- nlh.filter_devtype_hash = htonl(util_string_hash32(val));
+ nlh.filter_devtype_hash = htobe32(util_string_hash32(val));
/* add tag bloom filter */
tag_bloom_bits = 0;
udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
tag_bloom_bits |= util_string_bloom64(udev_list_entry_get_name(list_entry));
if (tag_bloom_bits > 0) {
- nlh.filter_tag_bloom_hi = htonl(tag_bloom_bits >> 32);
- nlh.filter_tag_bloom_lo = htonl(tag_bloom_bits & 0xffffffff);
+ nlh.filter_tag_bloom_hi = htobe32(tag_bloom_bits >> 32);
+ nlh.filter_tag_bloom_lo = htobe32(tag_bloom_bits & 0xffffffff);
}
/* add properties list */
diff --git a/src/locale/keymap-util.c b/src/locale/keymap-util.c
new file mode 100644
index 0000000000..a6bcd1ad54
--- /dev/null
+++ b/src/locale/keymap-util.c
@@ -0,0 +1,724 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2011 Lennart Poettering
+ Copyright 2013 Kay Sievers
+
+ 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 <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "def.h"
+#include "env-util.h"
+#include "fd-util.h"
+#include "fileio-label.h"
+#include "fileio.h"
+#include "keymap-util.h"
+#include "locale-util.h"
+#include "macro.h"
+#include "mkdir.h"
+#include "string-util.h"
+#include "strv.h"
+
+static bool startswith_comma(const char *s, const char *prefix) {
+ s = startswith(s, prefix);
+ if (!s)
+ return false;
+
+ return *s == ',' || *s == '\0';
+}
+
+static const char* strnulldash(const char *s) {
+ return isempty(s) || streq(s, "-") ? NULL : s;
+}
+
+static const char* systemd_kbd_model_map(void) {
+ const char* s;
+
+ s = getenv("SYSTEMD_KBD_MODEL_MAP");
+ if (s)
+ return s;
+
+ return SYSTEMD_KBD_MODEL_MAP;
+}
+
+static const char* systemd_language_fallback_map(void) {
+ const char* s;
+
+ s = getenv("SYSTEMD_LANGUAGE_FALLBACK_MAP");
+ if (s)
+ return s;
+
+ return SYSTEMD_LANGUAGE_FALLBACK_MAP;
+}
+
+static void context_free_x11(Context *c) {
+ c->x11_layout = mfree(c->x11_layout);
+ c->x11_options = mfree(c->x11_options);
+ c->x11_model = mfree(c->x11_model);
+ c->x11_variant = mfree(c->x11_variant);
+}
+
+static void context_free_vconsole(Context *c) {
+ c->vc_keymap = mfree(c->vc_keymap);
+ c->vc_keymap_toggle = mfree(c->vc_keymap_toggle);
+}
+
+static void context_free_locale(Context *c) {
+ int p;
+
+ for (p = 0; p < _VARIABLE_LC_MAX; p++)
+ c->locale[p] = mfree(c->locale[p]);
+}
+
+void context_free(Context *c) {
+ context_free_locale(c);
+ context_free_x11(c);
+ context_free_vconsole(c);
+};
+
+void locale_simplify(Context *c) {
+ int p;
+
+ for (p = VARIABLE_LANG+1; p < _VARIABLE_LC_MAX; p++)
+ if (isempty(c->locale[p]) || streq_ptr(c->locale[VARIABLE_LANG], c->locale[p]))
+ c->locale[p] = mfree(c->locale[p]);
+}
+
+static int locale_read_data(Context *c) {
+ int r;
+
+ context_free_locale(c);
+
+ r = parse_env_file("/etc/locale.conf", NEWLINE,
+ "LANG", &c->locale[VARIABLE_LANG],
+ "LANGUAGE", &c->locale[VARIABLE_LANGUAGE],
+ "LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE],
+ "LC_NUMERIC", &c->locale[VARIABLE_LC_NUMERIC],
+ "LC_TIME", &c->locale[VARIABLE_LC_TIME],
+ "LC_COLLATE", &c->locale[VARIABLE_LC_COLLATE],
+ "LC_MONETARY", &c->locale[VARIABLE_LC_MONETARY],
+ "LC_MESSAGES", &c->locale[VARIABLE_LC_MESSAGES],
+ "LC_PAPER", &c->locale[VARIABLE_LC_PAPER],
+ "LC_NAME", &c->locale[VARIABLE_LC_NAME],
+ "LC_ADDRESS", &c->locale[VARIABLE_LC_ADDRESS],
+ "LC_TELEPHONE", &c->locale[VARIABLE_LC_TELEPHONE],
+ "LC_MEASUREMENT", &c->locale[VARIABLE_LC_MEASUREMENT],
+ "LC_IDENTIFICATION", &c->locale[VARIABLE_LC_IDENTIFICATION],
+ NULL);
+
+ if (r == -ENOENT) {
+ int p;
+
+ /* Fill in what we got passed from systemd. */
+ for (p = 0; p < _VARIABLE_LC_MAX; p++) {
+ const char *name;
+
+ name = locale_variable_to_string(p);
+ assert(name);
+
+ r = free_and_strdup(&c->locale[p], empty_to_null(getenv(name)));
+ if (r < 0)
+ return r;
+ }
+
+ r = 0;
+ }
+
+ locale_simplify(c);
+ return r;
+}
+
+static int vconsole_read_data(Context *c) {
+ int r;
+
+ context_free_vconsole(c);
+
+ r = parse_env_file("/etc/vconsole.conf", NEWLINE,
+ "KEYMAP", &c->vc_keymap,
+ "KEYMAP_TOGGLE", &c->vc_keymap_toggle,
+ NULL);
+
+ if (r < 0 && r != -ENOENT)
+ return r;
+
+ return 0;
+}
+
+static int x11_read_data(Context *c) {
+ _cleanup_fclose_ FILE *f;
+ char line[LINE_MAX];
+ bool in_section = false;
+ int r;
+
+ context_free_x11(c);
+
+ f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
+ if (!f)
+ return errno == ENOENT ? 0 : -errno;
+
+ while (fgets(line, sizeof(line), f)) {
+ char *l;
+
+ char_array_0(line);
+ l = strstrip(line);
+
+ if (l[0] == 0 || l[0] == '#')
+ continue;
+
+ if (in_section && first_word(l, "Option")) {
+ _cleanup_strv_free_ char **a = NULL;
+
+ r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
+ if (r < 0)
+ return r;
+
+ if (strv_length(a) == 3) {
+ char **p = NULL;
+
+ if (streq(a[1], "XkbLayout"))
+ p = &c->x11_layout;
+ else if (streq(a[1], "XkbModel"))
+ p = &c->x11_model;
+ else if (streq(a[1], "XkbVariant"))
+ p = &c->x11_variant;
+ else if (streq(a[1], "XkbOptions"))
+ p = &c->x11_options;
+
+ if (p) {
+ free(*p);
+ *p = a[2];
+ a[2] = NULL;
+ }
+ }
+
+ } else if (!in_section && first_word(l, "Section")) {
+ _cleanup_strv_free_ char **a = NULL;
+
+ r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
+ if (r < 0)
+ return -ENOMEM;
+
+ if (strv_length(a) == 2 && streq(a[1], "InputClass"))
+ in_section = true;
+
+ } else if (in_section && first_word(l, "EndSection"))
+ in_section = false;
+ }
+
+ return 0;
+}
+
+int context_read_data(Context *c) {
+ int r, q, p;
+
+ r = locale_read_data(c);
+ q = vconsole_read_data(c);
+ p = x11_read_data(c);
+
+ return r < 0 ? r : q < 0 ? q : p;
+}
+
+int locale_write_data(Context *c, char ***settings) {
+ int r, p;
+ _cleanup_strv_free_ char **l = NULL;
+
+ /* Set values will be returned as strv in *settings on success. */
+
+ r = load_env_file(NULL, "/etc/locale.conf", NULL, &l);
+ if (r < 0 && r != -ENOENT)
+ return r;
+
+ for (p = 0; p < _VARIABLE_LC_MAX; p++) {
+ _cleanup_free_ char *t = NULL;
+ char **u;
+ const char *name;
+
+ name = locale_variable_to_string(p);
+ assert(name);
+
+ if (isempty(c->locale[p])) {
+ l = strv_env_unset(l, name);
+ continue;
+ }
+
+ if (asprintf(&t, "%s=%s", name, c->locale[p]) < 0)
+ return -ENOMEM;
+
+ u = strv_env_set(l, t);
+ if (!u)
+ return -ENOMEM;
+
+ strv_free(l);
+ l = u;
+ }
+
+ if (strv_isempty(l)) {
+ if (unlink("/etc/locale.conf") < 0)
+ return errno == ENOENT ? 0 : -errno;
+
+ return 0;
+ }
+
+ r = write_env_file_label("/etc/locale.conf", l);
+ if (r < 0)
+ return r;
+
+ *settings = l;
+ l = NULL;
+ return 0;
+}
+
+int vconsole_write_data(Context *c) {
+ int r;
+ _cleanup_strv_free_ char **l = NULL;
+
+ r = load_env_file(NULL, "/etc/vconsole.conf", NULL, &l);
+ if (r < 0 && r != -ENOENT)
+ return r;
+
+ if (isempty(c->vc_keymap))
+ l = strv_env_unset(l, "KEYMAP");
+ else {
+ _cleanup_free_ char *s = NULL;
+ char **u;
+
+ s = strappend("KEYMAP=", c->vc_keymap);
+ if (!s)
+ return -ENOMEM;
+
+ u = strv_env_set(l, s);
+ if (!u)
+ return -ENOMEM;
+
+ strv_free(l);
+ l = u;
+ }
+
+ if (isempty(c->vc_keymap_toggle))
+ l = strv_env_unset(l, "KEYMAP_TOGGLE");
+ else {
+ _cleanup_free_ char *s = NULL;
+ char **u;
+
+ s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
+ if (!s)
+ return -ENOMEM;
+
+ u = strv_env_set(l, s);
+ if (!u)
+ return -ENOMEM;
+
+ strv_free(l);
+ l = u;
+ }
+
+ if (strv_isempty(l)) {
+ if (unlink("/etc/vconsole.conf") < 0)
+ return errno == ENOENT ? 0 : -errno;
+
+ return 0;
+ }
+
+ return write_env_file_label("/etc/vconsole.conf", l);
+}
+
+int x11_write_data(Context *c) {
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_free_ char *temp_path = NULL;
+ int r;
+
+ if (isempty(c->x11_layout) &&
+ isempty(c->x11_model) &&
+ isempty(c->x11_variant) &&
+ isempty(c->x11_options)) {
+
+ if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
+ return errno == ENOENT ? 0 : -errno;
+
+ return 0;
+ }
+
+ mkdir_p_label("/etc/X11/xorg.conf.d", 0755);
+
+ r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
+ if (r < 0)
+ return r;
+
+ 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"
+ "Section \"InputClass\"\n"
+ " Identifier \"system-keyboard\"\n"
+ " MatchIsKeyboard \"on\"\n", f);
+
+ if (!isempty(c->x11_layout))
+ fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout);
+
+ if (!isempty(c->x11_model))
+ fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model);
+
+ if (!isempty(c->x11_variant))
+ fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant);
+
+ if (!isempty(c->x11_options))
+ fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options);
+
+ fputs("EndSection\n", f);
+
+ r = fflush_and_check(f);
+ if (r < 0)
+ goto fail;
+
+ if (rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
+ r = -errno;
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ (void) unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
+
+ if (temp_path)
+ (void) unlink(temp_path);
+
+ return r;
+}
+
+static int read_next_mapping(const char* filename,
+ unsigned min_fields, unsigned max_fields,
+ FILE *f, unsigned *n, char ***a) {
+ assert(f);
+ assert(n);
+ assert(a);
+
+ for (;;) {
+ char line[LINE_MAX];
+ char *l, **b;
+ int r;
+ size_t length;
+
+ errno = 0;
+ if (!fgets(line, sizeof(line), f)) {
+
+ if (ferror(f))
+ return errno > 0 ? -errno : -EIO;
+
+ return 0;
+ }
+
+ (*n)++;
+
+ l = strstrip(line);
+ if (l[0] == 0 || l[0] == '#')
+ continue;
+
+ r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
+ if (r < 0)
+ return r;
+
+ length = strv_length(b);
+ if (length < min_fields || length > max_fields) {
+ log_error("Invalid line %s:%u, ignoring.", filename, *n);
+ strv_free(b);
+ continue;
+
+ }
+
+ *a = b;
+ return 1;
+ }
+}
+
+int vconsole_convert_to_x11(Context *c) {
+ const char *map;
+ int modified = -1;
+
+ map = systemd_kbd_model_map();
+
+ if (isempty(c->vc_keymap)) {
+ modified =
+ !isempty(c->x11_layout) ||
+ !isempty(c->x11_model) ||
+ !isempty(c->x11_variant) ||
+ !isempty(c->x11_options);
+
+ context_free_x11(c);
+ } else {
+ _cleanup_fclose_ FILE *f = NULL;
+ unsigned n = 0;
+
+ f = fopen(map, "re");
+ if (!f)
+ return -errno;
+
+ for (;;) {
+ _cleanup_strv_free_ char **a = NULL;
+ int r;
+
+ r = read_next_mapping(map, 5, UINT_MAX, f, &n, &a);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ if (!streq(c->vc_keymap, a[0]))
+ continue;
+
+ if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
+ !streq_ptr(c->x11_model, strnulldash(a[2])) ||
+ !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
+ !streq_ptr(c->x11_options, strnulldash(a[4]))) {
+
+ if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 ||
+ free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 ||
+ free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 ||
+ free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0)
+ return -ENOMEM;
+
+ modified = true;
+ }
+
+ break;
+ }
+ }
+
+ if (modified > 0)
+ log_info("Changing X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",
+ strempty(c->x11_layout),
+ strempty(c->x11_model),
+ strempty(c->x11_variant),
+ strempty(c->x11_options));
+ else if (modified < 0)
+ log_notice("X11 keyboard layout was not modified: no conversion found for \"%s\".",
+ c->vc_keymap);
+ else
+ log_debug("X11 keyboard layout did not need to be modified.");
+
+ return modified > 0;
+}
+
+int find_converted_keymap(const char *x11_layout, const char *x11_variant, char **new_keymap) {
+ const char *dir;
+ _cleanup_free_ char *n;
+
+ if (x11_variant)
+ n = strjoin(x11_layout, "-", x11_variant, NULL);
+ else
+ n = strdup(x11_layout);
+ if (!n)
+ return -ENOMEM;
+
+ NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
+ _cleanup_free_ char *p = NULL, *pz = NULL;
+ bool uncompressed;
+
+ p = strjoin(dir, "xkb/", n, ".map", NULL);
+ pz = strjoin(dir, "xkb/", n, ".map.gz", NULL);
+ if (!p || !pz)
+ return -ENOMEM;
+
+ uncompressed = access(p, F_OK) == 0;
+ if (uncompressed || access(pz, F_OK) == 0) {
+ log_debug("Found converted keymap %s at %s",
+ n, uncompressed ? p : pz);
+
+ *new_keymap = n;
+ n = NULL;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int find_legacy_keymap(Context *c, char **new_keymap) {
+ const char *map;
+ _cleanup_fclose_ FILE *f = NULL;
+ unsigned n = 0;
+ unsigned best_matching = 0;
+ int r;
+
+ assert(!isempty(c->x11_layout));
+
+ map = systemd_kbd_model_map();
+
+ f = fopen(map, "re");
+ if (!f)
+ return -errno;
+
+ for (;;) {
+ _cleanup_strv_free_ char **a = NULL;
+ unsigned matching = 0;
+
+ r = read_next_mapping(map, 5, UINT_MAX, f, &n, &a);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
+
+ /* Determine how well matching this entry is */
+ if (streq(c->x11_layout, a[1]))
+ /* If we got an exact match, this is best */
+ matching = 10;
+ else {
+ /* We have multiple X layouts, look for an
+ * entry that matches our key with everything
+ * but the first layout stripped off. */
+ if (startswith_comma(c->x11_layout, a[1]))
+ matching = 5;
+ else {
+ char *x;
+
+ /* If that didn't work, strip off the
+ * other layouts from the entry, too */
+ x = strndupa(a[1], strcspn(a[1], ","));
+ if (startswith_comma(c->x11_layout, x))
+ matching = 1;
+ }
+ }
+
+ if (matching > 0) {
+ if (isempty(c->x11_model) || streq_ptr(c->x11_model, a[2])) {
+ matching++;
+
+ if (streq_ptr(c->x11_variant, a[3])) {
+ matching++;
+
+ if (streq_ptr(c->x11_options, a[4]))
+ matching++;
+ }
+ }
+ }
+
+ /* The best matching entry so far, then let's save that */
+ if (matching >= MAX(best_matching, 1u)) {
+ log_debug("Found legacy keymap %s with score %u",
+ a[0], matching);
+
+ if (matching > best_matching) {
+ best_matching = matching;
+
+ r = free_and_strdup(new_keymap, a[0]);
+ if (r < 0)
+ return r;
+ }
+ }
+ }
+
+ if (best_matching < 10 && c->x11_layout) {
+ /* The best match is only the first part of the X11
+ * keymap. Check if we have a converted map which
+ * matches just the first layout.
+ */
+ char *l, *v = NULL, *converted;
+
+ l = strndupa(c->x11_layout, strcspn(c->x11_layout, ","));
+ if (c->x11_variant)
+ v = strndupa(c->x11_variant, strcspn(c->x11_variant, ","));
+ r = find_converted_keymap(l, v, &converted);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ free(*new_keymap);
+ *new_keymap = converted;
+ }
+ }
+
+ return (bool) *new_keymap;
+}
+
+int find_language_fallback(const char *lang, char **language) {
+ const char *map;
+ _cleanup_fclose_ FILE *f = NULL;
+ unsigned n = 0;
+
+ assert(lang);
+ assert(language);
+
+ map = systemd_language_fallback_map();
+
+ f = fopen(map, "re");
+ if (!f)
+ return -errno;
+
+ for (;;) {
+ _cleanup_strv_free_ char **a = NULL;
+ int r;
+
+ r = read_next_mapping(map, 2, 2, f, &n, &a);
+ if (r <= 0)
+ return r;
+
+ if (streq(lang, a[0])) {
+ assert(strv_length(a) == 2);
+ *language = a[1];
+ a[1] = NULL;
+ return 1;
+ }
+ }
+
+ assert_not_reached("should not be here");
+}
+
+int x11_convert_to_vconsole(Context *c) {
+ bool modified = false;
+
+ if (isempty(c->x11_layout)) {
+ modified =
+ !isempty(c->vc_keymap) ||
+ !isempty(c->vc_keymap_toggle);
+
+ context_free_vconsole(c);
+ } else {
+ char *new_keymap = NULL;
+ int r;
+
+ r = find_converted_keymap(c->x11_layout, c->x11_variant, &new_keymap);
+ if (r < 0)
+ return r;
+ else if (r == 0) {
+ r = find_legacy_keymap(c, &new_keymap);
+ if (r < 0)
+ return r;
+ }
+ if (r == 0)
+ /* We search for layout-variant match first, but then we also look
+ * for anything which matches just the layout. So it's accurate to say
+ * that we couldn't find anything which matches the layout. */
+ log_notice("No conversion to virtual console map found for \"%s\".",
+ c->x11_layout);
+
+ if (!streq_ptr(c->vc_keymap, new_keymap)) {
+ free(c->vc_keymap);
+ c->vc_keymap = new_keymap;
+ c->vc_keymap_toggle = mfree(c->vc_keymap_toggle);
+ modified = true;
+ } else
+ free(new_keymap);
+ }
+
+ if (modified)
+ log_info("Changing virtual console keymap to '%s' toggle '%s'",
+ strempty(c->vc_keymap), strempty(c->vc_keymap_toggle));
+ else
+ log_debug("Virtual console keymap was not modified.");
+
+ return modified;
+}
diff --git a/src/locale/keymap-util.h b/src/locale/keymap-util.h
new file mode 100644
index 0000000000..20ef2a4a34
--- /dev/null
+++ b/src/locale/keymap-util.h
@@ -0,0 +1,46 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2011 Lennart Poettering
+ Copyright 2013 Kay Sievers
+
+ 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 "locale-util.h"
+
+typedef struct Context {
+ char *locale[_VARIABLE_LC_MAX];
+
+ char *x11_layout;
+ char *x11_model;
+ char *x11_variant;
+ char *x11_options;
+
+ char *vc_keymap;
+ char *vc_keymap_toggle;
+} Context;
+
+int find_converted_keymap(const char *x11_layout, const char *x11_variant, char **new_keymap);
+int find_legacy_keymap(Context *c, char **new_keymap);
+int find_language_fallback(const char *lang, char **language);
+
+int context_read_data(Context *c);
+void context_free(Context *c);
+int vconsole_convert_to_x11(Context *c);
+int vconsole_write_data(Context *c);
+int x11_convert_to_vconsole(Context *c);
+int x11_write_data(Context *c);
+void locale_simplify(Context *c);
+int locale_write_data(Context *c, char ***settings);
diff --git a/src/locale/localectl.c b/src/locale/localectl.c
index 4865335349..81afb4909f 100644
--- a/src/locale/localectl.c
+++ b/src/locale/localectl.c
@@ -656,7 +656,7 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) {
}
int main(int argc, char*argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
@@ -676,6 +676,7 @@ int main(int argc, char*argv[]) {
r = localectl_main(bus, argc, argv);
finish:
+ sd_bus_flush_close_unref(bus);
pager_close();
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 6af59fc830..298f176e40 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -34,288 +34,16 @@
#include "bus-message.h"
#include "bus-util.h"
#include "def.h"
-#include "env-util.h"
-#include "fd-util.h"
-#include "fileio-label.h"
-#include "fileio.h"
+#include "keymap-util.h"
#include "locale-util.h"
-#include "mkdir.h"
+#include "macro.h"
#include "path-util.h"
#include "selinux-util.h"
+#include "string-util.h"
#include "strv.h"
#include "user-util.h"
-#include "util.h"
-
-enum {
- /* We don't list LC_ALL here on purpose. People should be
- * using LANG instead. */
- LOCALE_LANG,
- LOCALE_LANGUAGE,
- LOCALE_LC_CTYPE,
- LOCALE_LC_NUMERIC,
- LOCALE_LC_TIME,
- LOCALE_LC_COLLATE,
- LOCALE_LC_MONETARY,
- LOCALE_LC_MESSAGES,
- LOCALE_LC_PAPER,
- LOCALE_LC_NAME,
- LOCALE_LC_ADDRESS,
- LOCALE_LC_TELEPHONE,
- LOCALE_LC_MEASUREMENT,
- LOCALE_LC_IDENTIFICATION,
- _LOCALE_MAX
-};
-
-static const char * const names[_LOCALE_MAX] = {
- [LOCALE_LANG] = "LANG",
- [LOCALE_LANGUAGE] = "LANGUAGE",
- [LOCALE_LC_CTYPE] = "LC_CTYPE",
- [LOCALE_LC_NUMERIC] = "LC_NUMERIC",
- [LOCALE_LC_TIME] = "LC_TIME",
- [LOCALE_LC_COLLATE] = "LC_COLLATE",
- [LOCALE_LC_MONETARY] = "LC_MONETARY",
- [LOCALE_LC_MESSAGES] = "LC_MESSAGES",
- [LOCALE_LC_PAPER] = "LC_PAPER",
- [LOCALE_LC_NAME] = "LC_NAME",
- [LOCALE_LC_ADDRESS] = "LC_ADDRESS",
- [LOCALE_LC_TELEPHONE] = "LC_TELEPHONE",
- [LOCALE_LC_MEASUREMENT] = "LC_MEASUREMENT",
- [LOCALE_LC_IDENTIFICATION] = "LC_IDENTIFICATION"
-};
-
-typedef struct Context {
- char *locale[_LOCALE_MAX];
-
- char *x11_layout;
- char *x11_model;
- char *x11_variant;
- char *x11_options;
-
- char *vc_keymap;
- char *vc_keymap_toggle;
-
- Hashmap *polkit_registry;
-} Context;
-
-static bool startswith_comma(const char *s, const char *prefix) {
- const char *t;
-
- return s && (t = startswith(s, prefix)) && (*t == ',');
-}
-
-static void context_free_x11(Context *c) {
- c->x11_layout = mfree(c->x11_layout);
- c->x11_options = mfree(c->x11_options);
- c->x11_model = mfree(c->x11_model);
- c->x11_variant = mfree(c->x11_variant);
-}
-
-static void context_free_vconsole(Context *c) {
- c->vc_keymap = mfree(c->vc_keymap);
- c->vc_keymap_toggle = mfree(c->vc_keymap_toggle);
-}
-
-static void context_free_locale(Context *c) {
- int p;
-
- for (p = 0; p < _LOCALE_MAX; p++)
- c->locale[p] = mfree(c->locale[p]);
-}
-
-static void context_free(Context *c) {
- context_free_locale(c);
- context_free_x11(c);
- context_free_vconsole(c);
-
- bus_verify_polkit_async_registry_free(c->polkit_registry);
-};
-
-static void locale_simplify(Context *c) {
- int p;
-
- for (p = LOCALE_LANG+1; p < _LOCALE_MAX; p++)
- if (isempty(c->locale[p]) || streq_ptr(c->locale[LOCALE_LANG], c->locale[p]))
- c->locale[p] = mfree(c->locale[p]);
-}
-
-static int locale_read_data(Context *c) {
- int r;
-
- context_free_locale(c);
-
- r = parse_env_file("/etc/locale.conf", NEWLINE,
- "LANG", &c->locale[LOCALE_LANG],
- "LANGUAGE", &c->locale[LOCALE_LANGUAGE],
- "LC_CTYPE", &c->locale[LOCALE_LC_CTYPE],
- "LC_NUMERIC", &c->locale[LOCALE_LC_NUMERIC],
- "LC_TIME", &c->locale[LOCALE_LC_TIME],
- "LC_COLLATE", &c->locale[LOCALE_LC_COLLATE],
- "LC_MONETARY", &c->locale[LOCALE_LC_MONETARY],
- "LC_MESSAGES", &c->locale[LOCALE_LC_MESSAGES],
- "LC_PAPER", &c->locale[LOCALE_LC_PAPER],
- "LC_NAME", &c->locale[LOCALE_LC_NAME],
- "LC_ADDRESS", &c->locale[LOCALE_LC_ADDRESS],
- "LC_TELEPHONE", &c->locale[LOCALE_LC_TELEPHONE],
- "LC_MEASUREMENT", &c->locale[LOCALE_LC_MEASUREMENT],
- "LC_IDENTIFICATION", &c->locale[LOCALE_LC_IDENTIFICATION],
- NULL);
-
- if (r == -ENOENT) {
- int p;
-
- /* Fill in what we got passed from systemd. */
- for (p = 0; p < _LOCALE_MAX; p++) {
- assert(names[p]);
-
- r = free_and_strdup(&c->locale[p], empty_to_null(getenv(names[p])));
- if (r < 0)
- return r;
- }
-
- r = 0;
- }
-
- locale_simplify(c);
- return r;
-}
-
-static int vconsole_read_data(Context *c) {
- int r;
- context_free_vconsole(c);
-
- r = parse_env_file("/etc/vconsole.conf", NEWLINE,
- "KEYMAP", &c->vc_keymap,
- "KEYMAP_TOGGLE", &c->vc_keymap_toggle,
- NULL);
-
- if (r < 0 && r != -ENOENT)
- return r;
-
- return 0;
-}
-
-static int x11_read_data(Context *c) {
- _cleanup_fclose_ FILE *f;
- char line[LINE_MAX];
- bool in_section = false;
- int r;
-
- context_free_x11(c);
-
- f = fopen("/etc/X11/xorg.conf.d/00-keyboard.conf", "re");
- if (!f)
- return errno == ENOENT ? 0 : -errno;
-
- while (fgets(line, sizeof(line), f)) {
- char *l;
-
- char_array_0(line);
- l = strstrip(line);
-
- if (l[0] == 0 || l[0] == '#')
- continue;
-
- if (in_section && first_word(l, "Option")) {
- _cleanup_strv_free_ char **a = NULL;
-
- r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
- if (r < 0)
- return r;
-
- if (strv_length(a) == 3) {
- char **p = NULL;
-
- if (streq(a[1], "XkbLayout"))
- p = &c->x11_layout;
- else if (streq(a[1], "XkbModel"))
- p = &c->x11_model;
- else if (streq(a[1], "XkbVariant"))
- p = &c->x11_variant;
- else if (streq(a[1], "XkbOptions"))
- p = &c->x11_options;
-
- if (p) {
- free(*p);
- *p = a[2];
- a[2] = NULL;
- }
- }
-
- } else if (!in_section && first_word(l, "Section")) {
- _cleanup_strv_free_ char **a = NULL;
-
- r = strv_split_extract(&a, l, WHITESPACE, EXTRACT_QUOTES);
- if (r < 0)
- return -ENOMEM;
-
- if (strv_length(a) == 2 && streq(a[1], "InputClass"))
- in_section = true;
-
- } else if (in_section && first_word(l, "EndSection"))
- in_section = false;
- }
-
- return 0;
-}
-
-static int context_read_data(Context *c) {
- int r, q, p;
-
- r = locale_read_data(c);
- q = vconsole_read_data(c);
- p = x11_read_data(c);
-
- return r < 0 ? r : q < 0 ? q : p;
-}
-
-static int locale_write_data(Context *c, char ***settings) {
- int r, p;
- _cleanup_strv_free_ char **l = NULL;
-
- /* Set values will be returned as strv in *settings on success. */
-
- r = load_env_file(NULL, "/etc/locale.conf", NULL, &l);
- if (r < 0 && r != -ENOENT)
- return r;
-
- for (p = 0; p < _LOCALE_MAX; p++) {
- _cleanup_free_ char *t = NULL;
- char **u;
-
- assert(names[p]);
-
- if (isempty(c->locale[p])) {
- l = strv_env_unset(l, names[p]);
- continue;
- }
-
- if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0)
- return -ENOMEM;
-
- u = strv_env_set(l, t);
- if (!u)
- return -ENOMEM;
-
- strv_free(l);
- l = u;
- }
-
- if (strv_isempty(l)) {
- if (unlink("/etc/locale.conf") < 0)
- return errno == ENOENT ? 0 : -errno;
-
- return 0;
- }
-
- r = write_env_file_label("/etc/locale.conf", l);
- if (r < 0)
- return r;
-
- *settings = l;
- l = NULL;
- return 0;
-}
+static Hashmap *polkit_registry = NULL;
static int locale_update_system_manager(Context *c, sd_bus *bus) {
_cleanup_free_ char **l_unset = NULL;
@@ -327,30 +55,33 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) {
assert(bus);
- l_unset = new0(char*, _LOCALE_MAX);
+ l_unset = new0(char*, _VARIABLE_LC_MAX);
if (!l_unset)
return -ENOMEM;
- l_set = new0(char*, _LOCALE_MAX);
+ l_set = new0(char*, _VARIABLE_LC_MAX);
if (!l_set)
return -ENOMEM;
- for (p = 0, c_set = 0, c_unset = 0; p < _LOCALE_MAX; p++) {
- assert(names[p]);
+ for (p = 0, c_set = 0, c_unset = 0; p < _VARIABLE_LC_MAX; p++) {
+ const char *name;
+
+ name = locale_variable_to_string(p);
+ assert(name);
if (isempty(c->locale[p]))
- l_unset[c_set++] = (char*) names[p];
+ l_unset[c_set++] = (char*) name;
else {
char *s;
- if (asprintf(&s, "%s=%s", names[p], c->locale[p]) < 0)
+ if (asprintf(&s, "%s=%s", name, c->locale[p]) < 0)
return -ENOMEM;
l_set[c_unset++] = s;
}
}
- assert(c_set + c_unset == _LOCALE_MAX);
+ assert(c_set + c_unset == _VARIABLE_LC_MAX);
r = sd_bus_message_new_method_call(bus, &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
@@ -374,124 +105,6 @@ static int locale_update_system_manager(Context *c, sd_bus *bus) {
return 0;
}
-static int vconsole_write_data(Context *c) {
- int r;
- _cleanup_strv_free_ char **l = NULL;
-
- r = load_env_file(NULL, "/etc/vconsole.conf", NULL, &l);
- if (r < 0 && r != -ENOENT)
- return r;
-
- if (isempty(c->vc_keymap))
- l = strv_env_unset(l, "KEYMAP");
- else {
- _cleanup_free_ char *s = NULL;
- char **u;
-
- s = strappend("KEYMAP=", c->vc_keymap);
- if (!s)
- return -ENOMEM;
-
- u = strv_env_set(l, s);
- if (!u)
- return -ENOMEM;
-
- strv_free(l);
- l = u;
- }
-
- if (isempty(c->vc_keymap_toggle))
- l = strv_env_unset(l, "KEYMAP_TOGGLE");
- else {
- _cleanup_free_ char *s = NULL;
- char **u;
-
- s = strappend("KEYMAP_TOGGLE=", c->vc_keymap_toggle);
- if (!s)
- return -ENOMEM;
-
- u = strv_env_set(l, s);
- if (!u)
- return -ENOMEM;
-
- strv_free(l);
- l = u;
- }
-
- if (strv_isempty(l)) {
- if (unlink("/etc/vconsole.conf") < 0)
- return errno == ENOENT ? 0 : -errno;
-
- return 0;
- }
-
- return write_env_file_label("/etc/vconsole.conf", l);
-}
-
-static int x11_write_data(Context *c) {
- _cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char *temp_path = NULL;
- int r;
-
- if (isempty(c->x11_layout) &&
- isempty(c->x11_model) &&
- isempty(c->x11_variant) &&
- isempty(c->x11_options)) {
-
- if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0)
- return errno == ENOENT ? 0 : -errno;
-
- return 0;
- }
-
- mkdir_p_label("/etc/X11/xorg.conf.d", 0755);
-
- r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path);
- if (r < 0)
- return r;
-
- 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"
- "Section \"InputClass\"\n"
- " Identifier \"system-keyboard\"\n"
- " MatchIsKeyboard \"on\"\n", f);
-
- if (!isempty(c->x11_layout))
- fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout);
-
- if (!isempty(c->x11_model))
- fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model);
-
- if (!isempty(c->x11_variant))
- fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant);
-
- if (!isempty(c->x11_options))
- fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options);
-
- fputs("EndSection\n", f);
-
- r = fflush_and_check(f);
- if (r < 0)
- goto fail;
-
- if (rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) {
- r = -errno;
- goto fail;
- }
-
- return 0;
-
-fail:
- (void) unlink("/etc/X11/xorg.conf.d/00-keyboard.conf");
-
- if (temp_path)
- (void) unlink(temp_path);
-
- return r;
-}
-
static int vconsole_reload(sd_bus *bus) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
@@ -512,337 +125,48 @@ static int vconsole_reload(sd_bus *bus) {
return r;
}
-static const char* strnulldash(const char *s) {
- return isempty(s) || streq(s, "-") ? NULL : s;
-}
-
-static int read_next_mapping(const char* filename,
- unsigned min_fields, unsigned max_fields,
- FILE *f, unsigned *n, char ***a) {
- assert(f);
- assert(n);
- assert(a);
-
- for (;;) {
- char line[LINE_MAX];
- char *l, **b;
- int r;
- size_t length;
-
- errno = 0;
- if (!fgets(line, sizeof(line), f)) {
-
- if (ferror(f))
- return errno > 0 ? -errno : -EIO;
-
- return 0;
- }
-
- (*n)++;
-
- l = strstrip(line);
- if (l[0] == 0 || l[0] == '#')
- continue;
-
- r = strv_split_extract(&b, l, WHITESPACE, EXTRACT_QUOTES);
- if (r < 0)
- return r;
-
- length = strv_length(b);
- if (length < min_fields || length > max_fields) {
- log_error("Invalid line %s:%u, ignoring.", filename, *n);
- strv_free(b);
- continue;
-
- }
-
- *a = b;
- return 1;
- }
-}
-
-static int vconsole_convert_to_x11(Context *c, sd_bus *bus) {
- bool modified = false;
-
- assert(bus);
-
- if (isempty(c->vc_keymap)) {
-
- modified =
- !isempty(c->x11_layout) ||
- !isempty(c->x11_model) ||
- !isempty(c->x11_variant) ||
- !isempty(c->x11_options);
-
- context_free_x11(c);
- } else {
- _cleanup_fclose_ FILE *f = NULL;
- unsigned n = 0;
-
- f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
- if (!f)
- return -errno;
-
- for (;;) {
- _cleanup_strv_free_ char **a = NULL;
- int r;
-
- r = read_next_mapping(SYSTEMD_KBD_MODEL_MAP, 5, UINT_MAX, f, &n, &a);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- if (!streq(c->vc_keymap, a[0]))
- continue;
-
- if (!streq_ptr(c->x11_layout, strnulldash(a[1])) ||
- !streq_ptr(c->x11_model, strnulldash(a[2])) ||
- !streq_ptr(c->x11_variant, strnulldash(a[3])) ||
- !streq_ptr(c->x11_options, strnulldash(a[4]))) {
-
- if (free_and_strdup(&c->x11_layout, strnulldash(a[1])) < 0 ||
- free_and_strdup(&c->x11_model, strnulldash(a[2])) < 0 ||
- free_and_strdup(&c->x11_variant, strnulldash(a[3])) < 0 ||
- free_and_strdup(&c->x11_options, strnulldash(a[4])) < 0)
- return -ENOMEM;
-
- modified = true;
- }
-
- break;
- }
- }
-
- if (modified) {
- int r;
-
- r = x11_write_data(c);
- if (r < 0)
- return log_error_errno(r, "Failed to set X11 keyboard layout: %m");
-
- log_info("Changed X11 keyboard layout to '%s' model '%s' variant '%s' options '%s'",
- strempty(c->x11_layout),
- strempty(c->x11_model),
- strempty(c->x11_variant),
- strempty(c->x11_options));
-
- sd_bus_emit_properties_changed(bus,
- "/org/freedesktop/locale1",
- "org.freedesktop.locale1",
- "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
- } else
- log_debug("X11 keyboard layout was not modified.");
-
- return 0;
-}
-
-static int find_converted_keymap(const char *x11_layout, const char *x11_variant, char **new_keymap) {
- const char *dir;
- _cleanup_free_ char *n;
-
- if (x11_variant)
- n = strjoin(x11_layout, "-", x11_variant, NULL);
- else
- n = strdup(x11_layout);
- if (!n)
- return -ENOMEM;
-
- NULSTR_FOREACH(dir, KBD_KEYMAP_DIRS) {
- _cleanup_free_ char *p = NULL, *pz = NULL;
- bool uncompressed;
-
- p = strjoin(dir, "xkb/", n, ".map", NULL);
- pz = strjoin(dir, "xkb/", n, ".map.gz", NULL);
- if (!p || !pz)
- return -ENOMEM;
-
- uncompressed = access(p, F_OK) == 0;
- if (uncompressed || access(pz, F_OK) == 0) {
- log_debug("Found converted keymap %s at %s",
- n, uncompressed ? p : pz);
-
- *new_keymap = n;
- n = NULL;
- return 1;
- }
- }
-
- return 0;
-}
-
-static int find_legacy_keymap(Context *c, char **new_keymap) {
- _cleanup_fclose_ FILE *f;
- unsigned n = 0;
- unsigned best_matching = 0;
+static int vconsole_convert_to_x11_and_emit(Context *c, sd_bus *bus) {
int r;
- f = fopen(SYSTEMD_KBD_MODEL_MAP, "re");
- if (!f)
- return -errno;
-
- for (;;) {
- _cleanup_strv_free_ char **a = NULL;
- unsigned matching = 0;
-
- r = read_next_mapping(SYSTEMD_KBD_MODEL_MAP, 5, UINT_MAX, f, &n, &a);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- /* Determine how well matching this entry is */
- if (streq_ptr(c->x11_layout, a[1]))
- /* If we got an exact match, this is best */
- matching = 10;
- else {
- /* We have multiple X layouts, look for an
- * entry that matches our key with everything
- * but the first layout stripped off. */
- if (startswith_comma(c->x11_layout, a[1]))
- matching = 5;
- else {
- char *x;
-
- /* If that didn't work, strip off the
- * other layouts from the entry, too */
- x = strndupa(a[1], strcspn(a[1], ","));
- if (startswith_comma(c->x11_layout, x))
- matching = 1;
- }
- }
-
- if (matching > 0) {
- if (isempty(c->x11_model) || streq_ptr(c->x11_model, a[2])) {
- matching++;
-
- if (streq_ptr(c->x11_variant, a[3])) {
- matching++;
-
- if (streq_ptr(c->x11_options, a[4]))
- matching++;
- }
- }
- }
-
- /* The best matching entry so far, then let's save that */
- if (matching >= MAX(best_matching, 1u)) {
- log_debug("Found legacy keymap %s with score %u",
- a[0], matching);
-
- if (matching > best_matching) {
- best_matching = matching;
-
- r = free_and_strdup(new_keymap, a[0]);
- if (r < 0)
- return r;
- }
- }
- }
-
- if (best_matching < 10 && c->x11_layout) {
- /* The best match is only the first part of the X11
- * keymap. Check if we have a converted map which
- * matches just the first layout.
- */
- char *l, *v = NULL, *converted;
-
- l = strndupa(c->x11_layout, strcspn(c->x11_layout, ","));
- if (c->x11_variant)
- v = strndupa(c->x11_variant, strcspn(c->x11_variant, ","));
- r = find_converted_keymap(l, v, &converted);
- if (r < 0)
- return r;
- if (r > 0) {
- free(*new_keymap);
- *new_keymap = converted;
- }
- }
-
- return 0;
-}
-
-static int find_language_fallback(const char *lang, char **language) {
- _cleanup_fclose_ FILE *f = NULL;
- unsigned n = 0;
-
- assert(language);
-
- f = fopen(SYSTEMD_LANGUAGE_FALLBACK_MAP, "re");
- if (!f)
- return -errno;
+ assert(bus);
- for (;;) {
- _cleanup_strv_free_ char **a = NULL;
- int r;
+ r = vconsole_convert_to_x11(c);
+ if (r <= 0)
+ return r;
- r = read_next_mapping(SYSTEMD_LANGUAGE_FALLBACK_MAP, 2, 2, f, &n, &a);
- if (r <= 0)
- return r;
+ /* modified */
+ r = x11_write_data(c);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write X11 keyboard layout: %m");
- if (streq(lang, a[0])) {
- assert(strv_length(a) == 2);
- *language = a[1];
- a[1] = NULL;
- return 1;
- }
- }
+ sd_bus_emit_properties_changed(bus,
+ "/org/freedesktop/locale1",
+ "org.freedesktop.locale1",
+ "X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
- assert_not_reached("should not be here");
+ return 1;
}
-static int x11_convert_to_vconsole(Context *c, sd_bus *bus) {
- bool modified = false;
+static int x11_convert_to_vconsole_and_emit(Context *c, sd_bus *bus) {
int r;
assert(bus);
- if (isempty(c->x11_layout)) {
-
- modified =
- !isempty(c->vc_keymap) ||
- !isempty(c->vc_keymap_toggle);
-
- context_free_x11(c);
- } else {
- char *new_keymap = NULL;
-
- r = find_converted_keymap(c->x11_layout, c->x11_variant, &new_keymap);
- if (r < 0)
- return r;
- else if (r == 0) {
- r = find_legacy_keymap(c, &new_keymap);
- if (r < 0)
- return r;
- }
-
- if (!streq_ptr(c->vc_keymap, new_keymap)) {
- free(c->vc_keymap);
- c->vc_keymap = new_keymap;
- c->vc_keymap_toggle = mfree(c->vc_keymap_toggle);
- modified = true;
- } else
- free(new_keymap);
- }
-
- if (modified) {
- r = vconsole_write_data(c);
- if (r < 0)
- log_error_errno(r, "Failed to set virtual console keymap: %m");
-
- log_info("Changed virtual console keymap to '%s' toggle '%s'",
- strempty(c->vc_keymap), strempty(c->vc_keymap_toggle));
+ r = x11_convert_to_vconsole(c);
+ if (r <= 0)
+ return r;
- sd_bus_emit_properties_changed(bus,
- "/org/freedesktop/locale1",
- "org.freedesktop.locale1",
- "VConsoleKeymap", "VConsoleKeymapToggle", NULL);
+ /* modified */
+ r = vconsole_write_data(c);
+ if (r < 0)
+ log_error_errno(r, "Failed to save virtual console keymap: %m");
- return vconsole_reload(bus);
- } else
- log_debug("Virtual console keymap was not modified.");
+ sd_bus_emit_properties_changed(bus,
+ "/org/freedesktop/locale1",
+ "org.freedesktop.locale1",
+ "VConsoleKeymap", "VConsoleKeymapToggle", NULL);
- return 0;
+ return vconsole_reload(bus);
}
static int property_get_locale(
@@ -858,17 +182,21 @@ static int property_get_locale(
_cleanup_strv_free_ char **l = NULL;
int p, q;
- l = new0(char*, _LOCALE_MAX+1);
+ l = new0(char*, _VARIABLE_LC_MAX+1);
if (!l)
return -ENOMEM;
- for (p = 0, q = 0; p < _LOCALE_MAX; p++) {
+ for (p = 0, q = 0; p < _VARIABLE_LC_MAX; p++) {
char *t;
+ const char *name;
+
+ name = locale_variable_to_string(p);
+ assert(name);
if (isempty(c->locale[p]))
continue;
- if (asprintf(&t, "%s=%s", names[p], c->locale[p]) < 0)
+ if (asprintf(&t, "%s=%s", name, c->locale[p]) < 0)
return -ENOMEM;
l[q++] = t;
@@ -884,7 +212,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
const char *lang = NULL;
int interactive;
bool modified = false;
- bool have[_LOCALE_MAX] = {};
+ bool have[_VARIABLE_LC_MAX] = {};
int p;
int r;
@@ -903,17 +231,21 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
STRV_FOREACH(i, l) {
bool valid = false;
- for (p = 0; p < _LOCALE_MAX; p++) {
+ for (p = 0; p < _VARIABLE_LC_MAX; p++) {
size_t k;
+ const char *name;
+
+ name = locale_variable_to_string(p);
+ assert(name);
- k = strlen(names[p]);
- if (startswith(*i, names[p]) &&
+ k = strlen(name);
+ if (startswith(*i, name) &&
(*i)[k] == '=' &&
locale_is_valid((*i) + k + 1)) {
valid = true;
have[p] = true;
- if (p == LOCALE_LANG)
+ if (p == VARIABLE_LANG)
lang = (*i) + k + 1;
if (!streq_ptr(*i + k + 1, c->locale[p]))
@@ -929,7 +261,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
/* If LANG was specified, but not LANGUAGE, check if we should
* set it based on the language fallback table. */
- if (have[LOCALE_LANG] && !have[LOCALE_LANGUAGE]) {
+ if (have[VARIABLE_LANG] && !have[VARIABLE_LANGUAGE]) {
_cleanup_free_ char *language = NULL;
assert(lang);
@@ -937,12 +269,12 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
(void) find_language_fallback(lang, &language);
if (language) {
log_debug("Converted LANG=%s to LANGUAGE=%s", lang, language);
- if (!streq_ptr(language, c->locale[LOCALE_LANGUAGE])) {
+ if (!streq_ptr(language, c->locale[VARIABLE_LANGUAGE])) {
r = strv_extendf(&l, "LANGUAGE=%s", language);
if (r < 0)
return r;
- have[LOCALE_LANGUAGE] = true;
+ have[VARIABLE_LANGUAGE] = true;
modified = true;
}
}
@@ -950,7 +282,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
/* Check whether a variable is unset */
if (!modified)
- for (p = 0; p < _LOCALE_MAX; p++)
+ for (p = 0; p < _VARIABLE_LC_MAX; p++)
if (!isempty(c->locale[p]) && !have[p]) {
modified = true;
break;
@@ -966,7 +298,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
NULL,
interactive,
UID_INVALID,
- &c->polkit_registry,
+ &polkit_registry,
error);
if (r < 0)
return r;
@@ -974,11 +306,15 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
STRV_FOREACH(i, l)
- for (p = 0; p < _LOCALE_MAX; p++) {
+ for (p = 0; p < _VARIABLE_LC_MAX; p++) {
size_t k;
+ const char *name;
- k = strlen(names[p]);
- if (startswith(*i, names[p]) && (*i)[k] == '=') {
+ name = locale_variable_to_string(p);
+ assert(name);
+
+ k = strlen(name);
+ if (startswith(*i, name) && (*i)[k] == '=') {
r = free_and_strdup(&c->locale[p], *i + k + 1);
if (r < 0)
return r;
@@ -986,7 +322,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
}
}
- for (p = 0; p < _LOCALE_MAX; p++) {
+ for (p = 0; p < _VARIABLE_LC_MAX; p++) {
if (have[p])
continue;
@@ -1053,7 +389,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro
NULL,
interactive,
UID_INVALID,
- &c->polkit_registry,
+ &polkit_registry,
error);
if (r < 0)
return r;
@@ -1084,7 +420,7 @@ static int method_set_vc_keyboard(sd_bus_message *m, void *userdata, sd_bus_erro
"VConsoleKeymap", "VConsoleKeymapToggle", NULL);
if (convert) {
- r = vconsole_convert_to_x11(c, sd_bus_message_get_bus(m));
+ r = vconsole_convert_to_x11_and_emit(c, sd_bus_message_get_bus(m));
if (r < 0)
log_error_errno(r, "Failed to convert keymap data: %m");
}
@@ -1229,7 +565,7 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
NULL,
interactive,
UID_INVALID,
- &c->polkit_registry,
+ &polkit_registry,
error);
if (r < 0)
return r;
@@ -1272,7 +608,7 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
"X11Layout", "X11Model", "X11Variant", "X11Options", NULL);
if (convert) {
- r = x11_convert_to_vconsole(c, sd_bus_message_get_bus(m));
+ r = x11_convert_to_vconsole_and_emit(c, sd_bus_message_get_bus(m));
if (r < 0)
log_error_errno(r, "Failed to convert keymap data: %m");
}
@@ -1364,11 +700,11 @@ int main(int argc, char *argv[]) {
}
r = bus_event_loop_with_idle(event, bus, "org.freedesktop.locale1", DEFAULT_EXIT_USEC, NULL, NULL);
- if (r < 0) {
+ if (r < 0)
log_error_errno(r, "Failed to run event loop: %m");
- goto finish;
- }
finish:
+ bus_verify_polkit_async_registry_free(polkit_registry);
+
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
diff --git a/src/locale/test-keymap-util.c b/src/locale/test-keymap-util.c
new file mode 100644
index 0000000000..2adda3da2b
--- /dev/null
+++ b/src/locale/test-keymap-util.c
@@ -0,0 +1,220 @@
+/***
+ 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 "alloc-util.h"
+#include "keymap-util.h"
+#include "log.h"
+#include "string-util.h"
+
+static void test_find_language_fallback(void) {
+ _cleanup_free_ char *ans = NULL, *ans2 = NULL;
+
+ log_info("/*** %s ***/", __func__);
+
+ assert_se(find_language_fallback("foobar", &ans) == 0);
+ assert_se(ans == NULL);
+
+ assert_se(find_language_fallback("csb", &ans) == 0);
+ assert_se(ans == NULL);
+
+ assert_se(find_language_fallback("csb_PL", &ans) == 1);
+ assert_se(streq(ans, "csb:pl"));
+
+ assert_se(find_language_fallback("szl_PL", &ans2) == 1);
+ assert_se(streq(ans2, "szl:pl"));
+}
+
+static void test_find_converted_keymap(void) {
+ _cleanup_free_ char *ans = NULL, *ans2 = NULL;
+ int r;
+
+ log_info("/*** %s ***/", __func__);
+
+ assert_se(find_converted_keymap("pl", "foobar", &ans) == 0);
+ assert_se(ans == NULL);
+
+ r = find_converted_keymap("pl", NULL, &ans);
+ if (r == 0) {
+ log_info("Skipping rest of %s: keymaps are not installed", __func__);
+ return;
+ }
+
+ assert_se(r == 1);
+ assert_se(streq(ans, "pl"));
+
+ assert_se(find_converted_keymap("pl", "dvorak", &ans2) == 1);
+ assert_se(streq(ans2, "pl-dvorak"));
+}
+
+static void test_find_legacy_keymap(void) {
+ Context c = {};
+ _cleanup_free_ char *ans = NULL, *ans2 = NULL;
+
+ log_info("/*** %s ***/", __func__);
+
+ c.x11_layout = (char*) "foobar";
+ assert_se(find_legacy_keymap(&c, &ans) == 0);
+ assert_se(ans == NULL);
+
+ c.x11_layout = (char*) "pl";
+ assert_se(find_legacy_keymap(&c, &ans) == 1);
+ assert_se(streq(ans, "pl2"));
+
+ c.x11_layout = (char*) "pl,ru";
+ assert_se(find_legacy_keymap(&c, &ans2) == 1);
+ assert_se(streq(ans, "pl2"));
+}
+
+static void test_vconsole_convert_to_x11(void) {
+ _cleanup_(context_free) Context c = {};
+
+ log_info("/*** %s ***/", __func__);
+
+ log_info("/* test emptying first (:) */");
+ assert_se(free_and_strdup(&c.x11_layout, "foo") >= 0);
+ assert_se(free_and_strdup(&c.x11_variant, "bar") >= 0);
+ assert_se(vconsole_convert_to_x11(&c) == 1);
+ assert_se(c.x11_layout == NULL);
+ assert_se(c.x11_variant == NULL);
+
+ log_info("/* test emptying second (:) */");
+
+ assert_se(vconsole_convert_to_x11(&c) == 0);
+ assert_se(c.x11_layout == NULL);
+ assert_se(c.x11_variant == NULL);
+
+ log_info("/* test without variant, new mapping (es:) */");
+ assert_se(free_and_strdup(&c.vc_keymap, "es") >= 0);
+
+ assert_se(vconsole_convert_to_x11(&c) == 1);
+ assert_se(streq(c.x11_layout, "es"));
+ assert_se(c.x11_variant == NULL);
+
+ log_info("/* test with known variant, new mapping (es:dvorak) */");
+ assert_se(free_and_strdup(&c.vc_keymap, "es-dvorak") >= 0);
+
+ assert_se(vconsole_convert_to_x11(&c) == 0); // FIXME
+ assert_se(streq(c.x11_layout, "es"));
+ assert_se(c.x11_variant == NULL); // FIXME: "dvorak"
+
+ log_info("/* test with old mapping (fr:latin9) */");
+ assert_se(free_and_strdup(&c.vc_keymap, "fr-latin9") >= 0);
+
+ assert_se(vconsole_convert_to_x11(&c) == 1);
+ assert_se(streq(c.x11_layout, "fr"));
+ assert_se(streq(c.x11_variant, "latin9"));
+
+ log_info("/* test with a compound mapping (ru,us) */");
+ assert_se(free_and_strdup(&c.vc_keymap, "ru") >= 0);
+
+ assert_se(vconsole_convert_to_x11(&c) == 1);
+ assert_se(streq(c.x11_layout, "ru,us"));
+ assert_se(c.x11_variant == NULL);
+
+ log_info("/* test with a simple mapping (us) */");
+ assert_se(free_and_strdup(&c.vc_keymap, "us") >= 0);
+
+ assert_se(vconsole_convert_to_x11(&c) == 1);
+ assert_se(streq(c.x11_layout, "us"));
+ assert_se(c.x11_variant == NULL);
+}
+
+static void test_x11_convert_to_vconsole(void) {
+ _cleanup_(context_free) Context c = {};
+ int r;
+
+ log_info("/*** %s ***/", __func__);
+
+ log_info("/* test emptying first (:) */");
+ assert_se(free_and_strdup(&c.vc_keymap, "foobar") >= 0);
+ assert_se(x11_convert_to_vconsole(&c) == 1);
+ assert_se(c.vc_keymap == NULL);
+
+ log_info("/* test emptying second (:) */");
+
+ assert_se(x11_convert_to_vconsole(&c) == 0);
+ assert_se(c.vc_keymap == NULL);
+
+ log_info("/* test without variant, new mapping (es:) */");
+ assert_se(free_and_strdup(&c.x11_layout, "es") >= 0);
+
+ assert_se(x11_convert_to_vconsole(&c) == 1);
+ assert_se(streq(c.vc_keymap, "es"));
+
+ log_info("/* test with unknown variant, new mapping (es:foobar) */");
+ assert_se(free_and_strdup(&c.x11_variant, "foobar") >= 0);
+
+ assert_se(x11_convert_to_vconsole(&c) == 0);
+ assert_se(streq(c.vc_keymap, "es"));
+
+ log_info("/* test with known variant, new mapping (es:dvorak) */");
+ assert_se(free_and_strdup(&c.x11_variant, "dvorak") >= 0);
+
+ r = x11_convert_to_vconsole(&c);
+ if (r == 0) {
+ log_info("Skipping rest of %s: keymaps are not installed", __func__);
+ return;
+ }
+
+ assert_se(r == 1);
+ assert_se(streq(c.vc_keymap, "es-dvorak"));
+
+ log_info("/* test with old mapping (fr:latin9) */");
+ assert_se(free_and_strdup(&c.x11_layout, "fr") >= 0);
+ assert_se(free_and_strdup(&c.x11_variant, "latin9") >= 0);
+
+ assert_se(x11_convert_to_vconsole(&c) == 1);
+ assert_se(streq(c.vc_keymap, "fr-latin9"));
+
+ log_info("/* test with a compound mapping (us,ru:) */");
+ assert_se(free_and_strdup(&c.x11_layout, "us,ru") >= 0);
+ assert_se(free_and_strdup(&c.x11_variant, NULL) >= 0);
+
+ assert_se(x11_convert_to_vconsole(&c) == 1);
+ assert_se(streq(c.vc_keymap, "us"));
+
+ log_info("/* test with a compound mapping (ru,us:) */");
+ assert_se(free_and_strdup(&c.x11_layout, "ru,us") >= 0);
+ assert_se(free_and_strdup(&c.x11_variant, NULL) >= 0);
+
+ assert_se(x11_convert_to_vconsole(&c) == 1);
+ assert_se(streq(c.vc_keymap, "ru"));
+
+ /* https://bugzilla.redhat.com/show_bug.cgi?id=1333998 */
+ log_info("/* test with a simple new mapping (ru:) */");
+ assert_se(free_and_strdup(&c.x11_layout, "ru") >= 0);
+ assert_se(free_and_strdup(&c.x11_variant, NULL) >= 0);
+
+ assert_se(x11_convert_to_vconsole(&c) == 0);
+ assert_se(streq(c.vc_keymap, "ru"));
+}
+
+int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+
+ test_find_language_fallback();
+ test_find_converted_keymap();
+ test_find_legacy_keymap();
+
+ test_vconsole_convert_to_x11();
+ test_x11_convert_to_vconsole();
+
+ return 0;
+}
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index 1c75565636..0fc2720b43 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -1554,7 +1554,7 @@ static int loginctl_main(int argc, char *argv[], sd_bus *bus) {
}
int main(int argc, char *argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
@@ -1576,6 +1576,8 @@ int main(int argc, char *argv[]) {
r = loginctl_main(argc, argv, bus);
finish:
+ sd_bus_flush_close_unref(bus);
+
pager_close();
polkit_agent_close();
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index a826321bf0..de44d369cf 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -843,7 +843,6 @@ int config_parse_tmpfs_size(
void *userdata) {
size_t *sz = data;
- const char *e;
int r;
assert(filename);
@@ -851,29 +850,17 @@ int config_parse_tmpfs_size(
assert(rvalue);
assert(data);
- e = endswith(rvalue, "%");
- if (e) {
- unsigned long ul;
- char *f;
-
- errno = 0;
- ul = strtoul(rvalue, &f, 10);
- if (errno > 0 || f != e) {
- log_syntax(unit, LOG_ERR, filename, line, errno, "Failed to parse percentage value, ignoring: %s", rvalue);
- return 0;
- }
-
- if (ul <= 0 || ul >= 100) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Percentage value out of range, ignoring: %s", rvalue);
- return 0;
- }
-
- *sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) ul) / (uint64_t) 100));
- } else {
+ /* First, try to parse as percentage */
+ r = parse_percent(rvalue);
+ if (r > 0 && r < 100)
+ *sz = physical_memory_scale(r, 100U);
+ else {
uint64_t k;
+ /* If the passed argument was not a percentage, or out of range, parse as byte size */
+
r = parse_size(rvalue, 1024, &k);
- if (r < 0 || (uint64_t) (size_t) k != k) {
+ if (r < 0 || k <= 0 || (uint64_t) (size_t) k != k) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
return 0;
}
diff --git a/src/login/logind.c b/src/login/logind.c
index caf149cfb7..d01dd110ea 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -61,7 +61,7 @@ static void manager_reset_config(Manager *m) {
m->idle_action_usec = 30 * USEC_PER_MINUTE;
m->idle_action = HANDLE_IGNORE;
- m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
+ m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
m->user_tasks_max = 12288;
m->sessions_max = 8192;
m->inhibitors_max = 8192;
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 98dc201340..4f023640f6 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -182,25 +182,20 @@ static int export_legacy_dbus_address(
_cleanup_free_ char *s = NULL;
int r = PAM_BUF_ERR;
- if (is_kdbus_available()) {
- if (asprintf(&s, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, uid, runtime) < 0)
- goto error;
- } else {
- /* FIXME: We *really* should move the access() check into the
- * daemons that spawn dbus-daemon, instead of forcing
- * DBUS_SESSION_BUS_ADDRESS= here. */
-
- s = strjoin(runtime, "/bus", NULL);
- if (!s)
- goto error;
-
- if (access(s, F_OK) < 0)
- return PAM_SUCCESS;
+ /* FIXME: We *really* should move the access() check into the
+ * daemons that spawn dbus-daemon, instead of forcing
+ * DBUS_SESSION_BUS_ADDRESS= here. */
- s = mfree(s);
- if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, runtime) < 0)
- goto error;
- }
+ s = strjoin(runtime, "/bus", NULL);
+ if (!s)
+ goto error;
+
+ if (access(s, F_OK) < 0)
+ return PAM_SUCCESS;
+
+ s = mfree(s);
+ if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, runtime) < 0)
+ goto error;
r = pam_misc_setenv(handle, "DBUS_SESSION_BUS_ADDRESS", s, 0);
if (r != PAM_SUCCESS)
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index afe5026373..583d2a21e7 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -2751,7 +2751,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
}
int main(int argc, char*argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
@@ -2773,6 +2773,7 @@ int main(int argc, char*argv[]) {
r = machinectl_main(argc, argv, bus);
finish:
+ sd_bus_flush_close_unref(bus);
pager_close();
polkit_agent_close();
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 735c231a4c..2d81311e81 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -138,7 +138,7 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
ll_addr->family = AF_INET;
ll_addr->in_addr.in = address;
ll_addr->prefixlen = 16;
- ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htonl(0xfffffffflu >> ll_addr->prefixlen);
+ ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htobe32(0xfffffffflu >> ll_addr->prefixlen);
ll_addr->scope = RT_SCOPE_LINK;
r = address_configure(ll_addr, link, ipv4ll_address_handler, false);
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 0302f57f26..1842685180 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1600,7 +1600,7 @@ static int link_up(Link *link) {
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
/* set it free if not enslaved with networkd */
- if (!link->network->bridge && !link->network->bond) {
+ if (!link->network->bridge && !link->network->bond && !link->network->vrf) {
r = sd_netlink_message_append_u32(req, IFLA_MASTER, 0);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFLA_MASTER attribute: %m");
@@ -2005,7 +2005,7 @@ static int link_joined(Link *link) {
log_link_error_errno(link, r, "Could not set bridge message: %m");
}
- if (link->network->bridge || streq("bridge", link->kind)) {
+ if (link->network->bridge || streq_ptr("bridge", link->kind)) {
r = link_set_bridge_vlan(link);
if (r < 0)
log_link_error_errno(link, r, "Could not set bridge vlan: %m");
@@ -2055,6 +2055,7 @@ static int link_enter_join_netdev(Link *link) {
if (!link->network->bridge &&
!link->network->bond &&
+ !link->network->vrf &&
hashmap_isempty(link->network->stacked_netdevs))
return link_joined(link);
@@ -2101,6 +2102,26 @@ static int link_enter_join_netdev(Link *link) {
link->enslaving++;
}
+ if (link->network->vrf) {
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(link->network->vrf),
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", link->network->vrf->ifname),
+ NULL);
+ r = netdev_join(link->network->vrf, link, netdev_join_handler);
+ if (r < 0) {
+ log_struct_errno(LOG_WARNING, r,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(link->network->vrf),
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", link->network->vrf->ifname),
+ NULL);
+ link_enter_failed(link);
+ return r;
+ }
+
+ link->enslaving++;
+ }
+
HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
log_struct(LOG_DEBUG,
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index a9512cd77b..9d69f61376 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -11,6 +11,7 @@
#include "networkd-netdev-veth.h"
#include "networkd-netdev-vlan.h"
#include "networkd-netdev-vxlan.h"
+#include "networkd-netdev-vrf.h"
#include "networkd-netdev.h"
#include "vlan-util.h"
%}
@@ -42,6 +43,9 @@ Tunnel.Local, config_parse_tunnel_address, 0,
Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
+Tunnel.Key, config_parse_tunnel_key, 0, offsetof(Tunnel, key)
+Tunnel.InputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, ikey)
+Tunnel.OutputKey, config_parse_tunnel_key, 0, offsetof(Tunnel, okey)
Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode)
Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel)
@@ -102,3 +106,4 @@ Bridge.ForwardDelaySec, config_parse_sec, 0,
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)
+VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table_id)
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c
index 7aaa041ba3..77a4734df8 100644
--- a/src/network/networkd-netdev-tunnel.c
+++ b/src/network/networkd-netdev-tunnel.c
@@ -35,7 +35,7 @@
#include "util.h"
#define DEFAULT_TNL_HOP_LIMIT 64
-#define IP6_FLOWINFO_FLOWLABEL htonl(0x000FFFFF)
+#define IP6_FLOWINFO_FLOWLABEL htobe32(0x000FFFFF)
static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = {
[NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6",
@@ -200,6 +200,33 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl
return r;
}
+static int netdev_vti_fill_message_key(NetDev *netdev, Link *link, sd_netlink_message *m) {
+ Tunnel *t = VTI(netdev);
+ uint32_t ikey, okey;
+ int r;
+
+ assert(link);
+ assert(m);
+ assert(t);
+
+ if (t->key != 0)
+ ikey = okey = htobe32(t->key);
+ else {
+ ikey = htobe32(t->ikey);
+ okey = htobe32(t->okey);
+ }
+
+ r = sd_netlink_message_append_u32(m, IFLA_VTI_IKEY, ikey);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_IKEY attribute: %m");
+
+ r = sd_netlink_message_append_u32(m, IFLA_VTI_OKEY, okey);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IFLA_VTI_OKEY attribute: %m");
+
+ return 0;
+}
+
static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
Tunnel *t = VTI(netdev);
int r;
@@ -214,6 +241,10 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_netlink
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
+ r = netdev_vti_fill_message_key(netdev, link, m);
+ if (r < 0)
+ return r;
+
r = sd_netlink_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
@@ -239,6 +270,10 @@ static int netdev_vti6_fill_message_create(NetDev *netdev, Link *link, sd_netlin
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LINK attribute: %m");
+ r = netdev_vti_fill_message_key(netdev, link, m);
+ if (r < 0)
+ return r;
+
r = sd_netlink_message_append_in6_addr(m, IFLA_VTI_LOCAL, &t->local.in6);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m");
@@ -413,6 +448,46 @@ int config_parse_tunnel_address(const char *unit,
return 0;
}
+int config_parse_tunnel_key(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) {
+ union in_addr_union buffer;
+ Tunnel *t = userdata;
+ uint32_t k;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = in_addr_from_string(AF_INET, rvalue, &buffer);
+ if (r < 0) {
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse tunnel key ignoring assignment: %s", rvalue);
+ return 0;
+ }
+ } else
+ k = be32toh(buffer.in.s_addr);
+
+ if (streq(lvalue, "Key"))
+ t->key = k;
+ else if (streq(lvalue, "InputKey"))
+ t->ikey = k;
+ else
+ t->okey = k;
+
+ return 0;
+}
+
int config_parse_ipv6_flowlabel(const char* unit,
const char *filename,
unsigned line,
@@ -444,7 +519,7 @@ int config_parse_ipv6_flowlabel(const char* unit,
if (k > 0xFFFFF)
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue);
else {
- *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL;
+ *ipv6_flowlabel = htobe32(k) & IP6_FLOWINFO_FLOWLABEL;
t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL;
}
}
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h
index 7d31e7b687..32a46bd82f 100644
--- a/src/network/networkd-netdev-tunnel.h
+++ b/src/network/networkd-netdev-tunnel.h
@@ -49,6 +49,10 @@ typedef struct Tunnel {
unsigned tos;
unsigned flags;
+ uint32_t key;
+ uint32_t ikey;
+ uint32_t okey;
+
union in_addr_union local;
union in_addr_union remote;
@@ -108,3 +112,8 @@ int config_parse_encap_limit(const char *unit, const char *filename,
unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data,
void *userdata);
+int config_parse_tunnel_key(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);
diff --git a/src/network/networkd-netdev-vrf.c b/src/network/networkd-netdev-vrf.c
new file mode 100644
index 0000000000..89bd142e8c
--- /dev/null
+++ b/src/network/networkd-netdev-vrf.c
@@ -0,0 +1,50 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Andreas Rammhold <andreas@rammhold.de>
+
+ 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 "sd-netlink.h"
+#include "missing.h"
+#include "networkd-netdev-vrf.h"
+
+static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
+ Vrf *v;
+ int r;
+
+ assert(netdev);
+ assert(!link);
+ assert(m);
+
+ v = VRF(netdev);
+
+ assert(v);
+
+ r = sd_netlink_message_append_u32(m, IFLA_VRF_TABLE, v->table_id);
+ if (r < 0)
+ return log_netdev_error_errno(netdev, r, "Could not append IPLA_VRF_TABLE attribute: %m");
+
+ return r;
+}
+
+const NetDevVTable vrf_vtable = {
+ .object_size = sizeof(Vrf),
+ .sections = "NetDev\0VRF\0",
+ .fill_message_create = netdev_vrf_fill_message_create,
+ .create_type = NETDEV_CREATE_MASTER,
+};
diff --git a/src/network/networkd-netdev-vrf.h b/src/network/networkd-netdev-vrf.h
new file mode 100644
index 0000000000..3d92a26a4d
--- /dev/null
+++ b/src/network/networkd-netdev-vrf.h
@@ -0,0 +1,33 @@
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 Andreas Rammhold <andreas@rammhold.de>
+
+ 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 Vrf Vrf;
+
+#include "networkd-netdev.h"
+
+struct Vrf {
+ NetDev meta;
+
+ uint32_t table_id;
+};
+
+DEFINE_NETDEV_CAST(VRF, Vrf);
+extern const NetDevVTable vrf_vtable;
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 851a36290c..b192884fd9 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -55,6 +55,8 @@ const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_TUN] = &tun_vtable,
[NETDEV_KIND_TAP] = &tap_vtable,
[NETDEV_KIND_IP6TNL] = &ip6tnl_vtable,
+ [NETDEV_KIND_VRF] = &vrf_vtable,
+
};
static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
@@ -78,6 +80,8 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
[NETDEV_KIND_TUN] = "tun",
[NETDEV_KIND_TAP] = "tap",
[NETDEV_KIND_IP6TNL] = "ip6tnl",
+ [NETDEV_KIND_VRF] = "vrf",
+
};
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
@@ -198,7 +202,7 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h
assert(netdev->state == NETDEV_STATE_READY);
assert(netdev->manager);
assert(netdev->manager->rtnl);
- assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
+ assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF));
assert(link);
assert(callback);
@@ -281,7 +285,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call
assert(netdev);
assert(netdev->manager);
assert(netdev->manager->rtnl);
- assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND));
+ assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND, NETDEV_KIND_VRF));
if (netdev->state == NETDEV_STATE_READY) {
r = netdev_enslave_ready(netdev, link, callback);
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 20244c0309..b92a973b85 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -55,6 +55,7 @@ typedef enum NetDevKind {
NETDEV_KIND_DUMMY,
NETDEV_KIND_TUN,
NETDEV_KIND_TAP,
+ NETDEV_KIND_VRF,
_NETDEV_KIND_MAX,
_NETDEV_KIND_INVALID = -1
} NetDevKind;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 0b0aa58f67..affc0d00e9 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -37,6 +37,7 @@ Network.MACVTAP, config_parse_netdev,
Network.IPVLAN, config_parse_netdev, 0, 0
Network.VXLAN, config_parse_netdev, 0, 0
Network.Tunnel, config_parse_tunnel, 0, 0
+Network.VRF, config_parse_netdev, 0, 0
Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp)
Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server)
Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 84bdf75b38..2b764d4f24 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -244,8 +244,8 @@ void network_free(Network *network) {
strv_free(network->bind_carrier);
netdev_unref(network->bridge);
-
netdev_unref(network->bond);
+ netdev_unref(network->vrf);
HASHMAP_FOREACH(netdev, network->stacked_netdevs, i) {
hashmap_remove(network->stacked_netdevs, netdev->ifname);
@@ -471,6 +471,10 @@ int config_parse_netdev(const char *unit,
network->bond = netdev;
break;
+ case NETDEV_KIND_VRF:
+ network->vrf = netdev;
+
+ break;
case NETDEV_KIND_VLAN:
case NETDEV_KIND_MACVLAN:
case NETDEV_KIND_MACVTAP:
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 38688cc400..08ee939faa 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -104,6 +104,7 @@ struct Network {
NetDev *bridge;
NetDev *bond;
+ NetDev *vrf;
Hashmap *stacked_netdevs;
/* DHCP Client Support */
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 52037f9c6d..cedaf47cf8 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -795,6 +795,7 @@ int config_parse_route_priority(const char *unit,
void *userdata) {
Network *network = userdata;
_cleanup_route_free_ Route *n = NULL;
+ uint32_t k;
int r;
assert(filename);
@@ -807,12 +808,14 @@ int config_parse_route_priority(const char *unit,
if (r < 0)
return r;
- r = config_parse_uint32(unit, filename, line, section,
- section_line, lvalue, ltype,
- rvalue, &n->priority, userdata);
- if (r < 0)
- return r;
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Could not parse route priority \"%s\", ignoring assignment: %m", rvalue);
+ return 0;
+ }
+ n->priority = k;
n = NULL;
return 0;
diff --git a/src/network/networkd.h b/src/network/networkd.h
index ab512f0d08..c4bd712147 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -41,6 +41,7 @@
#include "networkd-netdev-tuntap.h"
#include "networkd-netdev-veth.h"
#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-vrf.h"
#include "networkd-netdev-vxlan.h"
#include "networkd-network.h"
#include "networkd-util.h"
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
index 2d145b68a7..54db1b47f8 100644
--- a/src/nspawn/nspawn-seccomp.c
+++ b/src/nspawn/nspawn-seccomp.c
@@ -44,20 +44,76 @@ static int seccomp_add_default_syscall_filter(scmp_filter_ctx ctx,
uint64_t capability;
int syscall_num;
} blacklist[] = {
- { CAP_SYS_RAWIO, SCMP_SYS(iopl) },
- { CAP_SYS_RAWIO, SCMP_SYS(ioperm) },
- { CAP_SYS_BOOT, SCMP_SYS(kexec_load) },
- { CAP_SYS_ADMIN, SCMP_SYS(swapon) },
- { CAP_SYS_ADMIN, SCMP_SYS(swapoff) },
- { CAP_SYS_ADMIN, SCMP_SYS(open_by_handle_at) },
- { CAP_SYS_MODULE, SCMP_SYS(init_module) },
- { CAP_SYS_MODULE, SCMP_SYS(finit_module) },
- { CAP_SYS_MODULE, SCMP_SYS(delete_module) },
- { CAP_SYSLOG, SCMP_SYS(syslog) },
+ { 0, SCMP_SYS(_sysctl) }, /* obsolete syscall */
+ { 0, SCMP_SYS(add_key) }, /* keyring is not namespaced */
+ { 0, SCMP_SYS(afs_syscall) }, /* obsolete syscall */
+ { 0, SCMP_SYS(bdflush) },
+#ifdef __NR_bpf
+ { 0, SCMP_SYS(bpf) },
+#endif
+ { 0, SCMP_SYS(break) }, /* obsolete syscall */
+ { 0, SCMP_SYS(create_module) }, /* obsolete syscall */
+ { 0, SCMP_SYS(ftime) }, /* obsolete syscall */
+ { 0, SCMP_SYS(get_kernel_syms) }, /* obsolete syscall */
+ { 0, SCMP_SYS(getpmsg) }, /* obsolete syscall */
+ { 0, SCMP_SYS(gtty) }, /* obsolete syscall */
+#ifdef __NR_kexec_file_load
+ { 0, SCMP_SYS(kexec_file_load) },
+#endif
+ { 0, SCMP_SYS(kexec_load) },
+ { 0, SCMP_SYS(keyctl) }, /* keyring is not namespaced */
+ { 0, SCMP_SYS(lock) }, /* obsolete syscall */
+ { 0, SCMP_SYS(lookup_dcookie) },
+ { 0, SCMP_SYS(mpx) }, /* obsolete syscall */
+ { 0, SCMP_SYS(nfsservctl) }, /* obsolete syscall */
+ { 0, SCMP_SYS(open_by_handle_at) },
+ { 0, SCMP_SYS(perf_event_open) },
+ { 0, SCMP_SYS(prof) }, /* obsolete syscall */
+ { 0, SCMP_SYS(profil) }, /* obsolete syscall */
+ { 0, SCMP_SYS(putpmsg) }, /* obsolete syscall */
+ { 0, SCMP_SYS(query_module) }, /* obsolete syscall */
+ { 0, SCMP_SYS(quotactl) },
+ { 0, SCMP_SYS(request_key) }, /* keyring is not namespaced */
+ { 0, SCMP_SYS(security) }, /* obsolete syscall */
+ { 0, SCMP_SYS(sgetmask) }, /* obsolete syscall */
+ { 0, SCMP_SYS(ssetmask) }, /* obsolete syscall */
+ { 0, SCMP_SYS(stty) }, /* obsolete syscall */
+ { 0, SCMP_SYS(swapoff) },
+ { 0, SCMP_SYS(swapon) },
+ { 0, SCMP_SYS(sysfs) }, /* obsolete syscall */
+ { 0, SCMP_SYS(tuxcall) }, /* obsolete syscall */
+ { 0, SCMP_SYS(ulimit) }, /* obsolete syscall */
+ { 0, SCMP_SYS(uselib) }, /* obsolete syscall */
+ { 0, SCMP_SYS(ustat) }, /* obsolete syscall */
+ { 0, SCMP_SYS(vserver) }, /* obsolete syscall */
+ { CAP_SYSLOG, SCMP_SYS(syslog) },
+ { CAP_SYS_MODULE, SCMP_SYS(delete_module) },
+ { CAP_SYS_MODULE, SCMP_SYS(finit_module) },
+ { CAP_SYS_MODULE, SCMP_SYS(init_module) },
+ { CAP_SYS_PACCT, SCMP_SYS(acct) },
+ { CAP_SYS_PTRACE, SCMP_SYS(process_vm_readv) },
+ { CAP_SYS_PTRACE, SCMP_SYS(process_vm_writev) },
+ { CAP_SYS_PTRACE, SCMP_SYS(ptrace) },
+ { CAP_SYS_RAWIO, SCMP_SYS(ioperm) },
+ { CAP_SYS_RAWIO, SCMP_SYS(iopl) },
+ { CAP_SYS_RAWIO, SCMP_SYS(pciconfig_iobase) },
+ { CAP_SYS_RAWIO, SCMP_SYS(pciconfig_read) },
+ { CAP_SYS_RAWIO, SCMP_SYS(pciconfig_write) },
+#ifdef __NR_s390_pci_mmio_read
+ { CAP_SYS_RAWIO, SCMP_SYS(s390_pci_mmio_read) },
+#endif
+#ifdef __NR_s390_pci_mmio_write
+ { CAP_SYS_RAWIO, SCMP_SYS(s390_pci_mmio_write) },
+#endif
+ { CAP_SYS_TIME, SCMP_SYS(adjtimex) },
+ { CAP_SYS_TIME, SCMP_SYS(clock_adjtime) },
+ { CAP_SYS_TIME, SCMP_SYS(clock_settime) },
+ { CAP_SYS_TIME, SCMP_SYS(settimeofday) },
+ { CAP_SYS_TIME, SCMP_SYS(stime) },
};
for (i = 0; i < ELEMENTSOF(blacklist); i++) {
- if (cap_list_retain & (1ULL << blacklist[i].capability))
+ if (blacklist[i].capability != 0 && (cap_list_retain & (1ULL << blacklist[i].capability)))
continue;
r = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), blacklist[i].syscall_num, 0);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index ea24de7608..73c56d7310 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -137,6 +137,8 @@ static bool arg_ephemeral = false;
static LinkJournal arg_link_journal = LINK_AUTO;
static bool arg_link_journal_try = false;
static uint64_t arg_caps_retain =
+ (1ULL << CAP_AUDIT_CONTROL) |
+ (1ULL << CAP_AUDIT_WRITE) |
(1ULL << CAP_CHOWN) |
(1ULL << CAP_DAC_OVERRIDE) |
(1ULL << CAP_DAC_READ_SEARCH) |
@@ -146,23 +148,21 @@ static uint64_t arg_caps_retain =
(1ULL << CAP_KILL) |
(1ULL << CAP_LEASE) |
(1ULL << CAP_LINUX_IMMUTABLE) |
+ (1ULL << CAP_MKNOD) |
(1ULL << CAP_NET_BIND_SERVICE) |
(1ULL << CAP_NET_BROADCAST) |
(1ULL << CAP_NET_RAW) |
- (1ULL << CAP_SETGID) |
(1ULL << CAP_SETFCAP) |
+ (1ULL << CAP_SETGID) |
(1ULL << CAP_SETPCAP) |
(1ULL << CAP_SETUID) |
(1ULL << CAP_SYS_ADMIN) |
+ (1ULL << CAP_SYS_BOOT) |
(1ULL << CAP_SYS_CHROOT) |
(1ULL << CAP_SYS_NICE) |
(1ULL << CAP_SYS_PTRACE) |
- (1ULL << CAP_SYS_TTY_CONFIG) |
(1ULL << CAP_SYS_RESOURCE) |
- (1ULL << CAP_SYS_BOOT) |
- (1ULL << CAP_AUDIT_WRITE) |
- (1ULL << CAP_AUDIT_CONTROL) |
- (1ULL << CAP_MKNOD);
+ (1ULL << CAP_SYS_TTY_CONFIG);
static CustomMount *arg_custom_mounts = NULL;
static unsigned arg_n_custom_mounts = 0;
static char **arg_setenv = NULL;
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index 2b83d127b7..9a6e157e12 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -38,7 +38,7 @@
* IPv6 we use ::1 which unfortunately will not translate back to the
* hostname but instead something like "localhost" or so. */
-#define LOCALADDRESS_IPV4 (htonl(0x7F000002))
+#define LOCALADDRESS_IPV4 (htobe32(0x7F000002))
#define LOCALADDRESS_IPV6 &in6addr_loopback
NSS_GETHOSTBYNAME_PROTOTYPES(myhostname);
@@ -75,7 +75,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
* is optional */
canonical = "localhost";
- local_address_ipv4 = htonl(INADDR_LOOPBACK);
+ local_address_ipv4 = htobe32(INADDR_LOOPBACK);
} else if (is_gateway_hostname(name)) {
@@ -348,7 +348,7 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
if (is_localhost(name)) {
canonical = "localhost";
- local_address_ipv4 = htonl(INADDR_LOOPBACK);
+ local_address_ipv4 = htobe32(INADDR_LOOPBACK);
} else if (is_gateway_hostname(name)) {
@@ -437,9 +437,9 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
if ((*(uint32_t*) addr) == LOCALADDRESS_IPV4)
goto found;
- if ((*(uint32_t*) addr) == htonl(INADDR_LOOPBACK)) {
+ if ((*(uint32_t*) addr) == htobe32(INADDR_LOOPBACK)) {
canonical = "localhost";
- local_address_ipv4 = htonl(INADDR_LOOPBACK);
+ local_address_ipv4 = htobe32(INADDR_LOOPBACK);
goto found;
}
diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c
index bc6dcf04a4..2cb2e42b23 100644
--- a/src/resolve/resolve-tool.c
+++ b/src/resolve/resolve-tool.c
@@ -199,7 +199,7 @@ static int resolve_host(sd_bus *bus, const char *name) {
if (ifindex > 0 && !if_indextoname(ifindex, ifname))
log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex);
- r = in_addr_to_string(family, a, &pretty);
+ r = in_addr_ifindex_to_string(family, a, ifindex, &pretty);
if (r < 0)
return log_error_errno(r, "Failed to print address for %s: %m", name);
@@ -253,7 +253,7 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
if (ifindex <= 0)
ifindex = arg_ifindex;
- r = in_addr_to_string(family, address, &pretty);
+ r = in_addr_ifindex_to_string(family, address, ifindex, &pretty);
if (r < 0)
return log_oom();
@@ -345,31 +345,6 @@ static int resolve_address(sd_bus *bus, int family, const union in_addr_union *a
return 0;
}
-static int parse_address(const char *s, int *family, union in_addr_union *address, int *ifindex) {
- const char *percent, *a;
- int ifi = 0;
- int r;
-
- percent = strchr(s, '%');
- if (percent) {
- if (parse_ifindex(percent+1, &ifi) < 0) {
- ifi = if_nametoindex(percent+1);
- if (ifi <= 0)
- return -EINVAL;
- }
-
- a = strndupa(s, percent - s);
- } else
- a = s;
-
- r = in_addr_from_string_auto(a, family, address);
- if (r < 0)
- return r;
-
- *ifindex = ifi;
- return 0;
-}
-
static int output_rr_packet(const void *d, size_t l, int ifindex) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
@@ -1392,7 +1367,7 @@ int main(int argc, char **argv) {
if (startswith(argv[optind], "dns:"))
k = resolve_rfc4501(bus, argv[optind]);
else {
- k = parse_address(argv[optind], &family, &a, &ifindex);
+ k = in_addr_ifindex_from_string_auto(argv[optind], &family, &a, &ifindex);
if (k >= 0)
k = resolve_address(bus, family, &a, ifindex);
else
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index 6d86cbf123..f08c6c0637 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -245,17 +245,22 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *canonical = NULL;
union in_addr_union parsed;
- int r, ff;
+ int r, ff, parsed_ifindex = 0;
/* Check if the hostname is actually already an IP address formatted as string. In that case just parse it,
* let's not attempt to look it up. */
- r = in_addr_from_string_auto(hostname, &ff, &parsed);
+ r = in_addr_ifindex_from_string_auto(hostname, &ff, &parsed, &parsed_ifindex);
if (r < 0) /* not an address */
return 0;
if (family != AF_UNSPEC && ff != family)
return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address is not of the requested family.");
+ if (ifindex > 0 && parsed_ifindex > 0 && parsed_ifindex != ifindex)
+ return sd_bus_reply_method_errorf(m, BUS_ERROR_NO_SUCH_RR, "The specified address interface index does not match requested interface.");
+
+ if (parsed_ifindex > 0)
+ ifindex = parsed_ifindex;
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
@@ -288,7 +293,7 @@ static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname
/* When an IP address is specified we just return it as canonical name, in order to avoid a DNS
* look-up. However, we reformat it to make sure it's in a truly canonical form (i.e. on IPv6 the inner
* omissions are always done the same way). */
- r = in_addr_to_string(ff, &parsed, &canonical);
+ r = in_addr_ifindex_to_string(ff, &parsed, ifindex, &canonical);
if (r < 0)
return r;
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index 0dadf8b1dd..13dcba8421 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -185,7 +185,7 @@ int dns_answer_add_extend(DnsAnswer **a, DnsResourceRecord *rr, int ifindex, Dns
return dns_answer_add(*a, rr, ifindex, flags);
}
-int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl) {
+int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl, int ifindex) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *soa = NULL;
soa = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_SOA, name);
@@ -208,7 +208,7 @@ int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl) {
soa->soa.expire = 1;
soa->soa.minimum = ttl;
- return dns_answer_add(a, soa, 0, DNS_ANSWER_AUTHENTICATED);
+ return dns_answer_add(a, soa, ifindex, DNS_ANSWER_AUTHENTICATED);
}
int dns_answer_match_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *ret_flags) {
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index 0679c610f5..b2b86d1772 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -56,7 +56,7 @@ DnsAnswer *dns_answer_unref(DnsAnswer *a);
int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags);
int dns_answer_add_extend(DnsAnswer **a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags);
-int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl);
+int dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl, int ifindex);
int dns_answer_match_key(DnsAnswer *a, const DnsResourceKey *key, DnsAnswerFlags *combined_flags);
int dns_answer_contains_rr(DnsAnswer *a, DnsResourceRecord *rr, DnsAnswerFlags *combined_flags);
diff --git a/src/resolve/resolved-dns-scope.c b/src/resolve/resolved-dns-scope.c
index 6a69d7b7c2..9d484d0a48 100644
--- a/src/resolve/resolved-dns-scope.c
+++ b/src/resolve/resolved-dns-scope.c
@@ -721,7 +721,7 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
assert(p->question->n_keys == 1);
key = p->question->keys[0];
- r = dns_zone_lookup(&s->zone, key, &answer, &soa, &tentative);
+ r = dns_zone_lookup(&s->zone, key, 0, &answer, &soa, &tentative);
if (r < 0) {
log_debug_errno(r, "Failed to lookup key: %m");
return;
@@ -1029,3 +1029,12 @@ bool dns_scope_network_good(DnsScope *s) {
return manager_routable(s->manager, AF_UNSPEC);
}
+
+int dns_scope_ifindex(DnsScope *s) {
+ assert(s);
+
+ if (s->link)
+ return s->link->ifindex;
+
+ return 0;
+}
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index 291e5817d0..538bc61f81 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -107,3 +107,5 @@ DnsSearchDomain *dns_scope_get_search_domains(DnsScope *s);
bool dns_scope_name_needs_search_domain(DnsScope *s, const char *name);
bool dns_scope_network_good(DnsScope *s);
+
+int dns_scope_ifindex(DnsScope *s);
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index a4a67623e7..bcb1b6d8a7 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -404,8 +404,12 @@ static void dns_transaction_retry(DnsTransaction *t) {
}
static int dns_transaction_maybe_restart(DnsTransaction *t) {
+ int r;
+
assert(t);
+ /* Returns > 0 if the transaction was restarted, 0 if not */
+
if (!t->server)
return 0;
@@ -420,7 +424,12 @@ static int dns_transaction_maybe_restart(DnsTransaction *t) {
log_debug("Server feature level is now lower than when we began our transaction. Restarting with new ID.");
dns_transaction_shuffle_id(t);
- return dns_transaction_go(t);
+
+ r = dns_transaction_go(t);
+ if (r < 0)
+ return r;
+
+ return 1;
}
static int on_stream_complete(DnsStream *s, int error) {
@@ -557,8 +566,7 @@ static int dns_transaction_open_tcp(DnsTransaction *t) {
/* The interface index is difficult to determine if we are
* connecting to the local host, hence fill this in right away
* instead of determining it from the socket */
- if (t->scope->link)
- t->stream->ifindex = t->scope->link->ifindex;
+ t->stream->ifindex = dns_scope_ifindex(t->scope);
dns_transaction_reset_answer(t);
@@ -798,12 +806,9 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
switch (t->scope->protocol) {
case DNS_PROTOCOL_LLMNR:
- assert(t->scope->link);
-
- /* For LLMNR we will not accept any packets from other
- * interfaces */
+ /* For LLMNR we will not accept any packets from other interfaces */
- if (p->ifindex != t->scope->link->ifindex)
+ if (p->ifindex != dns_scope_ifindex(t->scope))
return;
if (p->family != t->scope->family)
@@ -820,10 +825,9 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
break;
case DNS_PROTOCOL_MDNS:
- assert(t->scope->link);
-
/* For mDNS we will not accept any packets from other interfaces */
- if (p->ifindex != t->scope->link->ifindex)
+
+ if (p->ifindex != dns_scope_ifindex(t->scope))
return;
if (p->family != t->scope->family)
@@ -1246,7 +1250,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
* for probing or verifying a zone item. */
if (set_isempty(t->notify_zone_items)) {
- r = dns_zone_lookup(&t->scope->zone, t->key, &t->answer, NULL, NULL);
+ r = dns_zone_lookup(&t->scope->zone, t->key, dns_scope_ifindex(t->scope), &t->answer, NULL, NULL);
if (r < 0)
return r;
if (r > 0) {
@@ -1426,6 +1430,9 @@ int dns_transaction_go(DnsTransaction *t) {
assert(t);
+ /* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has finished
+ * now. */
+
assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &ts) >= 0);
r = dns_transaction_prepare(t, ts);
diff --git a/src/resolve/resolved-dns-zone.c b/src/resolve/resolved-dns-zone.c
index 850eed8cb8..746a979f47 100644
--- a/src/resolve/resolved-dns-zone.c
+++ b/src/resolve/resolved-dns-zone.c
@@ -287,13 +287,16 @@ int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe) {
return 0;
}
-int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
+int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **ret_answer, DnsAnswer **ret_soa, bool *ret_tentative) {
_cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL, *soa = NULL;
unsigned n_answer = 0;
DnsZoneItem *j, *first;
bool tentative = true, need_soa = false;
int r;
+ /* Note that we don't actually need the ifindex for anything. However when it is passed we'll initialize the
+ * ifindex field in the answer with it */
+
assert(z);
assert(key);
assert(ret_answer);
@@ -389,7 +392,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
if (k < 0)
return k;
if (k > 0) {
- r = dns_answer_add(answer, j->rr, 0, DNS_ANSWER_AUTHENTICATED);
+ r = dns_answer_add(answer, j->rr, ifindex, DNS_ANSWER_AUTHENTICATED);
if (r < 0)
return r;
@@ -398,7 +401,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (found && !added) {
- r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL);
+ r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL, ifindex);
if (r < 0)
return r;
}
@@ -415,7 +418,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
if (j->state != DNS_ZONE_ITEM_PROBING)
tentative = false;
- r = dns_answer_add(answer, j->rr, 0, DNS_ANSWER_AUTHENTICATED);
+ r = dns_answer_add(answer, j->rr, ifindex, DNS_ANSWER_AUTHENTICATED);
if (r < 0)
return r;
}
@@ -435,7 +438,7 @@ int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **ret_answer, Dns
}
if (add_soa) {
- r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL);
+ r = dns_answer_add_soa(soa, dns_resource_key_name(key), LLMNR_DEFAULT_TTL, ifindex);
if (r < 0)
return r;
}
diff --git a/src/resolve/resolved-dns-zone.h b/src/resolve/resolved-dns-zone.h
index 408833c359..a41df37e6b 100644
--- a/src/resolve/resolved-dns-zone.h
+++ b/src/resolve/resolved-dns-zone.h
@@ -65,7 +65,7 @@ void dns_zone_flush(DnsZone *z);
int dns_zone_put(DnsZone *z, DnsScope *s, DnsResourceRecord *rr, bool probe);
void dns_zone_remove_rr(DnsZone *z, DnsResourceRecord *rr);
-int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
+int dns_zone_lookup(DnsZone *z, DnsResourceKey *key, int ifindex, DnsAnswer **answer, DnsAnswer **soa, bool *tentative);
void dns_zone_item_conflict(DnsZoneItem *i);
void dns_zone_item_notify(DnsZoneItem *i);
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index a46f13b92f..23101cb760 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -474,7 +474,6 @@ static int manager_sigusr2(sd_event_source *s, const struct signalfd_siginfo *si
assert(m);
manager_flush_caches(m);
- log_info("Flushed all caches.");
return 0;
}
@@ -1257,4 +1256,6 @@ void manager_flush_caches(Manager *m) {
LIST_FOREACH(scopes, scope, m->dns_scopes)
dns_cache_flush(&scope->cache);
+
+ log_info("Flushed all caches.");
}
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index 8f4f93ee0c..04471e2373 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -83,18 +83,14 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
if (isempty(eq))
r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
- else if (endswith(eq, "%")) {
- double percent;
-
- if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
- log_error("CPU quota '%s' invalid.", eq);
+ else {
+ r = parse_percent(eq);
+ if (r <= 0) {
+ log_error_errno(r, "CPU quota '%s' invalid.", eq);
return -EINVAL;
}
- r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100);
- } else {
- log_error("CPU quota needs to be in percent.");
- return -EINVAL;
+ r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U);
}
goto finish;
@@ -110,6 +106,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
char *n;
usec_t t;
size_t l;
+
r = parse_sec(eq, &t);
if (r < 0)
return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq);
@@ -123,6 +120,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
strcpy(mempcpy(n, field, l - 3), "USec");
r = sd_bus_message_append(m, "sv", n, "t", t);
goto finish;
+
+ } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemoryLimit")) {
+ uint64_t bytes;
+
+ if (isempty(eq) || streq(eq, "infinity"))
+ bytes = CGROUP_LIMIT_MAX;
+ else {
+ r = parse_percent(eq);
+ if (r >= 0) {
+ char *n;
+
+ /* When this is a percentage we'll convert this into a relative value in the range
+ * 0…UINT32_MAX and pass it in the MemoryLowByPhysicalMemory property (and related
+ * ones). This way the physical memory size can be determined server-side */
+
+ n = strjoina(field, "ByPhysicalMemory");
+ r = sd_bus_message_append(m, "sv", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U));
+ goto finish;
+
+ } else {
+ r = parse_size(eq, 1024, &bytes);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse bytes specification %s", assignment);
+ }
+ }
+
+ r = sd_bus_message_append(m, "sv", field, "t", bytes);
+ goto finish;
}
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
@@ -166,21 +191,6 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "b", r);
- } else if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemoryLimit")) {
- uint64_t bytes;
-
- if (isempty(eq) || streq(eq, "infinity"))
- bytes = CGROUP_LIMIT_MAX;
- else {
- r = parse_size(eq, 1024, &bytes);
- if (r < 0) {
- log_error("Failed to parse bytes specification %s", assignment);
- return -EINVAL;
- }
- }
-
- r = sd_bus_message_append(m, "v", "t", bytes);
-
} else if (streq(field, "TasksMax")) {
uint64_t n;
@@ -1113,7 +1123,8 @@ static int dump_processes(
assert(n == cg->n_children);
qsort_safe(children, n, sizeof(struct CGroupInfo*), cgroup_info_compare_func);
- n_columns = MAX(LESS_BY(n_columns, 2U), 20U);
+ if (n_columns != 0)
+ n_columns = MAX(LESS_BY(n_columns, 2U), 20U);
for (i = 0; i < n; i++) {
_cleanup_free_ char *pp = NULL;
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
index 8cfa936347..8e3307dc24 100644
--- a/src/shared/bus-util.c
+++ b/src/shared/bus-util.c
@@ -1505,40 +1505,6 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send
return 1;
}
-bool is_kdbus_wanted(void) {
- _cleanup_free_ char *value = NULL;
-#ifdef ENABLE_KDBUS
- const bool configured = true;
-#else
- const bool configured = false;
-#endif
-
- int r;
-
- if (get_proc_cmdline_key("kdbus", NULL) > 0)
- return true;
-
- r = get_proc_cmdline_key("kdbus=", &value);
- if (r <= 0)
- return configured;
-
- return parse_boolean(value) == 1;
-}
-
-bool is_kdbus_available(void) {
- _cleanup_close_ int fd = -1;
- struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
-
- if (!is_kdbus_wanted())
- return false;
-
- fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
- if (fd < 0)
- return false;
-
- return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
-}
-
int bus_property_get_rlimit(
sd_bus *bus,
const char *path,
diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h
index d792258ecd..db6b1acba2 100644
--- a/src/shared/bus-util.h
+++ b/src/shared/bus-util.h
@@ -157,7 +157,4 @@ int bus_log_create_error(int r);
int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
-bool is_kdbus_wanted(void);
-bool is_kdbus_available(void);
-
int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
diff --git a/src/shared/install.c b/src/shared/install.c
index 64d66a45d3..23cab96c50 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -779,7 +779,7 @@ static int find_symlinks(
fd = open(config_path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW);
if (fd < 0) {
- if (errno == ENOENT)
+ if (IN_SET(errno, ENOENT, ENOTDIR, EACCES))
return 0;
return -errno;
}
@@ -1271,7 +1271,7 @@ static int unit_file_search(
info->path = path;
path = NULL;
return r;
- } else if (r != -ENOENT)
+ } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
return r;
}
@@ -1296,7 +1296,7 @@ static int unit_file_search(
info->path = path;
path = NULL;
return r;
- } else if (r != -ENOENT)
+ } else if (!IN_SET(r, -ENOENT, -ENOTDIR, -EACCES))
return r;
}
}
@@ -2870,6 +2870,10 @@ int unit_file_get_list(
if (!d) {
if (errno == ENOENT)
continue;
+ if (IN_SET(errno, ENOTDIR, EACCES)) {
+ log_debug("Failed to open \"%s\": %m", *i);
+ continue;
+ }
return -errno;
}
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
index 30d22d2242..8656d112b8 100644
--- a/src/shared/seccomp-util.c
+++ b/src/shared/seccomp-util.c
@@ -95,7 +95,31 @@ const SystemCallFilterSet syscall_filter_sets[] = {
.set_name = "@clock",
.value =
"adjtimex\0"
+ "clock_adjtime\0"
+ "clock_settime\0"
"settimeofday\0"
+ "stime\0"
+ }, {
+ /* CPU emulation calls */
+ .set_name = "@cpu-emulation",
+ .value =
+ "modify_ldt\0"
+ "subpage_prot\0"
+ "switch_endian\0"
+ "vm86\0"
+ "vm86old\0"
+ }, {
+ /* Debugging/Performance Monitoring/Tracing */
+ .set_name = "@debug",
+ .value =
+ "lookup_dcookie\0"
+ "perf_event_open\0"
+ "process_vm_readv\0"
+ "process_vm_writev\0"
+ "ptrace\0"
+ "rtas\0"
+ "s390_runtime_instr\0"
+ "sys_debug_setcontext\0"
}, {
/* Default list */
.set_name = "@default",
@@ -148,10 +172,16 @@ const SystemCallFilterSet syscall_filter_sets[] = {
"shmdt\0"
"shmget\0"
}, {
+ /* Keyring */
+ .set_name = "@keyring",
+ .value =
+ "add_key\0"
+ "keyctl\0"
+ "request_key\0"
+ }, {
/* Kernel module control */
.set_name = "@module",
.value =
- "create_module\0"
"delete_module\0"
"finit_module\0"
"init_module\0"
@@ -197,40 +227,26 @@ const SystemCallFilterSet syscall_filter_sets[] = {
"_sysctl\0"
"afs_syscall\0"
"break\0"
- "fattach\0"
- "fdetach\0"
+ "create_module\0"
"ftime\0"
"get_kernel_syms\0"
- "get_mempolicy\0"
- "getmsg\0"
"getpmsg\0"
"gtty\0"
- "isastream\0"
"lock\0"
- "madvise1\0"
- "modify_ldt\0"
"mpx\0"
- "pciconfig_iobase\0"
- "perf_event_open\0"
"prof\0"
"profil\0"
- "putmsg\0"
"putpmsg\0"
"query_module\0"
- "rtas\0"
- "s390_runtime_instr\0"
"security\0"
"sgetmask\0"
"ssetmask\0"
"stty\0"
- "subpage_prot\0"
- "switch_endian\0"
- "sys_debug_setcontext\0"
+ "sysfs\0"
"tuxcall\0"
"ulimit\0"
"uselib\0"
- "vm86\0"
- "vm86old\0"
+ "ustat\0"
"vserver\0"
}, {
/* Nice grab-bag of all system calls which need superuser capabilities */
@@ -242,6 +258,7 @@ const SystemCallFilterSet syscall_filter_sets[] = {
"acct\0"
"bdflush\0"
"bpf\0"
+ "capset\0"
"chown32\0"
"chown\0"
"chroot\0"
@@ -268,7 +285,6 @@ const SystemCallFilterSet syscall_filter_sets[] = {
"setreuid\0"
"setuid32\0"
"setuid\0"
- "stime\0"
"swapoff\0"
"swapon\0"
"sysctl\0"
@@ -295,6 +311,7 @@ const SystemCallFilterSet syscall_filter_sets[] = {
.value =
"ioperm\0"
"iopl\0"
+ "pciconfig_iobase\0"
"pciconfig_read\0"
"pciconfig_write\0"
"s390_pci_mmio_read\0"
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 784c1cd7b5..0dfdae4538 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -588,7 +588,8 @@ static int get_unit_list(
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, &reply);
- if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) {
+ if (r < 0 && (sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD) ||
+ sd_bus_error_has_name(&error, SD_BUS_ERROR_ACCESS_DENIED))) {
/* Fallback to legacy ListUnitsFiltered method */
fallback = true;
log_debug_errno(r, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error, r));
@@ -734,12 +735,12 @@ static int list_units(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
r = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (r < 0)
return r;
@@ -946,12 +947,12 @@ static int list_sockets(int argc, char *argv[], void *userdata) {
int r = 0, n;
sd_bus *bus;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (n < 0)
return n;
@@ -1253,12 +1254,12 @@ static int list_timers(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r = 0;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
n = get_unit_list_recursive(bus, strv_skip(argv, 1), &unit_infos, &replies, &machines);
if (n < 0)
return n;
@@ -1424,8 +1425,6 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
int r;
bool fallback = false;
- pager_open(arg_no_pager, false);
-
if (install_client_side()) {
Hashmap *h;
UnitFileList *u;
@@ -1540,6 +1539,8 @@ static int list_unit_files(int argc, char *argv[], void *userdata) {
return bus_log_parse_error(r);
}
+ pager_open(arg_no_pager, false);
+
qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
output_unit_file_list(units, c);
@@ -1788,12 +1789,12 @@ static int list_dependencies(int argc, char *argv[], void *userdata) {
} else
u = SPECIAL_DEFAULT_TARGET;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
puts(u);
return list_dependencies_one(bus, u, 0, &units, 0);
@@ -2019,8 +2020,6 @@ static int list_machines(int argc, char *argv[], void *userdata) {
return -EPERM;
}
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
@@ -2029,6 +2028,8 @@ static int list_machines(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
output_machines_list(machine_infos, r);
free_machines_list(machine_infos, r);
@@ -2232,8 +2233,6 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
int r;
bool skipped = false;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
@@ -2274,6 +2273,8 @@ static int list_jobs(int argc, char *argv[], void *userdata) {
if (r < 0)
return bus_log_parse_error(r);
+ pager_open(arg_no_pager, false);
+
output_jobs_list(jobs, c, skipped);
return 0;
}
@@ -2286,12 +2287,12 @@ static int cancel_job(int argc, char *argv[], void *userdata) {
if (argc <= 1)
return trivial_method(argc, argv, userdata);
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
STRV_FOREACH(name, strv_skip(argv, 1)) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
uint32_t id;
@@ -2827,13 +2828,13 @@ static int start_unit(int argc, char *argv[], void *userdata) {
char **name;
int r = 0;
- ask_password_agent_open_if_enabled();
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ ask_password_agent_open_if_enabled();
+ polkit_agent_open_if_enabled();
+
if (arg_action == ACTION_SYSTEMCTL) {
enum action action;
@@ -2953,9 +2954,6 @@ static int logind_reboot(enum action a) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
- (void) logind_set_wall_message();
-
r = acquire_bus(BUS_FULL, &bus);
if (r < 0)
return r;
@@ -2991,6 +2989,9 @@ static int logind_reboot(enum action a) {
return -EINVAL;
}
+ polkit_agent_open_if_enabled();
+ (void) logind_set_wall_message();
+
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
@@ -3337,12 +3338,12 @@ static int kill_unit(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r, q;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
if (!arg_kill_who)
arg_kill_who = "all";
@@ -3847,14 +3848,13 @@ static void print_status_info(
printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
}
- if (i->control_group)
- printf(" CGroup: %s\n", i->control_group);
-
- {
+ if (i->control_group) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
static const char prefix[] = " ";
unsigned c;
+ printf(" CGroup: %s\n", i->control_group);
+
c = columns();
if (c > sizeof(prefix) - 1)
c -= sizeof(prefix) - 1;
@@ -4559,12 +4559,20 @@ static int show_one(
const char *verb,
sd_bus *bus,
const char *path,
+ const char *unit,
bool show_properties,
bool *new_line,
bool *ellipsized) {
+ static const struct bus_properties_map property_map[] = {
+ { "LoadState", "s", NULL, offsetof(UnitStatusInfo, load_state) },
+ { "ActiveState", "s", NULL, offsetof(UnitStatusInfo, active_state) },
+ {}
+ };
+
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_set_free_ Set *found_properties = NULL;
UnitStatusInfo info = {
.memory_current = (uint64_t) -1,
.memory_high = CGROUP_LIMIT_MAX,
@@ -4574,14 +4582,6 @@ static int show_one(
.tasks_current = (uint64_t) -1,
.tasks_max = (uint64_t) -1,
};
- struct property_info {
- const char *load_state, *active_state;
- } property_info = {};
- static const struct bus_properties_map property_map[] = {
- { "LoadState", "s", NULL, offsetof(struct property_info, load_state) },
- { "ActiveState", "s", NULL, offsetof(struct property_info, active_state) },
- {}
- };
ExecStatusInfo *p;
int r;
@@ -4602,16 +4602,24 @@ static int show_one(
if (r < 0)
return log_error_errno(r, "Failed to get properties: %s", bus_error_message(&error, r));
- r = bus_message_map_all_properties(reply, property_map, &property_info);
- if (r < 0)
- return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
+ if (unit) {
+ r = bus_message_map_all_properties(reply, property_map, &info);
+ if (r < 0)
+ return log_error_errno(r, "Failed to map properties: %s", bus_error_message(&error, r));
- if (streq_ptr(property_info.load_state, "not-found") && streq_ptr(property_info.active_state, "inactive"))
- return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
+ if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive")) {
+ log_error("Unit %s could not be found.", unit);
- r = sd_bus_message_rewind(reply, true);
- if (r < 0)
- return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
+ if (streq(verb, "status"))
+ return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
+
+ return -ENOENT;
+ }
+
+ r = sd_bus_message_rewind(reply, true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to rewind: %s", bus_error_message(&error, r));
+ }
r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
if (r < 0)
@@ -4637,9 +4645,17 @@ static int show_one(
if (r < 0)
return bus_log_parse_error(r);
- if (show_properties)
+ if (show_properties) {
+ r = set_ensure_allocated(&found_properties, &string_hash_ops);
+ if (r < 0)
+ return log_oom();
+
+ r = set_put(found_properties, name);
+ if (r < 0 && r != EEXIST)
+ return log_oom();
+
r = print_property(name, reply, contents);
- else
+ } else
r = status_property(name, reply, &info, contents);
if (r < 0)
return r;
@@ -4661,35 +4677,30 @@ static int show_one(
r = 0;
- if (!show_properties) {
- if (streq(verb, "help"))
- show_unit_help(&info);
+ if (show_properties) {
+ char **pp;
+
+ STRV_FOREACH(pp, arg_properties) {
+ if (!set_contains(found_properties, *pp)) {
+ log_warning("Property %s does not exist.", *pp);
+ r = -ENXIO;
+ }
+ }
+ } else if (streq(verb, "help"))
+ show_unit_help(&info);
+ else if (streq(verb, "status")) {
+ print_status_info(bus, &info, ellipsized);
+
+ if (info.active_state && STR_IN_SET(info.active_state, "inactive", "failed"))
+ r = EXIT_PROGRAM_NOT_RUNNING;
else
- print_status_info(bus, &info, ellipsized);
+ r = EXIT_PROGRAM_RUNNING_OR_SERVICE_OK;
}
strv_free(info.documentation);
strv_free(info.dropin_paths);
strv_free(info.listen);
- if (!streq_ptr(info.active_state, "active") &&
- !streq_ptr(info.active_state, "reloading") &&
- streq(verb, "status")) {
- /* According to LSB: "program not running" */
- /* 0: program is running or service is OK
- * 1: program is dead and /run PID file exists
- * 2: program is dead and /run/lock lock file exists
- * 3: program is not running
- * 4: program or service status is unknown
- */
- if (info.pid_file && access(info.pid_file, F_OK) == 0)
- r = EXIT_PROGRAM_DEAD_AND_PID_EXISTS;
- else if (streq_ptr(info.load_state, "not-found") && streq_ptr(info.active_state, "inactive"))
- r = EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN;
- else
- r = EXIT_PROGRAM_NOT_RUNNING;
- }
-
while ((p = info.exec)) {
LIST_REMOVE(exec, info.exec, p);
exec_status_info_free(p);
@@ -4762,7 +4773,7 @@ static int show_all(
if (!p)
return log_oom();
- r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
+ r = show_one(verb, bus, p, u->id, show_properties, new_line, ellipsized);
if (r < 0)
return r;
else if (r > 0 && ret == 0)
@@ -4844,6 +4855,10 @@ static int show(int argc, char *argv[], void *userdata) {
return -EINVAL;
}
+ r = acquire_bus(BUS_MANAGER, &bus);
+ if (r < 0)
+ return r;
+
pager_open(arg_no_pager, false);
if (show_status)
@@ -4852,17 +4867,12 @@ static int show(int argc, char *argv[], void *userdata) {
* be split up into many files. */
setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
- r = acquire_bus(BUS_MANAGER, &bus);
- if (r < 0)
- return r;
-
/* If no argument is specified inspect the manager itself */
if (show_properties && argc <= 1)
- return show_one(argv[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
+ return show_one(argv[0], bus, "/org/freedesktop/systemd1", NULL, show_properties, &new_line, &ellipsized);
if (show_status && argc <= 1) {
- pager_open(arg_no_pager, false);
show_system_status(bus);
new_line = true;
@@ -4873,7 +4883,7 @@ static int show(int argc, char *argv[], void *userdata) {
char **name;
STRV_FOREACH(name, strv_skip(argv, 1)) {
- _cleanup_free_ char *unit = NULL;
+ _cleanup_free_ char *path = NULL, *unit = NULL;
uint32_t id;
if (safe_atou32(*name, &id) < 0) {
@@ -4883,19 +4893,23 @@ static int show(int argc, char *argv[], void *userdata) {
continue;
} else if (show_properties) {
/* Interpret as job id */
- if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
+ if (asprintf(&path, "/org/freedesktop/systemd1/job/%u", id) < 0)
return log_oom();
} else {
/* Interpret as PID */
- r = get_unit_dbus_path_by_pid(bus, id, &unit);
+ r = get_unit_dbus_path_by_pid(bus, id, &path);
if (r < 0) {
ret = r;
continue;
}
+
+ r = unit_name_from_dbus_path(path, &unit);
+ if (r < 0)
+ return log_oom();
}
- r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
+ r = show_one(argv[0], bus, path, unit, show_properties, &new_line, &ellipsized);
if (r < 0)
return r;
else if (r > 0 && ret == 0)
@@ -4910,20 +4924,17 @@ static int show(int argc, char *argv[], void *userdata) {
return log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- _cleanup_free_ char *unit;
+ _cleanup_free_ char *path;
- unit = unit_dbus_path_from_name(*name);
- if (!unit)
+ path = unit_dbus_path_from_name(*name);
+ if (!path)
return log_oom();
- r = show_one(argv[0], bus, unit, show_properties, &new_line, &ellipsized);
+ r = show_one(argv[0], bus, path, *name, show_properties, &new_line, &ellipsized);
if (r < 0)
return r;
- else if (r > 0 && ret == 0)
+ if (r > 0 && ret == 0)
ret = r;
-
- if (r == EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN)
- log_error("Can't display property %s. Unit %s does not exist.", *patterns, *name);
}
}
}
@@ -5018,12 +5029,12 @@ static int set_property(int argc, char *argv[], void *userdata) {
char **i;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5070,12 +5081,12 @@ static int daemon_reload(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
switch (arg_action) {
case ACTION_RELOAD:
@@ -5130,12 +5141,12 @@ static int trivial_method(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
method =
streq(argv[0], "clear-jobs") ||
streq(argv[0], "cancel") ? "ClearJobs" :
@@ -5173,12 +5184,12 @@ static int reset_failed(int argc, char *argv[], void *userdata) {
if (argc <= 1)
return trivial_method(argc, argv, userdata);
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = expand_names(bus, strv_skip(argv, 1), NULL, &names);
if (r < 0)
return log_error_errno(r, "Failed to expand names: %m");
@@ -5212,12 +5223,12 @@ static int show_environment(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- pager_open(arg_no_pager, false);
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ pager_open(arg_no_pager, false);
+
r = sd_bus_get_property(
bus,
"org.freedesktop.systemd1",
@@ -5321,12 +5332,12 @@ static int set_environment(int argc, char *argv[], void *userdata) {
assert(argc > 1);
assert(argv);
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
method = streq(argv[0], "set-environment")
? "SetEnvironment"
: "UnsetEnvironment";
@@ -5358,12 +5369,12 @@ static int import_environment(int argc, char *argv[], void *userdata) {
sd_bus *bus;
int r;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5655,12 +5666,12 @@ static int enable_unit(int argc, char *argv[], void *userdata) {
const char *method;
sd_bus *bus;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
if (streq(verb, "enable")) {
method = "EnableUnitFiles";
expect_carries_install_info = true;
@@ -5821,12 +5832,12 @@ static int add_dependency(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
@@ -5883,12 +5894,12 @@ static int preset_all(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
sd_bus *bus;
- polkit_agent_open_if_enabled();
-
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
return r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
@@ -7709,8 +7720,6 @@ static int logind_schedule_shutdown(void) {
sd_bus *bus;
int r;
- (void) logind_set_wall_message();
-
r = acquire_bus(BUS_FULL, &bus);
if (r < 0)
return r;
@@ -7737,6 +7746,8 @@ static int logind_schedule_shutdown(void) {
if (arg_dry)
action = strjoina("dry-", action);
+ (void) logind_set_wall_message();
+
r = sd_bus_call_method(
bus,
"org.freedesktop.login1",
@@ -7927,6 +7938,8 @@ int main(int argc, char*argv[]) {
}
finish:
+ release_busses();
+
pager_close();
ask_password_agent_close();
polkit_agent_close();
@@ -7938,8 +7951,6 @@ finish:
strv_free(arg_wall);
free(arg_root);
- release_busses();
-
/* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
return r < 0 ? EXIT_FAILURE : r;
}
diff --git a/src/test/test-nss.c b/src/test/test-nss.c
index 55af592287..c43bda5917 100644
--- a/src/test/test-nss.c
+++ b/src/test/test-nss.c
@@ -400,8 +400,8 @@ int main(int argc, char **argv) {
_cleanup_free_ char *dir = NULL, *hostname = NULL;
const char *module;
- const uint32_t local_address_ipv4 = htonl(0x7F000001);
- const uint32_t local_address_ipv4_2 = htonl(0x7F000002);
+ const uint32_t local_address_ipv4 = htobe32(0x7F000001);
+ const uint32_t local_address_ipv4_2 = htobe32(0x7F000002);
_cleanup_free_ struct local_address *addresses = NULL;
int n_addresses;
diff --git a/src/test/test-parse-util.c b/src/test/test-parse-util.c
index 7d8677e17c..0a76308f72 100644
--- a/src/test/test-parse-util.c
+++ b/src/test/test-parse-util.c
@@ -475,6 +475,24 @@ static void test_safe_atod(void) {
assert_se(*e == ',');
}
+static void test_parse_percent(void) {
+ assert_se(parse_percent("") == -EINVAL);
+ assert_se(parse_percent("foo") == -EINVAL);
+ assert_se(parse_percent("0") == -EINVAL);
+ assert_se(parse_percent("50") == -EINVAL);
+ assert_se(parse_percent("100") == -EINVAL);
+ assert_se(parse_percent("-1") == -EINVAL);
+ assert_se(parse_percent("0%") == 0);
+ assert_se(parse_percent("55%") == 55);
+ assert_se(parse_percent("100%") == 100);
+ assert_se(parse_percent("-7%") == -ERANGE);
+ assert_se(parse_percent("107%") == -ERANGE);
+ assert_se(parse_percent("%") == -EINVAL);
+ assert_se(parse_percent("%%") == -EINVAL);
+ assert_se(parse_percent("%1") == -EINVAL);
+ assert_se(parse_percent("1%%") == -EINVAL);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -488,6 +506,7 @@ int main(int argc, char *argv[]) {
test_safe_atou16();
test_safe_atoi16();
test_safe_atod();
+ test_parse_percent();
return 0;
}
diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c
index a7a8f621a2..80ad5ed98b 100644
--- a/src/test/test-proc-cmdline.c
+++ b/src/test/test-proc-cmdline.c
@@ -23,6 +23,7 @@
#include "proc-cmdline.h"
#include "special.h"
#include "string-util.h"
+#include "util.h"
static int parse_item(const char *key, const char *value) {
assert_se(key);
@@ -36,9 +37,19 @@ static void test_parse_proc_cmdline(void) {
}
static void test_runlevel_to_target(void) {
+ in_initrd_force(false);
assert_se(streq_ptr(runlevel_to_target(NULL), NULL));
assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL));
+ assert_se(streq_ptr(runlevel_to_target("rd.unknown-runlevel"), NULL));
assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET));
+ assert_se(streq_ptr(runlevel_to_target("rd.rescue"), NULL));
+
+ in_initrd_force(true);
+ assert_se(streq_ptr(runlevel_to_target(NULL), NULL));
+ assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL));
+ assert_se(streq_ptr(runlevel_to_target("rd.unknown-runlevel"), NULL));
+ assert_se(streq_ptr(runlevel_to_target("3"), NULL));
+ assert_se(streq_ptr(runlevel_to_target("rd.rescue"), SPECIAL_RESCUE_TARGET));
}
int main(void) {
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index 4616314200..99c92780b8 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -18,82 +18,87 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <sched.h>
+#include <sys/mount.h>
#include <sys/personality.h>
+#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
#include "alloc-util.h"
#include "architecture.h"
+#include "fd-util.h"
#include "log.h"
#include "macro.h"
+#include "parse-util.h"
#include "process-util.h"
+#include "stdio-util.h"
#include "string-util.h"
#include "terminal-util.h"
#include "util.h"
#include "virt.h"
-static void test_get_process_comm(void) {
+static void test_get_process_comm(pid_t pid) {
struct stat st;
_cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL, *cwd = NULL, *root = NULL;
_cleanup_free_ char *env = NULL;
+ char path[strlen("/proc//comm") + DECIMAL_STR_MAX(pid_t)];
pid_t e;
uid_t u;
gid_t g;
dev_t h;
int r;
- pid_t me;
-
- if (stat("/proc/1/comm", &st) == 0) {
- assert_se(get_process_comm(1, &a) >= 0);
- log_info("pid1 comm: '%s'", a);
- } else
- log_warning("/proc/1/comm does not exist.");
- assert_se(get_process_cmdline(1, 0, true, &c) >= 0);
- log_info("pid1 cmdline: '%s'", c);
+ xsprintf(path, "/proc/"PID_FMT"/comm", pid);
- assert_se(get_process_cmdline(1, 8, false, &d) >= 0);
- log_info("pid1 cmdline truncated: '%s'", d);
+ if (stat(path, &st) == 0) {
+ assert_se(get_process_comm(pid, &a) >= 0);
+ log_info("PID"PID_FMT" comm: '%s'", pid, a);
+ } else
+ log_warning("%s not exist.", path);
- assert_se(get_process_ppid(1, &e) >= 0);
- log_info("pid1 ppid: "PID_FMT, e);
- assert_se(e == 0);
+ assert_se(get_process_cmdline(pid, 0, true, &c) >= 0);
+ log_info("PID"PID_FMT" cmdline: '%s'", pid, c);
- assert_se(is_kernel_thread(1) == 0);
+ assert_se(get_process_cmdline(pid, 8, false, &d) >= 0);
+ log_info("PID"PID_FMT" cmdline truncated to 8: '%s'", pid, d);
- r = get_process_exe(1, &f);
- assert_se(r >= 0 || r == -EACCES);
- log_info("pid1 exe: '%s'", strna(f));
+ free(d);
+ assert_se(get_process_cmdline(pid, 1, false, &d) >= 0);
+ log_info("PID"PID_FMT" cmdline truncated to 1: '%s'", pid, d);
- assert_se(get_process_uid(1, &u) == 0);
- log_info("pid1 uid: "UID_FMT, u);
- assert_se(u == 0);
+ assert_se(get_process_ppid(pid, &e) >= 0);
+ log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e);
+ assert_se(pid == 1 ? e == 0 : e > 0);
- assert_se(get_process_gid(1, &g) == 0);
- log_info("pid1 gid: "GID_FMT, g);
- assert_se(g == 0);
+ assert_se(is_kernel_thread(pid) == 0 || pid != 1);
- me = getpid();
-
- r = get_process_cwd(me, &cwd);
+ r = get_process_exe(pid, &f);
assert_se(r >= 0 || r == -EACCES);
- log_info("pid1 cwd: '%s'", cwd);
+ log_info("PID"PID_FMT" exe: '%s'", pid, strna(f));
- r = get_process_root(me, &root);
- assert_se(r >= 0 || r == -EACCES);
- log_info("pid1 root: '%s'", root);
+ assert_se(get_process_uid(pid, &u) == 0);
+ log_info("PID"PID_FMT" UID: "UID_FMT, pid, u);
+ assert_se(u == 0 || pid != 1);
- r = get_process_environ(me, &env);
+ assert_se(get_process_gid(pid, &g) == 0);
+ log_info("PID"PID_FMT" GID: "GID_FMT, pid, g);
+ assert_se(g == 0 || pid != 1);
+
+ r = get_process_environ(pid, &env);
assert_se(r >= 0 || r == -EACCES);
- log_info("self strlen(environ): '%zu'", strlen(env));
+ log_info("PID"PID_FMT" strlen(environ): %zi", pid, env ? (ssize_t)strlen(env) : (ssize_t)-errno);
if (!detect_container())
- assert_se(get_ctty_devnr(1, &h) == -ENXIO);
+ assert_se(get_ctty_devnr(pid, &h) == -ENXIO || pid != 1);
- getenv_for_pid(1, "PATH", &i);
- log_info("pid1 $PATH: '%s'", strna(i));
+ getenv_for_pid(pid, "PATH", &i);
+ log_info("PID"PID_FMT" $PATH: '%s'", pid, strna(i));
}
static void test_pid_is_unwaited(void) {
@@ -153,14 +158,213 @@ static void test_personality(void) {
#endif
}
+static void test_get_process_cmdline_harder(void) {
+ char path[] = "/tmp/test-cmdlineXXXXXX";
+ _cleanup_close_ int fd = -1;
+ _cleanup_free_ char *line = NULL;
+ pid_t pid;
+
+ if (geteuid() != 0)
+ return;
+
+#ifdef HAVE_VALGRIND_VALGRIND_H
+ /* valgrind patches open(/proc//cmdline)
+ * so, test_get_process_cmdline_harder fails always
+ * See https://github.com/systemd/systemd/pull/3555#issuecomment-226564908 */
+ if (RUNNING_ON_VALGRIND)
+ return;
+#endif
+
+ pid = fork();
+ if (pid > 0) {
+ siginfo_t si;
+
+ (void) wait_for_terminate(pid, &si);
+
+ assert_se(si.si_code == CLD_EXITED);
+ assert_se(si.si_status == 0);
+
+ return;
+ }
+
+ assert_se(pid == 0);
+ assert_se(unshare(CLONE_NEWNS) >= 0);
+
+ fd = mkostemp(path, O_CLOEXEC);
+ assert_se(fd >= 0);
+ assert_se(mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) >= 0);
+ assert_se(unlink(path) >= 0);
+
+ assert_se(prctl(PR_SET_NAME, "testa") >= 0);
+
+ assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT);
+
+ assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(streq(line, "[testa]"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 1, true, &line) >= 0);
+ assert_se(streq(line, ""));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 2, true, &line) >= 0);
+ assert_se(streq(line, "["));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 3, true, &line) >= 0);
+ assert_se(streq(line, "[."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 4, true, &line) >= 0);
+ assert_se(streq(line, "[.."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 5, true, &line) >= 0);
+ assert_se(streq(line, "[..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 6, true, &line) >= 0);
+ assert_se(streq(line, "[...]"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 7, true, &line) >= 0);
+ assert_se(streq(line, "[t...]"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 8, true, &line) >= 0);
+ assert_se(streq(line, "[testa]"));
+ line = mfree(line);
+
+ assert_se(write(fd, "\0\0\0\0\0\0\0\0\0", 10) == 10);
+
+ assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT);
+
+ assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(streq(line, "[testa]"));
+ line = mfree(line);
+
+ assert_se(write(fd, "foo\0bar\0\0\0\0\0", 10) == 10);
+
+ assert_se(get_process_cmdline(getpid(), 0, false, &line) >= 0);
+ assert_se(streq(line, "foo bar"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(streq(line, "foo bar"));
+ line = mfree(line);
+
+ assert_se(write(fd, "quux", 4) == 4);
+ assert_se(get_process_cmdline(getpid(), 0, false, &line) >= 0);
+ assert_se(streq(line, "foo bar quux"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(streq(line, "foo bar quux"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 1, true, &line) >= 0);
+ assert_se(streq(line, ""));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 2, true, &line) >= 0);
+ assert_se(streq(line, "."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 3, true, &line) >= 0);
+ assert_se(streq(line, ".."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 4, true, &line) >= 0);
+ assert_se(streq(line, "..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 5, true, &line) >= 0);
+ assert_se(streq(line, "f..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 6, true, &line) >= 0);
+ assert_se(streq(line, "fo..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 7, true, &line) >= 0);
+ assert_se(streq(line, "foo..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 8, true, &line) >= 0);
+ assert_se(streq(line, "foo..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 9, true, &line) >= 0);
+ assert_se(streq(line, "foo b..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 10, true, &line) >= 0);
+ assert_se(streq(line, "foo ba..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 11, true, &line) >= 0);
+ assert_se(streq(line, "foo bar..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 12, true, &line) >= 0);
+ assert_se(streq(line, "foo bar..."));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 13, true, &line) >= 0);
+ assert_se(streq(line, "foo bar quux"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 14, true, &line) >= 0);
+ assert_se(streq(line, "foo bar quux"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 1000, true, &line) >= 0);
+ assert_se(streq(line, "foo bar quux"));
+ line = mfree(line);
+
+ assert_se(ftruncate(fd, 0) >= 0);
+ assert_se(prctl(PR_SET_NAME, "aaaa bbbb cccc") >= 0);
+
+ assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT);
+
+ assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0);
+ assert_se(streq(line, "[aaaa bbbb cccc]"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 10, true, &line) >= 0);
+ assert_se(streq(line, "[aaaa...]"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 11, true, &line) >= 0);
+ assert_se(streq(line, "[aaaa...]"));
+ line = mfree(line);
+
+ assert_se(get_process_cmdline(getpid(), 12, true, &line) >= 0);
+ assert_se(streq(line, "[aaaa b...]"));
+ line = mfree(line);
+
+ safe_close(fd);
+ _exit(0);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- test_get_process_comm();
+ if (argc > 1) {
+ pid_t pid = 0;
+
+ (void) parse_pid(argv[1], &pid);
+ test_get_process_comm(pid);
+ } else {
+ test_get_process_comm(1);
+ test_get_process_comm(getpid());
+ }
+
test_pid_is_unwaited();
test_pid_is_alive();
test_personality();
+ test_get_process_cmdline_harder();
return 0;
}
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 1a439bd0d4..1f853a7f16 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -353,7 +353,7 @@ static void test_nameinfo_pretty(void) {
union sockaddr_union s = {
.in.sin_family = AF_INET,
.in.sin_port = 0,
- .in.sin_addr.s_addr = htonl(INADDR_ANY),
+ .in.sin_addr.s_addr = htobe32(INADDR_ANY),
};
int r;
@@ -391,17 +391,17 @@ static void test_sockaddr_equal(void) {
union sockaddr_union a = {
.in.sin_family = AF_INET,
.in.sin_port = 0,
- .in.sin_addr.s_addr = htonl(INADDR_ANY),
+ .in.sin_addr.s_addr = htobe32(INADDR_ANY),
};
union sockaddr_union b = {
.in.sin_family = AF_INET,
.in.sin_port = 0,
- .in.sin_addr.s_addr = htonl(INADDR_ANY),
+ .in.sin_addr.s_addr = htobe32(INADDR_ANY),
};
union sockaddr_union c = {
.in.sin_family = AF_INET,
.in.sin_port = 0,
- .in.sin_addr.s_addr = htonl(1234),
+ .in.sin_addr.s_addr = htobe32(1234),
};
union sockaddr_union d = {
.in6.sin6_family = AF_INET6,
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 9b6d2a7968..e177612a9f 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -26,6 +26,7 @@
#include "def.h"
#include "fileio.h"
#include "fs-util.h"
+#include "parse-util.h"
#include "raw-clone.h"
#include "rm-rf.h"
#include "string-util.h"
@@ -263,6 +264,53 @@ static void test_raw_clone(void) {
}
}
+static void test_physical_memory(void) {
+ uint64_t p;
+ char buf[FORMAT_BYTES_MAX];
+
+ p = physical_memory();
+ assert_se(p > 0);
+ assert_se(p < UINT64_MAX);
+ assert_se(p % page_size() == 0);
+
+ log_info("Memory: %s (%" PRIu64 ")", format_bytes(buf, sizeof(buf), p), p);
+}
+
+static void test_physical_memory_scale(void) {
+ uint64_t p;
+
+ p = physical_memory();
+
+ assert_se(physical_memory_scale(0, 100) == 0);
+ assert_se(physical_memory_scale(100, 100) == p);
+
+ log_info("Memory original: %" PRIu64, physical_memory());
+ log_info("Memory scaled by 50%%: %" PRIu64, physical_memory_scale(50, 100));
+ log_info("Memory divided by 2: %" PRIu64, physical_memory() / 2);
+ log_info("Page size: %zu", page_size());
+
+ /* There might be an uneven number of pages, hence permit these calculations to be half a page off... */
+ assert_se(page_size()/2 + physical_memory_scale(50, 100) - p/2 <= page_size());
+ assert_se(physical_memory_scale(200, 100) == p*2);
+
+ assert_se(physical_memory_scale(0, 1) == 0);
+ assert_se(physical_memory_scale(1, 1) == p);
+ assert_se(physical_memory_scale(2, 1) == p*2);
+
+ assert_se(physical_memory_scale(0, 2) == 0);
+
+ assert_se(page_size()/2 + physical_memory_scale(1, 2) - p/2 <= page_size());
+ assert_se(physical_memory_scale(2, 2) == p);
+ assert_se(physical_memory_scale(4, 2) == p*2);
+
+ assert_se(physical_memory_scale(0, UINT32_MAX) == 0);
+ assert_se(physical_memory_scale(UINT32_MAX, UINT32_MAX) == p);
+
+ /* overflow */
+ assert_se(physical_memory_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
+
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -277,6 +325,8 @@ int main(int argc, char *argv[]) {
test_log2i();
test_execute_directory();
test_raw_clone();
+ test_physical_memory();
+ test_physical_memory_scale();
return 0;
}
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index b7871f81aa..7f61cf0181 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -480,7 +480,7 @@ static int timedatectl_main(sd_bus *bus, int argc, char *argv[]) {
}
int main(int argc, char *argv[]) {
- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
@@ -500,6 +500,7 @@ int main(int argc, char *argv[]) {
r = timedatectl_main(bus, argc, argv);
finish:
+ sd_bus_flush_close_unref(bus);
pager_close();
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 66b51c1209..6753c52005 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -433,17 +433,13 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
case QUERY_PROPERTY:
list_entry = udev_device_get_properties_list_entry(device);
while (list_entry != NULL) {
- if (export) {
- const char *prefix = export_prefix;
-
- if (prefix == NULL)
- prefix = "";
- printf("%s%s='%s'\n", prefix,
+ if (export)
+ printf("%s%s='%s'\n", strempty(export_prefix),
udev_list_entry_get_name(list_entry),
udev_list_entry_get_value(list_entry));
- } else {
+ else
printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
- }
+
list_entry = udev_list_entry_get_next(list_entry);
}
break;
diff --git a/units/emergency.service.in b/units/emergency.service.in
index 0de16f24e8..da68eb8faa 100644
--- a/units/emergency.service.in
+++ b/units/emergency.service.in
@@ -18,7 +18,7 @@ Before=shutdown.target
Environment=HOME=/root
WorkingDirectory=-/root
ExecStartPre=-/bin/plymouth --wait quit
-ExecStartPre=-/bin/echo -e 'Welcome to 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.'
+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"
Type=idle
StandardInput=tty-force
diff --git a/units/rescue.service.in b/units/rescue.service.in
index ecf96bc211..5feff69c89 100644
--- a/units/rescue.service.in
+++ b/units/rescue.service.in
@@ -17,7 +17,7 @@ Before=shutdown.target
Environment=HOME=/root
WorkingDirectory=-/root
ExecStartPre=-/bin/plymouth --wait quit
-ExecStartPre=-/bin/echo -e 'Welcome to 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.'
+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"
Type=idle
StandardInput=tty-force
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index d8f18bed53..0b03a589ea 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -21,4 +21,4 @@ PrivateNetwork=yes
ProtectSystem=yes
ProtectHome=yes
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
diff --git a/units/systemd-importd.service.in b/units/systemd-importd.service.in
index a3d1a1519b..0f5489e7e3 100644
--- a/units/systemd-importd.service.in
+++ b/units/systemd-importd.service.in
@@ -18,4 +18,4 @@ NoNewPrivileges=yes
WatchdogSec=3min
KillMode=mixed
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
diff --git a/units/systemd-journald.service.in b/units/systemd-journald.service.in
index 58808d4f8c..08ace8ae44 100644
--- a/units/systemd-journald.service.in
+++ b/units/systemd-journald.service.in
@@ -25,7 +25,7 @@ CapabilityBoundingSet=CAP_SYS_ADMIN CAP_DAC_OVERRIDE CAP_SYS_PTRACE CAP_SYSLOG C
WatchdogSec=3min
FileDescriptorStoreMax=1024
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
# Increase the default a bit in order to allow many simultaneous
# services being run since we keep one fd open per service. Also, when
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
index 5efa677548..1f3151c2b5 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -21,4 +21,4 @@ PrivateNetwork=yes
ProtectSystem=yes
ProtectHome=yes
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @privileged @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index a9598760e2..bee08d011f 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -26,7 +26,7 @@ BusName=org.freedesktop.login1
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
WatchdogSec=3min
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @obsolete @raw-io
# Increase the default a bit in order to allow many simultaneous
# logins since we keep one fd open per session.
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index 82dca05338..cd4a097f5a 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -18,7 +18,7 @@ BusName=org.freedesktop.machine1
CapabilityBoundingSet=CAP_KILL CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_SETGID CAP_SYS_CHROOT CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_CHOWN CAP_FOWNER CAP_FSETID CAP_MKNOD
WatchdogSec=3min
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
# 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
diff --git a/units/systemd-networkd.service.m4.in b/units/systemd-networkd.service.m4.in
index 3feb2b84f5..38d967d2d1 100644
--- a/units/systemd-networkd.service.m4.in
+++ b/units/systemd-networkd.service.m4.in
@@ -32,7 +32,7 @@ ProtectSystem=full
ProtectHome=yes
WatchdogSec=3min
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
[Install]
WantedBy=multi-user.target
diff --git a/units/systemd-resolved.service.m4.in b/units/systemd-resolved.service.m4.in
index 4a94f747e2..a9cc3988ed 100644
--- a/units/systemd-resolved.service.m4.in
+++ b/units/systemd-resolved.service.m4.in
@@ -28,7 +28,7 @@ ProtectSystem=full
ProtectHome=yes
WatchdogSec=3min
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
[Install]
WantedBy=multi-user.target
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
index 1bdbe65aad..bc1795d747 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -19,4 +19,4 @@ PrivateTmp=yes
ProtectSystem=yes
ProtectHome=yes
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
index 8c86021f5e..df1e339196 100644
--- a/units/systemd-timesyncd.service.in
+++ b/units/systemd-timesyncd.service.in
@@ -29,7 +29,7 @@ ProtectSystem=full
ProtectHome=yes
WatchdogSec=3min
MemoryDenyWriteExecute=yes
-SystemCallFilter=~@module @mount @obsolete @raw-io ptrace
+SystemCallFilter=~@cpu-emulation @debug @keyring @module @mount @obsolete @raw-io
[Install]
WantedBy=sysinit.target
diff --git a/units/tmp.mount.m4 b/units/tmp.mount.m4
index 1448bd268a..0baecfd22f 100644
--- a/units/tmp.mount.m4
+++ b/units/tmp.mount.m4
@@ -19,4 +19,4 @@ After=swap.target
What=tmpfs
Where=/tmp
Type=tmpfs
-Options=mode=1777,strictatime
+Options=mode=1777,strictatime,nosuid,nodev